@taiga-ui/cdk 2.26.0 → 2.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/README.md +4 -5
  2. package/abstract/control.d.ts +1 -1
  3. package/abstract/interactive.d.ts +4 -4
  4. package/abstract/taiga-ui-cdk-abstract.metadata.json +1 -1
  5. package/bundles/taiga-ui-cdk-abstract.umd.js +3 -3
  6. package/bundles/taiga-ui-cdk-abstract.umd.js.map +1 -1
  7. package/bundles/taiga-ui-cdk-abstract.umd.min.js +1 -1
  8. package/bundles/taiga-ui-cdk-abstract.umd.min.js.map +1 -1
  9. package/bundles/taiga-ui-cdk-date-time.umd.js +366 -287
  10. package/bundles/taiga-ui-cdk-date-time.umd.js.map +1 -1
  11. package/bundles/taiga-ui-cdk-date-time.umd.min.js +1 -1
  12. package/bundles/taiga-ui-cdk-date-time.umd.min.js.map +1 -1
  13. package/bundles/taiga-ui-cdk-directives-copy-processor.umd.js +276 -0
  14. package/bundles/taiga-ui-cdk-directives-copy-processor.umd.js.map +1 -0
  15. package/bundles/taiga-ui-cdk-directives-copy-processor.umd.min.js +16 -0
  16. package/bundles/taiga-ui-cdk-directives-copy-processor.umd.min.js.map +1 -0
  17. package/bundles/taiga-ui-cdk-directives-for.umd.js.map +1 -1
  18. package/bundles/taiga-ui-cdk-directives-for.umd.min.js.map +1 -1
  19. package/bundles/taiga-ui-cdk-directives-media.umd.js +1 -1
  20. package/bundles/taiga-ui-cdk-directives-media.umd.js.map +1 -1
  21. package/bundles/taiga-ui-cdk-directives-media.umd.min.js +1 -1
  22. package/bundles/taiga-ui-cdk-directives-media.umd.min.js.map +1 -1
  23. package/bundles/taiga-ui-cdk-services.umd.js +4 -4
  24. package/bundles/taiga-ui-cdk-services.umd.js.map +1 -1
  25. package/bundles/taiga-ui-cdk-services.umd.min.js +1 -1
  26. package/bundles/taiga-ui-cdk-services.umd.min.js.map +1 -1
  27. package/bundles/taiga-ui-cdk-tokens.umd.js +5 -0
  28. package/bundles/taiga-ui-cdk-tokens.umd.js.map +1 -1
  29. package/bundles/taiga-ui-cdk-tokens.umd.min.js +1 -1
  30. package/bundles/taiga-ui-cdk-tokens.umd.min.js.map +1 -1
  31. package/bundles/taiga-ui-cdk-utils-miscellaneous.umd.js +4 -1
  32. package/bundles/taiga-ui-cdk-utils-miscellaneous.umd.js.map +1 -1
  33. package/bundles/taiga-ui-cdk-utils-miscellaneous.umd.min.js +1 -1
  34. package/bundles/taiga-ui-cdk-utils-miscellaneous.umd.min.js.map +1 -1
  35. package/date-time/date-separator.d.ts +2 -0
  36. package/date-time/day-range.d.ts +24 -12
  37. package/date-time/day.d.ts +71 -58
  38. package/date-time/index.d.ts +1 -0
  39. package/date-time/month-range.d.ts +1 -1
  40. package/date-time/month.d.ts +26 -26
  41. package/date-time/taiga-ui-cdk-date-time.metadata.json +1 -1
  42. package/date-time/time.d.ts +12 -12
  43. package/date-time/year.d.ts +27 -27
  44. package/directives/copy-processor/copy-processor.directive.d.ts +7 -0
  45. package/directives/copy-processor/copy-processor.module.d.ts +2 -0
  46. package/directives/copy-processor/index.d.ts +2 -0
  47. package/directives/copy-processor/package.json +13 -0
  48. package/directives/copy-processor/taiga-ui-cdk-directives-copy-processor.d.ts +4 -0
  49. package/directives/copy-processor/taiga-ui-cdk-directives-copy-processor.metadata.json +1 -0
  50. package/directives/for/for.directive.d.ts +1 -1
  51. package/directives/for/taiga-ui-cdk-directives-for.metadata.json +1 -1
  52. package/directives/media/media.directive.d.ts +1 -1
  53. package/directives/media/taiga-ui-cdk-directives-media.metadata.json +1 -1
  54. package/esm2015/abstract/control.js +1 -1
  55. package/esm2015/abstract/interactive.js +4 -4
  56. package/esm2015/date-time/date-separator.js +5 -0
  57. package/esm2015/date-time/day-range.js +46 -23
  58. package/esm2015/date-time/day.js +164 -122
  59. package/esm2015/date-time/index.js +2 -1
  60. package/esm2015/date-time/month-range.js +6 -6
  61. package/esm2015/date-time/month.js +56 -56
  62. package/esm2015/date-time/time.js +40 -40
  63. package/esm2015/date-time/year.js +49 -49
  64. package/esm2015/directives/copy-processor/copy-processor.directive.js +37 -0
  65. package/esm2015/directives/copy-processor/copy-processor.module.js +13 -0
  66. package/esm2015/directives/copy-processor/index.js +3 -0
  67. package/esm2015/directives/copy-processor/taiga-ui-cdk-directives-copy-processor.js +5 -0
  68. package/esm2015/directives/for/for.directive.js +1 -1
  69. package/esm2015/directives/media/media.directive.js +2 -2
  70. package/esm2015/services/destroy.service.js +6 -3
  71. package/esm2015/services/obscured.service.js +1 -1
  72. package/esm2015/services/pan.service.js +3 -3
  73. package/esm2015/services/static-request.service.js +1 -1
  74. package/esm2015/tokens/index.js +2 -1
  75. package/esm2015/tokens/touch-supported.js +6 -0
  76. package/esm2015/utils/miscellaneous/ease-in-out-quad.js +2 -2
  77. package/esm2015/utils/miscellaneous/identity.js +4 -1
  78. package/esm5/abstract/control.js +1 -1
  79. package/esm5/abstract/interactive.js +4 -4
  80. package/esm5/date-time/date-separator.js +5 -0
  81. package/esm5/date-time/day-range.js +51 -23
  82. package/esm5/date-time/day.js +168 -122
  83. package/esm5/date-time/index.js +2 -1
  84. package/esm5/date-time/month-range.js +6 -6
  85. package/esm5/date-time/month.js +56 -56
  86. package/esm5/date-time/time.js +41 -41
  87. package/esm5/date-time/year.js +49 -49
  88. package/esm5/directives/copy-processor/copy-processor.directive.js +38 -0
  89. package/esm5/directives/copy-processor/copy-processor.module.js +16 -0
  90. package/esm5/directives/copy-processor/index.js +3 -0
  91. package/esm5/directives/copy-processor/taiga-ui-cdk-directives-copy-processor.js +5 -0
  92. package/esm5/directives/for/for.directive.js +1 -1
  93. package/esm5/directives/media/media.directive.js +2 -2
  94. package/esm5/services/destroy.service.js +4 -4
  95. package/esm5/services/obscured.service.js +1 -1
  96. package/esm5/services/pan.service.js +3 -3
  97. package/esm5/services/static-request.service.js +1 -1
  98. package/esm5/tokens/index.js +2 -1
  99. package/esm5/tokens/touch-supported.js +6 -0
  100. package/esm5/utils/miscellaneous/ease-in-out-quad.js +2 -2
  101. package/esm5/utils/miscellaneous/identity.js +4 -1
  102. package/fesm2015/taiga-ui-cdk-abstract.js +3 -3
  103. package/fesm2015/taiga-ui-cdk-abstract.js.map +1 -1
  104. package/fesm2015/taiga-ui-cdk-date-time.js +343 -275
  105. package/fesm2015/taiga-ui-cdk-date-time.js.map +1 -1
  106. package/fesm2015/taiga-ui-cdk-directives-copy-processor.js +52 -0
  107. package/fesm2015/taiga-ui-cdk-directives-copy-processor.js.map +1 -0
  108. package/fesm2015/taiga-ui-cdk-directives-for.js.map +1 -1
  109. package/fesm2015/taiga-ui-cdk-directives-media.js +1 -1
  110. package/fesm2015/taiga-ui-cdk-directives-media.js.map +1 -1
  111. package/fesm2015/taiga-ui-cdk-services.js +7 -4
  112. package/fesm2015/taiga-ui-cdk-services.js.map +1 -1
  113. package/fesm2015/taiga-ui-cdk-tokens.js +5 -1
  114. package/fesm2015/taiga-ui-cdk-tokens.js.map +1 -1
  115. package/fesm2015/taiga-ui-cdk-utils-miscellaneous.js +4 -1
  116. package/fesm2015/taiga-ui-cdk-utils-miscellaneous.js.map +1 -1
  117. package/fesm5/taiga-ui-cdk-abstract.js +3 -3
  118. package/fesm5/taiga-ui-cdk-abstract.js.map +1 -1
  119. package/fesm5/taiga-ui-cdk-date-time.js +364 -287
  120. package/fesm5/taiga-ui-cdk-date-time.js.map +1 -1
  121. package/fesm5/taiga-ui-cdk-directives-copy-processor.js +56 -0
  122. package/fesm5/taiga-ui-cdk-directives-copy-processor.js.map +1 -0
  123. package/fesm5/taiga-ui-cdk-directives-for.js.map +1 -1
  124. package/fesm5/taiga-ui-cdk-directives-media.js +1 -1
  125. package/fesm5/taiga-ui-cdk-directives-media.js.map +1 -1
  126. package/fesm5/taiga-ui-cdk-services.js +5 -5
  127. package/fesm5/taiga-ui-cdk-services.js.map +1 -1
  128. package/fesm5/taiga-ui-cdk-tokens.js +5 -1
  129. package/fesm5/taiga-ui-cdk-tokens.js.map +1 -1
  130. package/fesm5/taiga-ui-cdk-utils-miscellaneous.js +4 -1
  131. package/fesm5/taiga-ui-cdk-utils-miscellaneous.js.map +1 -1
  132. package/package.json +4 -4
  133. package/services/destroy.service.d.ts +3 -2
  134. package/services/obscured.service.d.ts +1 -1
  135. package/services/static-request.service.d.ts +1 -1
  136. package/services/taiga-ui-cdk-services.metadata.json +1 -1
  137. package/tokens/index.d.ts +1 -0
  138. package/tokens/taiga-ui-cdk-tokens.metadata.json +1 -1
  139. package/tokens/touch-supported.d.ts +2 -0
  140. package/utils/miscellaneous/identity.d.ts +3 -0
