├── .gitignore ├── LICENCE ├── README.md ├── day.png ├── month.png ├── package.json ├── phone.png ├── src ├── components │ └── date-picker-component │ │ └── date-picker-component.ts ├── date-picker.module.ts └── index.ts ├── tsconfig.json └── year.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Specifies intentionally untracked files to ignore when using Git 2 | # http://git-scm.com/docs/gitignore 3 | 4 | *~ 5 | *.sw[mnpcod] 6 | *.log 7 | *.tmp 8 | *.tmp.* 9 | log.txt 10 | *.sublime-project 11 | *.sublime-workspace 12 | .vscode/ 13 | npm-debug.log* 14 | 15 | .idea/ 16 | .ionic/ 17 | .sourcemaps/ 18 | .sass-cache/ 19 | .tmp/ 20 | .versions/ 21 | coverage/ 22 | www/ 23 | node_modules/ 24 | dist/ 25 | tmp/ 26 | temp/ 27 | platforms/ 28 | plugins/ 29 | plugins/android.json 30 | plugins/ios.json 31 | $RECYCLE.BIN/ 32 | 33 | .DS_Store 34 | Thumbs.db 35 | UserInterfaceState.xcuserstate 36 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Kanung Hoksang 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 all 13 | 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 THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ionic Date Picker Component 2 | 3 | This is a date picker component for your Ionic 4 app. 4 | 5 | 6 | ## How to use ### 7 | 8 | ### 1) Install using npm ### 9 | 10 | ``` 11 | npm i ionic4-date-picker --save 12 | ``` 13 | 14 | ### 2) Add it to your ngModule in .module ### 15 | 16 | ``` 17 | import { DatePickerModule } from 'ionic4-date-picker'; 18 | ``` 19 | ``` 20 | 21 | @NgModule({ 22 | ..., 23 | imports: [ 24 | .... 25 | DatePickerModule 26 | .... 27 | ], 28 | .... 29 | }) 30 | ``` 31 | ### 3) Use the directive ionic-calendar-date-picker in your html ### 32 | ``` 33 | 34 | ``` 35 | 36 | 37 | ## Options ### 38 | 39 | `(onSelect)` - An event that is created when a date is selected. Outputs Date object. 40 | 41 | `[date]` - A date object that sets the selected date in the calendar. (not required. Default is today) 42 | 43 | `[fromDate]` - A date object that sets the min date in the calendar. (not required) 44 | 45 | `[toDate]` - A date object that sets max date in the calendar. (not required) 46 | 47 | `[monthLabels]` - An array of month label strings. (not required. Default is ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];) 48 | 49 | `[dayLabels]` - An array of day label strings. (not required. Default is ['S', 'M', 'T', 'W', 'T', 'F', 'S'];) 50 | 51 | `[validDates]` - An array of Date objects. When this is provided all the other dates will be disabled. The component still respects start date and end date if provided (not required. Default is [];) 52 | 53 | ## Styling Option by Date ### 54 | `[dateStyles]` - An Java dictionary representing style (value) for each date in YYYY-MM-DD (key in ISO). 55 | For eg: 56 | dateStyles = { 57 | '2019-04-10': {'background-color': 'red'}, 58 | '2019-04-09': {'background-color': 'green'}, 59 | '2019-04-08': {'background-color': 'blue'}, 60 | }; 61 | Hint: You can use toDate().toISOString().slice(0,10) on your Date object to quickly get the key. 62 | 63 | 64 | ## Styling Options ### 65 | ``` 66 | 67 | ``` 68 | 69 | None of these are required options. 70 | 71 | 72 | `[backgroundStyle]` - Background color of the component. Default: { 'background-color': '#ffffff' }; 73 | 74 | `[notInCalendarStyle]` - When a day is not in the calendar. Default: { 'color': '#8b8b8b' }; 75 | 76 | `[dayLabelsStyle]` - Day Label styling (S, M, T, W ... ). Default: { 'font-weight': 500, 'font-size': '14px' }; 77 | 78 | `[monthLabelsStyle]` - Month Label Styling (Jan, Feb, Mar ... ). Default: { 'font-size': '15px' }; 79 | 80 | `[yearLabelsStyle]` - Year Label Styling (2000, 2001 ...). Default: { 'font-size': '15px' }; 81 | 82 | `[itemSelectedStyle]` - Styling on selected Item by the user. Default: { 'background': '#488aff', 'color': '#f4f4f4 !important' }; 83 | 84 | `[todaysItemStyle]` - Styling on showing todays Day, Month, Year. Default: { 'color': '#32db64' }; 85 | 86 | `[invalidDateStyle]` - Styling on invalid Dates when you provide validDates input. Default: { 'text-decoration': 'line-through', 'color': 'red' }; 87 | 88 | ### 4) Pictures ### 89 | 90 | ![](demo_gif.gif) 91 | ![Day Selection]( day.png "Day Selection") 92 | ![Year Selection]( year.png "Year Selection") 93 | ![Month Selection]( month.png "Month Selection") 94 | ![Demo]( phone.png "Demo on a Phone") 95 | 96 | 97 | -------------------------------------------------------------------------------- /day.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/write2sv/ionic4-date-picker/6b7a3a6f7afb1a834c392584f87244d3c749d1f0/day.png -------------------------------------------------------------------------------- /month.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/write2sv/ionic4-date-picker/6b7a3a6f7afb1a834c392584f87244d3c749d1f0/month.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ionic4-date-picker", 3 | "version": "0.1.1", 4 | "description": "ionic4 date picker module", 5 | "main": "./dist/index.js", 6 | "typings": "./dist/index.d.ts", 7 | "files": [ 8 | "dist" 9 | ], 10 | "scripts": { 11 | "ngc": "ngc", 12 | "build": "rm -r dist && npm run ngc", 13 | "publishPackage": "npm run build && npm publish" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/write2sv/ionic4-date-picker" 18 | }, 19 | "keywords": [ 20 | "ionic4", 21 | "datepicker", 22 | "calendar", 23 | "component" 24 | ], 25 | "author": "Venkata Surya Sagi", 26 | "license": "MIT", 27 | "devDependencies": { 28 | "@angular/common": "9.0.0", 29 | "@angular/compiler": "9.0.0", 30 | "@angular/compiler-cli": "9.0.0", 31 | "@angular/core": "9.0.0", 32 | "@angular/forms": "9.0.0", 33 | "@angular/platform-browser": "9.0.0", 34 | "@angular/platform-browser-dynamic": "9.0.0", 35 | "@types/node": "13.7.6", 36 | "rxjs": "6.5.4", 37 | "typescript": "3.7.5", 38 | "zone.js": "0.10.2", 39 | "@ionic/angular": "5.0.1", 40 | "@angular/router": "9.0.0" 41 | }, 42 | "dependencies": { 43 | "dayspan": "0.12.5", 44 | "moment": "2.24.0" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /phone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/write2sv/ionic4-date-picker/6b7a3a6f7afb1a834c392584f87244d3c749d1f0/phone.png -------------------------------------------------------------------------------- /src/components/date-picker-component/date-picker-component.ts: -------------------------------------------------------------------------------- 1 | import {Component, OnInit, Input, Output, EventEmitter} from '@angular/core'; 2 | import {Calendar, Day} from 'dayspan'; 3 | import moment from 'moment'; 4 | 5 | const HTML_CODE = ` 6 |
7 | 8 | 9 | 10 | 11 | {{monthLabels[monthSelected-1]}} 12 | 13 | 14 | {{yearSelected}} 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | {{daylabel}} 31 | 32 | 33 | 34 | 35 | 36 | {{isValidDay(day) ? day.dayOfMonth : '  '}} 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | {{monthLabel}} 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 |
61 | 62 | 63 | 64 | 65 | {{startYear}} to {{endYear}} 66 | 67 | 68 | 69 | 70 | 71 |
72 |
73 | 74 | 75 | 76 | 77 | 78 |
79 | 80 | 81 | {{year}} 82 | 83 | 84 |
85 |
86 | `; 87 | 88 | const CSS_STYLE = ` 89 | .item { 90 | .item-inner { 91 | border-bottom: none !important; 92 | } 93 | } 94 | 95 | ion-icon { 96 | font-size: 25px; 97 | } 98 | 99 | .year-range { 100 | font-size: 15px; 101 | font-weight: 550; 102 | &.button[disabled] { 103 | opacity: 1; 104 | color: gray !important; 105 | } 106 | } 107 | 108 | .calendar-button { 109 | text-decoration: underline; 110 | padding-right: 2px !important; 111 | padding-left: 2px !important; 112 | } 113 | 114 | .invalidMonth { 115 | color: #8b8b8b 116 | } 117 | `; 118 | 119 | @Component({ 120 | selector: 'ionic-calendar-date-picker', 121 | template: HTML_CODE, 122 | styles: [CSS_STYLE], 123 | }) 124 | export class DatePickerComponent implements OnInit { 125 | 126 | @Input() monthLabels = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; 127 | @Input() dayLabels = ['S', 'M', 'T', 'W', 'T', 'F', 'S']; 128 | @Input() date: Date; 129 | @Input() fromDate: Date; 130 | @Input() toDate: Date; 131 | @Input() validDates: Date[] = []; 132 | @Input() dateStyles: any = {}; 133 | 134 | @Input() backgroundStyle = {'background-color': '#ffffff'}; 135 | @Input() notInCalendarStyle = {'color': '#8b8b8b'}; 136 | @Input() dayLabelsStyle = {'font-weight': 500, 'font-size': '14px'}; 137 | @Input() monthLabelsStyle = {'font-size': '15px'}; 138 | @Input() yearLabelsStyle = {'font-size': '15px'}; 139 | @Input() itemSelectedStyle = {'background': '#488aff', 'color': '#f4f4f4 !important'}; 140 | @Input() invalidDateStyle = {'text-decoration': 'line-through', 'color': 'red'}; 141 | @Input() todaysItemStyle = {'color': '#32db64'}; 142 | 143 | @Output() onSelect: EventEmitter = new EventEmitter(); 144 | 145 | showView = 'calendar'; 146 | weeks: Array>; 147 | years: Array; 148 | 149 | yearSelected = new Date().getFullYear(); 150 | monthSelected = new Date().getMonth() + 1; 151 | 152 | currentYear = new Date().getFullYear(); 153 | currentMonth = new Date().getMonth() + 1; 154 | currentDay = new Date().getDate(); 155 | 156 | daySelected: Day; 157 | dayHighlighted: Day; 158 | 159 | startYear: number; 160 | endYear: number; 161 | 162 | ngOnInit() { 163 | this.initOptions(); 164 | this.createCalendarWeeks(); 165 | } 166 | 167 | initOptions() { 168 | 169 | if (this.date && this.fromDate && this.date < this.fromDate) { 170 | throw new Error('Invalid date input. date must be same or greater than fromDate'); 171 | } 172 | 173 | if (this.date && this.toDate && this.toDate < this.date) { 174 | throw new Error('Invalid date input. date must be same or lesser than toDate'); 175 | } 176 | 177 | if (this.toDate && this.fromDate && this.fromDate > this.toDate) { 178 | throw new Error('Invalid date input. from date must be lesser than or equal to toDate'); 179 | } 180 | 181 | this.yearSelected = this.date ? this.date.getFullYear() : this.toDate ? this.toDate.getFullYear() : new Date().getFullYear(); 182 | this.monthSelected = this.date ? this.date.getMonth() + 1 : this.toDate ? this.toDate.getMonth() + 1 : new Date().getMonth() + 1; 183 | this.dayHighlighted = this.date ? Day.fromDate(this.date) : this.toDate ? Day.fromDate(this.toDate) : Day.today(); 184 | 185 | if (this.date) { 186 | this.daySelected = this.dayHighlighted; 187 | } 188 | } 189 | 190 | createCalendarWeeks() { 191 | this.weeks = this.generateCalendarWeeks( 192 | Day.fromMoment( 193 | moment(this.monthSelected + '-01-' + this.yearSelected, 'MM-DD-YYYY') 194 | ) 195 | ); 196 | } 197 | 198 | hasPrevious(): boolean { 199 | if (!this.fromDate) { 200 | return true; 201 | } 202 | 203 | let previousMonth; 204 | let previousYear; 205 | if (this.monthSelected === 1) { 206 | previousMonth = 11; 207 | previousYear = this.yearSelected - 1; 208 | } else { 209 | previousMonth = this.monthSelected; 210 | previousYear = this.yearSelected; 211 | } 212 | 213 | // The last day of previous month should be greatar than or equal to fromDate 214 | return new Date(previousYear, previousMonth, 0) >= this.fromDate; 215 | } 216 | 217 | hasNext(): boolean { 218 | if (!this.toDate) { 219 | return true; 220 | } 221 | 222 | let nextMonth; 223 | let nextYear; 224 | if (this.monthSelected === 12) { 225 | nextMonth = 0; 226 | nextYear = this.yearSelected + 1; 227 | } else { 228 | nextMonth = this.monthSelected; 229 | nextYear = this.yearSelected; 230 | } 231 | 232 | // The first day of next month should be less than or equal to toDate 233 | return new Date(nextYear, nextMonth, 1) <= this.toDate; 234 | } 235 | 236 | previous() { 237 | if (this.monthSelected === 1) { 238 | this.monthSelected = 12; 239 | this.yearSelected--; 240 | } else { 241 | this.monthSelected--; 242 | } 243 | 244 | this.createCalendarWeeks(); 245 | } 246 | 247 | next() { 248 | if (this.monthSelected === 12) { 249 | this.monthSelected = 1; 250 | this.yearSelected++; 251 | } else { 252 | this.monthSelected++; 253 | } 254 | 255 | this.createCalendarWeeks(); 256 | } 257 | 258 | confirmDay(day: Day) { 259 | this.onSelect.emit(day.toDate()); 260 | } 261 | 262 | selectDay(day: Day) { 263 | if (!this.isValidDay(day) || !this.isOneOfTheValidDates(day)) { 264 | return; 265 | } 266 | 267 | this.daySelected = day; 268 | setTimeout(() => { 269 | this.confirmDay(day); 270 | }, 200); 271 | } 272 | 273 | showMonthView() { 274 | this.showView = 'month'; 275 | `` 276 | } 277 | 278 | hasYearSelection() { 279 | if (!this.toDate || !this.fromDate) { 280 | return true; 281 | } 282 | 283 | return this.toDate.getFullYear() !== this.fromDate.getFullYear(); 284 | } 285 | 286 | showYearView() { 287 | this.showView = 'year'; 288 | let startYear = this.yearSelected - 10; 289 | if (startYear % 10 !== 0) { 290 | startYear = startYear - (startYear % 10); 291 | } 292 | const endYear = startYear + 19; 293 | 294 | this.startYear = startYear; 295 | this.endYear = endYear; 296 | 297 | this.generateYears(); 298 | } 299 | 300 | generateYears() { 301 | if (this.fromDate && this.startYear < this.fromDate.getFullYear()) { 302 | this.startYear = this.fromDate.getFullYear(); 303 | } 304 | 305 | if (this.toDate && this.endYear > this.toDate.getFullYear()) { 306 | this.endYear = this.toDate.getFullYear(); 307 | } 308 | 309 | this.years = []; 310 | for (let i = this.startYear; i <= this.endYear; i++) { 311 | this.years.push(i); 312 | } 313 | } 314 | 315 | showPreviousYears() { 316 | this.endYear = this.startYear - 1; 317 | this.startYear = this.endYear - 19; 318 | this.generateYears(); 319 | } 320 | 321 | showNextYears() { 322 | this.startYear = this.endYear + 1; 323 | this.endYear = this.startYear + 19; 324 | this.generateYears(); 325 | } 326 | 327 | hasPreviousYears() { 328 | if (!this.fromDate) { 329 | return true; 330 | } 331 | 332 | return this.startYear > this.fromDate.getFullYear(); 333 | } 334 | 335 | hasNextYears() { 336 | if (!this.toDate) { 337 | return true; 338 | } 339 | 340 | return this.endYear < this.toDate.getFullYear(); 341 | } 342 | 343 | selectMonth(month: number) { 344 | if (!this.isValidMonth(month - 1)) { 345 | return; 346 | } 347 | 348 | this.monthSelected = month; 349 | this.createCalendarWeeks(); 350 | setTimeout(() => { 351 | this.showView = 'calendar'; 352 | }, 200); 353 | } 354 | 355 | selectYear(year) { 356 | this.yearSelected = year; 357 | this.createCalendarWeeks(); 358 | setTimeout(() => { 359 | this.showView = 'calendar'; 360 | }, 200); 361 | } 362 | 363 | resetView() { 364 | this.showView = 'calendar'; 365 | } 366 | 367 | isToday(day) { 368 | return this.yearSelected === this.currentYear && this.monthSelected === this.currentMonth && this.currentDay === day; 369 | } 370 | 371 | generateCalendarWeeks(forDay: Day): Array { 372 | const weeks: Array = []; 373 | const month = Calendar.months(1, forDay); 374 | const numOfWeeks = month.days.length / 7; 375 | 376 | let dayIndex = 0; 377 | for (let week = 0; week < numOfWeeks; week++) { 378 | const days = []; 379 | for (let day = 0; day < 7; day++) { 380 | days.push(month.days[dayIndex]); 381 | dayIndex++; 382 | } 383 | weeks.push(days); 384 | } 385 | return weeks; 386 | } 387 | 388 | isValidDay(day: Day) { 389 | if (!this.toDate && !this.fromDate) { 390 | return true; 391 | } 392 | 393 | if (this.toDate && this.fromDate) { 394 | return day.toDate() >= this.fromDate && day.toDate() <= this.toDate; 395 | } 396 | 397 | if (this.toDate) { 398 | return day.toDate() <= this.toDate; 399 | } 400 | 401 | if (this.fromDate) { 402 | return day.toDate() >= this.fromDate; 403 | } 404 | } 405 | 406 | isOneOfTheValidDates(day: Day) { 407 | if (this.validDates && this.validDates.length) { 408 | const index = this.validDates.findIndex(validDate => 409 | validDate.getFullYear() === day.toDate().getFullYear() && 410 | validDate.getMonth() === day.toDate().getMonth() && 411 | validDate.getDate() === day.toDate().getDate() 412 | ); 413 | return index !== -1; 414 | } 415 | 416 | return true; 417 | } 418 | 419 | isValidMonth(index: number) { 420 | if (this.toDate && this.toDate.getFullYear() !== this.yearSelected && this.fromDate && this.fromDate.getFullYear() !== this.yearSelected) { 421 | return true; 422 | } 423 | 424 | if (!this.toDate && !this.fromDate) { 425 | return true; 426 | } 427 | 428 | if (this.fromDate && !this.toDate) { 429 | return new Date(this.yearSelected, index, 1) >= this.fromDate; 430 | } 431 | 432 | if (this.toDate && !this.fromDate) { 433 | return new Date(this.yearSelected, index, 1) <= this.toDate; 434 | } 435 | 436 | return new Date(this.yearSelected, index, 1) >= this.fromDate && 437 | new Date(this.yearSelected, index, 1) <= this.toDate; 438 | } 439 | 440 | //Styles 441 | 442 | getDayStyle(day: Day) { 443 | let style = {}; 444 | if (this.isToday(day.dayOfMonth)) { 445 | style = this.todaysItemStyle; 446 | } 447 | 448 | if (this.daySelected && day.dayIdentifier === this.daySelected.dayIdentifier) { 449 | style = {...style, ...this.itemSelectedStyle}; 450 | } 451 | 452 | const dayStyle = this.dateStyles && this.dateStyles[day.toDate().toISOString().slice(0, 10)]; 453 | if (dayStyle) { 454 | style = {...style, ...dayStyle}; 455 | } 456 | 457 | return style; 458 | } 459 | 460 | getMonthStyle(index) { 461 | let style = {}; 462 | style = {...style, ...this.monthLabelsStyle}; 463 | if (index === this.currentMonth - 1) { 464 | style = {...style, ...this.todaysItemStyle}; 465 | } 466 | 467 | if (index === this.monthSelected - 1) { 468 | style = {...style, ...this.itemSelectedStyle}; 469 | } 470 | 471 | return style; 472 | } 473 | 474 | getYearStyle(year) { 475 | let style = {}; 476 | style = {...style, ...this.yearLabelsStyle}; 477 | if (year === this.currentYear) { 478 | style = {...style, ...this.todaysItemStyle}; 479 | } 480 | 481 | if (year === this.yearSelected) { 482 | style = {...style, ...this.itemSelectedStyle}; 483 | } 484 | 485 | return style; 486 | } 487 | 488 | //End of styles 489 | 490 | } 491 | -------------------------------------------------------------------------------- /src/date-picker.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule, ModuleWithProviders } from '@angular/core'; 2 | import {IonicModule} from "@ionic/angular"; 3 | import {CommonModule} from "@angular/common"; 4 | import {FormsModule} from "@angular/forms"; 5 | 6 | import { DatePickerComponent } from './components/date-picker-component/date-picker-component'; 7 | 8 | @NgModule({ 9 | imports: [ 10 | IonicModule, 11 | CommonModule, 12 | FormsModule 13 | ], 14 | declarations: [ 15 | DatePickerComponent, 16 | ], 17 | exports: [ 18 | DatePickerComponent 19 | ] 20 | }) 21 | export class DatePickerModule { 22 | forRoot(): ModuleWithProviders { 23 | return { 24 | ngModule: DatePickerModule, 25 | providers: [] 26 | }; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export { DatePickerModule } from './date-picker.module'; -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "es2015", 4 | "target": "es5", 5 | "moduleResolution": "node", 6 | "sourceMap": true, 7 | "inlineSources": true, 8 | "declaration": true, 9 | "noImplicitAny": false, 10 | "experimentalDecorators": true, 11 | "lib": [ 12 | "dom", 13 | "es2017" 14 | ], 15 | "outDir": "dist", 16 | "allowSyntheticDefaultImports": true 17 | }, 18 | "exclude": [ 19 | "node_modules", 20 | "dist", 21 | "scripts" 22 | ], 23 | "angularCompilerOptions": { 24 | "skipTemplateCodegen": true, 25 | "enableIvy": false 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /year.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/write2sv/ionic4-date-picker/6b7a3a6f7afb1a834c392584f87244d3c749d1f0/year.png --------------------------------------------------------------------------------