@@ -60,6 +60,10 @@ const TUI_DATE_FORMAT = new InjectionToken('Active date format for Taiga UI', {
60
60
  factory: () => 'DMY',
61
61
  });
62
62
 
63
+ const TUI_DATE_SEPARATOR = new InjectionToken('Date separator for Taiga UI components', {
64
+ factory: () => '.',
65
+ });
66
+
63
67
  /**
64
68
  * Immutable year object
65
69
  * @nosideeffects
@@ -69,6 +73,54 @@ class TuiYear {
69
73
  this.year = year;
70
74
  tuiAssert.assert(TuiYear.isValidYear(year));
71
75
  }
76
+ /**
77
+ * Checks year for validity
78
+ */
79
+ static isValidYear(year) {
80
+ return Number.isInteger(year) && inRange(year, MIN_YEAR, MAX_YEAR + 1);
81
+ }
82
+ /**
83
+ * Check if passed year is a leap year
84
+ */
85
+ static isLeapYear(year) {
86
+ tuiAssert.assert(TuiYear.isValidYear(year));
87
+ return year % 400 === 0 || (year % 4 === 0 && year % 100 !== 0);
88
+ }
89
+ /**
90
+ * Returns amount of leap years from year 0 to the passed one
91
+ */
92
+ static getAbsoluteLeapYears(year) {
93
+ tuiAssert.assert(TuiYear.isValidYear(year));
94
+ return Math.ceil(year / 400) + (Math.ceil(year / 4) - Math.ceil(year / 100));
95
+ }
96
+ /**
97
+ * @deprecated DONT USE IT (will be deleted soon)
98
+ *
99
+ * Returns day of week offset of the beginning of the passed year
100
+ *
101
+ * @param year
102
+ * @param absoluteLeapYears amount of leap years prior to the passed one
103
+ * @return offset in days
104
+ */
105
+ static getYearStartDaysOffset(year, absoluteLeapYears) {
106
+ tuiAssert.assert(TuiYear.isValidYear(year));
107
+ tuiAssert.assert(Number.isInteger(absoluteLeapYears));
108
+ tuiAssert.assert(year >= absoluteLeapYears);
109
+ tuiAssert.assert(absoluteLeapYears >= 0);
110
+ return ((absoluteLeapYears * DAYS_IN_LEAP_YEAR +
111
+ (year - absoluteLeapYears) * DAYS_IN_NORMAL_YEAR +
112
+ 5) %
113
+ DAYS_IN_WEEK);
114
+ }
115
+ static lengthBetween(from, to) {
116
+ return to.year - from.year;
117
+ }
118
+ /**
119
+ * Normalizes year by clamping it between min and max years
120
+ */
121
+ static normalizeYearPart(year) {
122
+ return normalizeToIntNumber(year, MIN_YEAR, MAX_YEAR);
123
+ }
72
124
  get formattedYear() {
73
125
  return padStart(this.year.toString(), 4, '0');
74
126
  }
@@ -138,68 +190,75 @@ class TuiYear {
138
190
  toJSON() {
139
191
  return this.formattedYear;
140
192
  }
193
+ }
194
+
195
+ /**
196
+ * Immutable object consisting of year and month
197
+ */
198
+ class TuiMonth extends TuiYear {
141
199
  /**
142
- * Checks year for validity
200
+ * @param year
201
+ * @param month (starting with 0)
143
202
  */
144
- static isValidYear(year) {
145
- return Number.isInteger(year) && inRange(year, MIN_YEAR, MAX_YEAR + 1);
203
+ constructor(year, month) {
204
+ super(year);
205
+ this.month = month;
206
+ tuiAssert.assert(TuiMonth.isValidMonth(year, month));
146
207
  }
147
208
  /**
148
- * Check if passed year is a leap year
209
+ * Tests month and year for validity
149
210
  */
150
- static isLeapYear(year) {
151
- tuiAssert.assert(TuiYear.isValidYear(year));
152
- return year % 400 === 0 || (year % 4 === 0 && year % 100 !== 0);
211
+ static isValidMonth(year, month) {
212
+ return TuiYear.isValidYear(year) && TuiMonth.isValidMonthPart(month);
153
213
  }
154
214
  /**
155
- * Returns amount of leap years from year 0 to the passed one
215
+ * Returns number of days in a month
156
216
  */
157
- static getAbsoluteLeapYears(year) {
158
- tuiAssert.assert(TuiYear.isValidYear(year));
159
- return Math.ceil(year / 400) + (Math.ceil(year / 4) - Math.ceil(year / 100));
217
+ static getMonthDaysCount(month, isLeapYear) {
218
+ tuiAssert.assert(TuiMonth.isValidMonthPart(month));
219
+ switch (month) {
220
+ case 1 /* February */:
221
+ return isLeapYear ? 29 : 28;
222
+ case 3 /* April */:
223
+ case 5 /* June */:
224
+ case 8 /* September */:
225
+ case 10 /* November */:
226
+ return 30;
227
+ default:
228
+ return 31;
229
+ }
160
230
  }
161
231
  /**
162
- * @deprecated DONT USE IT (will be deleted soon)
163
- *
164
- * Returns day of week offset of the beginning of the passed year
165
- *
166
- * @param year
167
- * @param absoluteLeapYears amount of leap years prior to the passed one
168
- * @return offset in days
232
+ * Returns current month and year based on local time zone
233
+ * @nosideeffects
169
234
  */
170
- static getYearStartDaysOffset(year, absoluteLeapYears) {
171
- tuiAssert.assert(TuiYear.isValidYear(year));
172
- tuiAssert.assert(Number.isInteger(absoluteLeapYears));
173
- tuiAssert.assert(year >= absoluteLeapYears);
174
- tuiAssert.assert(absoluteLeapYears >= 0);
175
- return ((absoluteLeapYears * DAYS_IN_LEAP_YEAR +
176
- (year - absoluteLeapYears) * DAYS_IN_NORMAL_YEAR +
177
- 5) %
178
- DAYS_IN_WEEK);
235
+ static currentLocal() {
236
+ const nativeDate = new Date();
237
+ return new TuiMonth(nativeDate.getFullYear(), nativeDate.getMonth());
238
+ }
239
+ /**
240
+ * Returns current month and year based on UTC
241
+ */
242
+ static currentUtc() {
243
+ const nativeDate = new Date();
244
+ return new TuiMonth(nativeDate.getUTCFullYear(), nativeDate.getUTCMonth());
179
245
  }
180
246
  static lengthBetween(from, to) {
181
- return to.year - from.year;
247
+ const absoluteFrom = from.month + from.year * 12;
248
+ const absoluteTo = to.month + to.year * 12;
249
+ return absoluteTo - absoluteFrom;
182
250
  }
183
251
  /**
184
- * Normalizes year by clamping it between min and max years
252
+ * Normalizes number by clamping it between min and max month
185
253
  */
186
- static normalizeYearPart(year) {
187
- return normalizeToIntNumber(year, MIN_YEAR, MAX_YEAR);
254
+ static normalizeMonthPart(month) {
255
+ return normalizeToIntNumber(month, MIN_MONTH, MAX_MONTH);
188
256
  }
189
- }
190
-
191
- /**
192
- * Immutable object consisting of year and month
193
- */
194
- class TuiMonth extends TuiYear {
195
257
  /**
196
- * @param year
197
- * @param month (starting with 0)
258
+ * Tests month for validity
198
259
  */
199
- constructor(year, month) {
200
- super(year);
201
- this.month = month;
202
- tuiAssert.assert(TuiMonth.isValidMonth(year, month));
260
+ static isValidMonthPart(month) {
261
+ return Number.isInteger(month) && inRange(month, MIN_MONTH, MAX_MONTH + 1);
203
262
  }
204
263
  get formattedMonthPart() {
205
264
  return padStart((this.month + 1).toString(), 2, '0');
@@ -304,77 +363,164 @@ class TuiMonth extends TuiYear {
304
363
  toUtcNativeDate() {
305
364
  return new Date(Date.UTC(this.year, this.month));
306
365
  }
366
+ }
367
+
368
+ // TODO: Localized formatting
369
+ /**
370
+ * Immutable date object, consisting of day, month and year
371
+ */
372
+ class TuiDay extends TuiMonth {
373
+ constructor(year, month, day) {
374
+ super(year, month);
375
+ this.day = day;
376
+ tuiAssert.assert(TuiDay.isValidDay(year, month, day));
377
+ }
307
378
  /**
308
- * Tests month and year for validity
379
+ * Creates {@link TuiDay} from native {@link Date} based on local time zone
309
380
  */
310
- static isValidMonth(year, month) {
311
- return TuiYear.isValidYear(year) && TuiMonth.isValidMonthPart(month);
381
+ static fromLocalNativeDate(date) {
382
+ return new TuiDay(date.getFullYear(), date.getMonth(), date.getDate());
312
383
  }
313
384
  /**
314
- * Returns number of days in a month
385
+ * Creates {@link TuiDay} from native {@link Date} using UTC
315
386
  */
316
- static getMonthDaysCount(month, isLeapYear) {
317
- tuiAssert.assert(TuiMonth.isValidMonthPart(month));
318
- switch (month) {
319
- case 1 /* February */:
320
- return isLeapYear ? 29 : 28;
321
- case 3 /* April */:
322
- case 5 /* June */:
323
- case 8 /* September */:
324
- case 10 /* November */:
325
- return 30;
326
- default:
327
- return 31;
387
+ static fromUtcNativeDate(date) {
388
+ return new TuiDay(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
389
+ }
390
+ /**
391
+ * Check validity of year, month and day
392
+ *
393
+ * @param year
394
+ * @param month
395
+ * @param day
396
+ * @return boolean validity
397
+ */
398
+ static isValidDay(year, month, day) {
399
+ return (TuiMonth.isValidMonth(year, month) &&
400
+ Number.isInteger(day) &&
401
+ inRange(day, MIN_DAY, TuiMonth.getMonthDaysCount(month, TuiYear.isLeapYear(year)) + 1));
402
+ }
403
+ /**
404
+ * @deprecated DONT USE IT (will be deleted soon)
405
+ *
406
+ * Calculated day on a calendar grid
407
+ *
408
+ * @param month
409
+ * @param row row in a calendar
410
+ * @param col column in a calendar
411
+ * @return resulting day on these coordinates (could exceed passed month)
412
+ */
413
+ static getDayFromMonthRowCol(month, row, col) {
414
+ tuiAssert.assert(Number.isInteger(row));
415
+ tuiAssert.assert(inRange(row, 0, 6));
416
+ tuiAssert.assert(Number.isInteger(col));
417
+ tuiAssert.assert(inRange(col, 0, DAYS_IN_WEEK));
418
+ let day = row * DAYS_IN_WEEK + col - month.monthStartDaysOffset + 1;
419
+ if (day > month.daysCount) {
420
+ day = day - month.daysCount;
421
+ month = month.append({ month: 1 });
328
422
  }
423
+ if (day <= 0) {
424
+ month = month.append({ month: -1 });
425
+ day = month.daysCount + day;
426
+ }
427
+ return new TuiDay(month.year, month.month, day);
329
428
  }
330
429
  /**
331
- * Returns current month and year based on local time zone
332
- * @nosideeffects
430
+ * Current day based on local time zone
333
431
  */
334
432
  static currentLocal() {
335
433
  const nativeDate = new Date();
336
- return new TuiMonth(nativeDate.getFullYear(), nativeDate.getMonth());
434
+ const year = nativeDate.getFullYear();
435
+ const month = nativeDate.getMonth();
436
+ const day = nativeDate.getDate();
437
+ return new TuiDay(year, month, day);
337
438
  }
338
439
  /**
339
- * Returns current month and year based on UTC
440
+ * Calculates {@link TuiDay} normalizing year, month and day. {@link NaN} is turned into minimal value.
441
+ *
442
+ * @param year any year value, including invalid
443
+ * @param month any month value, including invalid (months start with 0)
444
+ * @param day any day value, including invalid
445
+ * @return normalized date
340
446
  */
341
- static currentUtc() {
342
- const nativeDate = new Date();
343
- return new TuiMonth(nativeDate.getUTCFullYear(), nativeDate.getUTCMonth());
447
+ static normalizeOf(year, month, day) {
448
+ const normalizedYear = TuiYear.normalizeYearPart(year);
449
+ const normalizedMonth = TuiMonth.normalizeMonthPart(month);
450
+ const normalizedDay = TuiDay.normalizeDayPart(day, normalizedMonth, normalizedYear);
451
+ return new TuiDay(normalizedYear, normalizedMonth, normalizedDay);
344
452
  }
345
453
  static lengthBetween(from, to) {
346
- const absoluteFrom = from.month + from.year * 12;
347
- const absoluteTo = to.month + to.year * 12;
348
- return absoluteTo - absoluteFrom;
454
+ return Math.round((to.toLocalNativeDate().getTime() - from.toLocalNativeDate().getTime()) /
455
+ (1000 * 60 * 60 * 24));
349
456
  }
457
+ static parseRawDateString(date, dateMode = 'DMY') {
458
+ tuiAssert.assert(date.length === DATE_FILLER_LENGTH, '[parseRawDateString]: wrong date string length');
459
+ switch (dateMode) {
460
+ case 'YMD':
461
+ return {
462
+ day: parseInt(date.slice(8, 10), 10),
463
+ month: parseInt(date.slice(5, 7), 10) - 1,
464
+ year: parseInt(date.slice(0, 4), 10),
465
+ };
466
+ case 'MDY':
467
+ return {
468
+ day: parseInt(date.slice(3, 5), 10),
469
+ month: parseInt(date.slice(0, 2), 10) - 1,
470
+ year: parseInt(date.slice(6, 10), 10),
471
+ };
472
+ default:
473
+ case 'DMY':
474
+ return {
475
+ day: parseInt(date.slice(0, 2), 10),
476
+ month: parseInt(date.slice(3, 5), 10) - 1,
477
+ year: parseInt(date.slice(6, 10), 10),
478
+ };
479
+ }
480
+ }
481
+ // TODO: Move month and year related code corresponding classes
350
482
  /**
351
- * Normalizes number by clamping it between min and max month
483
+ * Parsing a string with date with normalization
484
+ *
485
+ * @param rawDate date string
486
+ * @param dateMode date format of the date string (DMY | MDY | YMD)
487
+ * @return normalized date
352
488
  */
353
- static normalizeMonthPart(month) {
354
- return normalizeToIntNumber(month, MIN_MONTH, MAX_MONTH);
489
+ static normalizeParse(rawDate, dateMode = 'DMY') {
490
+ const { day, month, year } = this.parseRawDateString(rawDate, dateMode);
491
+ return TuiDay.normalizeOf(year, month, day);
355
492
  }
356
493
  /**
357
- * Tests month for validity
494
+ * Parsing a date stringified in a toJSON format
495
+ * @param yearMonthDayString date string in format of YYYY-MM-DD
496
+ * @return date
497
+ * @throws exceptions if any part of the date is invalid
358
498
  */
359
- static isValidMonthPart(month) {
360
- return Number.isInteger(month) && inRange(month, MIN_MONTH, MAX_MONTH + 1);
361
- }
362
- }
363
-
364
- // TODO: Localized formatting
365
- /**
366
- * Immutable date object, consisting of day, month and year
367
- */
368
- class TuiDay extends TuiMonth {
369
- constructor(year, month, day) {
370
- super(year, month);
371
- this.day = day;
372
- tuiAssert.assert(TuiDay.isValidDay(year, month, day));
499
+ static jsonParse(yearMonthDayString) {
500
+ const { day, month, year } = this.parseRawDateString(yearMonthDayString, 'YMD');
501
+ if (!TuiYear.isValidYear(year)) {
502
+ throw new Error('Invalid year: ' + year);
503
+ }
504
+ if (!TuiMonth.isValidMonth(year, month)) {
505
+ throw new Error('Invalid month: ' + month);
506
+ }
507
+ if (!Number.isInteger(day) ||
508
+ !inRange(day, MIN_DAY, TuiMonth.getMonthDaysCount(month, TuiYear.isLeapYear(year)) + 1)) {
509
+ throw new Error('Invalid day: ' + day);
510
+ }
511
+ return new TuiDay(year, month, day);
512
+ }
513
+ static normalizeDayPart(day, month, year) {
514
+ tuiAssert.assert(TuiMonth.isValidMonth(year, month));
515
+ const monthDaysCount = TuiMonth.getMonthDaysCount(month, TuiYear.isLeapYear(year));
516
+ return normalizeToIntNumber(day, 1, monthDaysCount);
373
517
  }
374
518
  get formattedDayPart() {
375
519
  return padStart(this.day.toString(), 2, '0');
376
520
  }
377
521
  /**
522
+ * @deprecated use {@link getFormattedDay} instead
523
+ * TODO remove in 3.0
378
524
  * Formatted whole date
379
525
  */
380
526
  get formattedDay() {
@@ -490,8 +636,26 @@ class TuiDay extends TuiMonth {
490
636
  }
491
637
  return new TuiDay(years, months, days);
492
638
  }
493
- toString() {
494
- return this.formattedDay;
639
+ /**
640
+ * Returns formatted whole date
641
+ */
642
+ getFormattedDay(dateFormat, separator) {
643
+ tuiAssert.assert(separator.length === 1, 'Separator should consist of only 1 symbol');
644
+ const dd = this.formattedDayPart;
645
+ const mm = this.formattedMonthPart;
646
+ const yyyy = this.formattedYear;
647
+ switch (dateFormat) {
648
+ case 'YMD':
649
+ return `${yyyy}${separator}${mm}${separator}${dd}`;
650
+ case 'MDY':
651
+ return `${mm}${separator}${dd}${separator}${yyyy}`;
652
+ case 'DMY':
653
+ default:
654
+ return `${dd}${separator}${mm}${separator}${yyyy}`;
655
+ }
656
+ }
657
+ toString(dateFormat = 'DMY', separator = '.') {
658
+ return this.getFormattedDay(dateFormat, separator);
495
659
  }
496
660
  toJSON() {
497
661
  return `${super.toJSON()}-${this.formattedDayPart}`;
@@ -508,125 +672,6 @@ class TuiDay extends TuiMonth {
508
672
  toUtcNativeDate() {
509
673
  return new Date(Date.UTC(this.year, this.month, this.day));
510
674
  }
511
- /**
512
- * Creates {@link TuiDay} from native {@link Date} based on local time zone
513
- */
514
- static fromLocalNativeDate(date) {
515
- return new TuiDay(date.getFullYear(), date.getMonth(), date.getDate());
516
- }
517
- /**
518
- * Creates {@link TuiDay} from native {@link Date} using UTC
519
- */
520
- static fromUtcNativeDate(date) {
521
- return new TuiDay(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
522
- }
523
- /**
524
- * Check validity of year, month and day
525
- *
526
- * @param year
527
- * @param month
528
- * @param day
529
- * @return boolean validity
530
- */
531
- static isValidDay(year, month, day) {
532
- return (TuiMonth.isValidMonth(year, month) &&
533
- Number.isInteger(day) &&
534
- inRange(day, MIN_DAY, TuiMonth.getMonthDaysCount(month, TuiYear.isLeapYear(year)) + 1));
535
- }
536
- /**
537
- * @deprecated DONT USE IT (will be deleted soon)
538
- *
539
- * Calculated day on a calendar grid
540
- *
541
- * @param month
542
- * @param row row in a calendar
543
- * @param col column in a calendar
544
- * @return resulting day on these coordinates (could exceed passed month)
545
- */
546
- static getDayFromMonthRowCol(month, row, col) {
547
- tuiAssert.assert(Number.isInteger(row));
548
- tuiAssert.assert(inRange(row, 0, 6));
549
- tuiAssert.assert(Number.isInteger(col));
550
- tuiAssert.assert(inRange(col, 0, DAYS_IN_WEEK));
551
- let day = row * DAYS_IN_WEEK + col - month.monthStartDaysOffset + 1;
552
- if (day > month.daysCount) {
553
- day = day - month.daysCount;
554
- month = month.append({ month: 1 });
555
- }
556
- if (day <= 0) {
557
- month = month.append({ month: -1 });
558
- day = month.daysCount + day;
559
- }
560
- return new TuiDay(month.year, month.month, day);
561
- }
562
- /**
563
- * Current day based on local time zone
564
- */
565
- static currentLocal() {
566
- const nativeDate = new Date();
567
- const year = nativeDate.getFullYear();
568
- const month = nativeDate.getMonth();
569
- const day = nativeDate.getDate();
570
- return new TuiDay(year, month, day);
571
- }
572
- /**
573
- * Calculates {@link TuiDay} normalizing year, month and day. {@link NaN} is turned into minimal value.
574
- *
575
- * @param year any year value, including invalid
576
- * @param month any month value, including invalid (months start with 0)
577
- * @param day any day value, including invalid
578
- * @return normalized date
579
- */
580
- static normalizeOf(year, month, day) {
581
- const normalizedYear = TuiYear.normalizeYearPart(year);
582
- const normalizedMonth = TuiMonth.normalizeMonthPart(month);
583
- const normalizedDay = TuiDay.normalizeDayPart(day, normalizedMonth, normalizedYear);
584
- return new TuiDay(normalizedYear, normalizedMonth, normalizedDay);
585
- }
586
- static lengthBetween(from, to) {
587
- return Math.round((to.toLocalNativeDate().getTime() - from.toLocalNativeDate().getTime()) /
588
- (1000 * 60 * 60 * 24));
589
- }
590
- // TODO: Move month and year related code corresponding classes
591
- /**
592
- * Parsing a string with date with normalization
593
- *
594
- * @param yearMonthDayString date string in format of DD.MM.Yyyy
595
- * @return normalized date
596
- */
597
- static normalizeParse(yearMonthDayString) {
598
- const day = parseInt(yearMonthDayString.slice(0, 2), 10);
599
- const month = parseInt(yearMonthDayString.slice(3, 5), 10) - 1;
600
- const year = parseInt(yearMonthDayString.slice(6, 10), 10);
601
- return TuiDay.normalizeOf(year, month, day);
602
- }
603
- /**
604
- * Parsing a date stringified in a toJSON format
605
- * @param yearMonthDayString date string in format of YYYY-MM-DD
606
- * @return date
607
- * @throws exceptions if any part of the date is invalid
608
- */
609
- static jsonParse(yearMonthDayString) {
610
- const day = parseInt(yearMonthDayString.slice(8, 10), 10);
611
- const month = parseInt(yearMonthDayString.slice(5, 7), 10) - 1;
612
- const year = parseInt(yearMonthDayString.slice(0, 4), 10);
613
- if (!TuiYear.isValidYear(year)) {
614
- throw new Error('Invalid year: ' + year);
615
- }
616
- if (!TuiMonth.isValidMonth(year, month)) {
617
- throw new Error('Invalid month: ' + month);
618
- }
619
- if (!Number.isInteger(day) ||
620
- !inRange(day, MIN_DAY, TuiMonth.getMonthDaysCount(month, TuiYear.isLeapYear(year)) + 1)) {
621
- throw new Error('Invalid day: ' + day);
622
- }
623
- return new TuiDay(year, month, day);
624
- }
625
- static normalizeDayPart(day, month, year) {
626
- tuiAssert.assert(TuiMonth.isValidMonth(year, month));
627
- const monthDaysCount = TuiMonth.getMonthDaysCount(month, TuiYear.isLeapYear(year));
628
- return normalizeToIntNumber(day, 1, monthDaysCount);
629
- }
630
675
  }
631
676
 
632
677
  /**
@@ -638,6 +683,11 @@ class TuiMonthRange {
638
683
  this.to = to;
639
684
  tuiAssert.assert(from.monthSameOrBefore(to));
640
685
  }
686
+ static sort(month1, month2) {
687
+ return month1.monthSameOrBefore(month2)
688
+ ? new TuiMonthRange(month1, month2)
689
+ : new TuiMonthRange(month2, month1);
690
+ }
641
691
  get isSingleMonth() {
642
692
  return this.from.monthSame(this.to);
643
693
  }
@@ -650,13 +700,13 @@ class TuiMonthRange {
650
700
  toString() {
651
701
  return `${this.from}${RANGE_SEPARATOR_CHAR}${this.to}`;
652
702
  }
653
- static sort(month1, month2) {
654
- return month1.monthSameOrBefore(month2)
655
- ? new TuiMonthRange(month1, month2)
656
- : new TuiMonthRange(month2, month1);
657
- }
658
703
  }
659
704
 
705
+ /**
706
+ * Temporary type guard to satisfy ts-overloading of normalizeParse method
707
+ * @deprecated TODO rm in v3.0
708
+ */
709
+ const isDateMode = (dateMode) => ['DMY', 'YMD', 'MDY'].includes(dateMode);
660
710
  /**
661
711
  * An immutable range of two {@link TuiDay} objects
662
712
  */
@@ -667,14 +717,44 @@ class TuiDayRange extends TuiMonthRange {
667
717
  this.to = to;
668
718
  tuiAssert.assert(from.daySameOrBefore(to));
669
719
  }
720
+ /**
721
+ * Creates range from two days after sorting them
722
+ *
723
+ * @param day1
724
+ * @param day2
725
+ * @return new range with sorted days
726
+ */
727
+ static sort(day1, day2) {
728
+ return day1.daySameOrBefore(day2)
729
+ ? new TuiDayRange(day1, day2)
730
+ : new TuiDayRange(day2, day1);
731
+ }
732
+ /**
733
+ * Parse and correct a day range in string format
734
+ *
735
+ * @param rangeString a string of dates in a format dd.mm.yyyy - dd.mm.yyyy
736
+ * @param dateMode {@link TuiDateMode}
737
+ * @return normalized day range object
738
+ */
739
+ static normalizeParse(rangeString, dateMode = 'DMY') {
740
+ const dateFormat = isDateMode(dateMode) ? dateMode : 'DMY';
741
+ const leftDay = TuiDay.normalizeParse(rangeString.slice(0, DATE_FILLER_LENGTH), dateFormat);
742
+ if (rangeString.length < DATE_RANGE_FILLER_LENGTH) {
743
+ return new TuiDayRange(leftDay, leftDay);
744
+ }
745
+ return TuiDayRange.sort(leftDay, TuiDay.normalizeParse(rangeString.slice(DATE_FILLER_LENGTH + RANGE_SEPARATOR_CHAR.length), dateFormat));
746
+ }
670
747
  get isSingleDay() {
671
748
  return this.from.daySame(this.to);
672
749
  }
673
750
  /**
674
751
  * Human readable format.
752
+ * @deprecated use {@link getFormattedDayRange} instead
675
753
  */
676
754
  get formattedDayRange() {
677
- return `${this.from.formattedDay}${RANGE_SEPARATOR_CHAR}${this.to.formattedDay}`;
755
+ const from = this.from.getFormattedDay('DMY', '.');
756
+ const to = this.to.getFormattedDay('DMY', '.');
757
+ return `${from}${RANGE_SEPARATOR_CHAR}${to}`;
678
758
  }
679
759
  /**
680
760
  * Tests ranges for identity
@@ -696,29 +776,17 @@ class TuiDayRange extends TuiMonthRange {
696
776
  return new TuiDayRange(this.from.dayLimit(min, max), this.to.dayLimit(min, max));
697
777
  }
698
778
  /**
699
- * Creates range from two days after sorting them
700
- *
701
- * @param day1
702
- * @param day2
703
- * @return new range with sorted days
779
+ * Human readable format.
704
780
  */
705
- static sort(day1, day2) {
706
- return day1.daySameOrBefore(day2)
707
- ? new TuiDayRange(day1, day2)
708
- : new TuiDayRange(day2, day1);
781
+ getFormattedDayRange(dateFormat, dateSeparator) {
782
+ const from = this.from.getFormattedDay(dateFormat, dateSeparator);
783
+ const to = this.to.getFormattedDay(dateFormat, dateSeparator);
784
+ return `${from}${RANGE_SEPARATOR_CHAR}${to}`;
709
785
  }
710
- /**
711
- * Parse and correct a day range in string format
712
- *
713
- * @param rangeString a string of dates in a format dd.mm.yyyy - dd.mm.yyyy
714
- * @return normalized day range object
715
- */
716
- static normalizeParse(rangeString) {
717
- const leftDay = TuiDay.normalizeParse(rangeString.slice(0, DATE_FILLER_LENGTH));
718
- if (rangeString.length < DATE_RANGE_FILLER_LENGTH) {
719
- return new TuiDayRange(leftDay, leftDay);
720
- }
721
- return TuiDayRange.sort(leftDay, TuiDay.normalizeParse(rangeString.slice(DATE_FILLER_LENGTH + RANGE_SEPARATOR_CHAR.length)));
786
+ toString(dateFormat = 'DMY', dateSeparator = '.') {
787
+ const from = this.from.getFormattedDay(dateFormat, dateSeparator);
788
+ const to = this.to.getFormattedDay(dateFormat, dateSeparator);
789
+ return `${from}${RANGE_SEPARATOR_CHAR}${to}`;
722
790
  }
723
791
  }
724
792
 
@@ -736,45 +804,6 @@ class TuiTime {
736
804
  this.ms = ms;
737
805
  tuiAssert.assert(TuiTime.isValidTime(hours, minutes, seconds, ms), 'Time must be real, but got:', hours, minutes, seconds, ms);
738
806
  }
739
- /**
740
- * Shifts time by hours and minutes
741
- */
742
- shift({ hours = 0, minutes = 0, seconds = 0, ms = 0 }) {
743
- const newMs = (1000 + this.ms + (ms % 1000)) % 1000;
744
- const secondsInMs = ms < 0 ? Math.ceil(ms / 1000) : Math.floor(ms / 1000);
745
- const secondsToAdd = secondsInMs + seconds;
746
- const newSeconds = (60 + this.seconds + (secondsToAdd % 60)) % 60;
747
- const minutesInSeconds = secondsToAdd < 0
748
- ? Math.ceil(secondsToAdd / 60)
749
- : Math.floor(secondsToAdd / 60);
750
- const minutesToAdd = minutesInSeconds + minutes;
751
- const newMinutes = (60 + this.minutes + (minutesToAdd % 60)) % 60;
752
- const hoursInMinutes = minutesToAdd < 0
753
- ? Math.ceil(minutesToAdd / 60)
754
- : Math.floor(minutesToAdd / 60);
755
- const hoursToAdd = hoursInMinutes + hours;
756
- const newHours = (24 + this.hours + (hoursToAdd % 24)) % 24;
757
- return new TuiTime(newHours, newMinutes, newSeconds, newMs);
758
- }
759
- /**
760
- * Converts TuiTime to string
761
- */
762
- toString(mode) {
763
- const needAddMs = mode === 'HH:MM:SS.MSS' || (!mode && this.ms > 0);
764
- const needAddSeconds = needAddMs || mode === 'HH:MM:SS' || (!mode && this.seconds > 0);
765
- return (`${this.formatTime(this.hours)}:${this.formatTime(this.minutes)}` +
766
- `${needAddSeconds ? ':' + this.formatTime(this.seconds) : ''}` +
767
- `${needAddMs ? '.' + this.formatTime(this.ms, 3) : ''}`);
768
- }
769
- /**
770
- * Converts TuiTime to milliseconds
771
- */
772
- toAbsoluteMilliseconds() {
773
- return (this.hours * MILLISECONDS_IN_HOUR +
774
- this.minutes * MILLISECONDS_IN_MINUTE +
775
- this.seconds * 1000 +
776
- this.ms);
777
- }
778
807
  /**
779
808
  * Checks if time is valid
780
809
  */
@@ -831,6 +860,45 @@ class TuiTime {
831
860
  static fromLocalNativeDate(date) {
832
861
  return new TuiTime(date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds());
833
862
  }
863
+ /**
864
+ * Shifts time by hours and minutes
865
+ */
866
+ shift({ hours = 0, minutes = 0, seconds = 0, ms = 0 }) {
867
+ const newMs = (1000 + this.ms + (ms % 1000)) % 1000;
868
+ const secondsInMs = ms < 0 ? Math.ceil(ms / 1000) : Math.floor(ms / 1000);
869
+ const secondsToAdd = secondsInMs + seconds;
870
+ const newSeconds = (60 + this.seconds + (secondsToAdd % 60)) % 60;
871
+ const minutesInSeconds = secondsToAdd < 0
872
+ ? Math.ceil(secondsToAdd / 60)
873
+ : Math.floor(secondsToAdd / 60);
874
+ const minutesToAdd = minutesInSeconds + minutes;
875
+ const newMinutes = (60 + this.minutes + (minutesToAdd % 60)) % 60;
876
+ const hoursInMinutes = minutesToAdd < 0
877
+ ? Math.ceil(minutesToAdd / 60)
878
+ : Math.floor(minutesToAdd / 60);
879
+ const hoursToAdd = hoursInMinutes + hours;
880
+ const newHours = (24 + this.hours + (hoursToAdd % 24)) % 24;
881
+ return new TuiTime(newHours, newMinutes, newSeconds, newMs);
882
+ }
883
+ /**
884
+ * Converts TuiTime to string
885
+ */
886
+ toString(mode) {
887
+ const needAddMs = mode === 'HH:MM:SS.MSS' || (!mode && this.ms > 0);
888
+ const needAddSeconds = needAddMs || mode === 'HH:MM:SS' || (!mode && this.seconds > 0);
889
+ return (`${this.formatTime(this.hours)}:${this.formatTime(this.minutes)}` +
890
+ `${needAddSeconds ? ':' + this.formatTime(this.seconds) : ''}` +
891
+ `${needAddMs ? '.' + this.formatTime(this.ms, 3) : ''}`);
892
+ }
893
+ /**
894
+ * Converts TuiTime to milliseconds
895
+ */
896
+ toAbsoluteMilliseconds() {
897
+ return (this.hours * MILLISECONDS_IN_HOUR +
898
+ this.minutes * MILLISECONDS_IN_MINUTE +
899
+ this.seconds * 1000 +
900
+ this.ms);
901
+ }
834
902
  formatTime(time, digits = 2) {
835
903
  return padStart(time.toString(), digits, '0');
836
904
  }
@@ -840,5 +908,5 @@ class TuiTime {
840
908
  * Generated bundle index. Do not edit.
841
909
  */
842
910
 
843
- export { DATE_FILLER_LENGTH, DATE_RANGE_FILLER_LENGTH, DAYS_IN_LEAP_YEAR, DAYS_IN_NORMAL_YEAR, DAYS_IN_WEEK, HOURS_IN_DAY, MAX_MONTH, MAX_YEAR, MILLISECONDS_IN_DAY, MILLISECONDS_IN_HOUR, MILLISECONDS_IN_MINUTE, MILLISECONDS_IN_SECOND, MINUTES_IN_HOUR, MIN_DAY, MIN_MONTH, MIN_YEAR, MONTHS_IN_YEAR, RANGE_SEPARATOR_CHAR, SECONDS_IN_MINUTE, TUI_DATE_FILLER, TUI_DATE_FORMAT, TUI_DATE_RANGE_FILLER, TUI_FIRST_DAY, TUI_LAST_DAY, TuiDay, TuiDayRange, TuiMonth, TuiMonthRange, TuiTime, TuiYear };
911
+ export { DATE_FILLER_LENGTH, DATE_RANGE_FILLER_LENGTH, DAYS_IN_LEAP_YEAR, DAYS_IN_NORMAL_YEAR, DAYS_IN_WEEK, HOURS_IN_DAY, MAX_MONTH, MAX_YEAR, MILLISECONDS_IN_DAY, MILLISECONDS_IN_HOUR, MILLISECONDS_IN_MINUTE, MILLISECONDS_IN_SECOND, MINUTES_IN_HOUR, MIN_DAY, MIN_MONTH, MIN_YEAR, MONTHS_IN_YEAR, RANGE_SEPARATOR_CHAR, SECONDS_IN_MINUTE, TUI_DATE_FILLER, TUI_DATE_FORMAT, TUI_DATE_RANGE_FILLER, TUI_DATE_SEPARATOR, TUI_FIRST_DAY, TUI_LAST_DAY, TuiDay, TuiDayRange, TuiMonth, TuiMonthRange, TuiTime, TuiYear, isDateMode };
844
912
  //# sourceMappingURL=taiga-ui-cdk-date-time.js.map