@tactics/toddle-styleguide 5.3.1 → 5.3.3

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 (178) hide show
  1. package/App.tsx +0 -19
  2. package/app.json +8 -4
  3. package/index.tsx +0 -4
  4. package/package.json +55 -27
  5. package/src/components/atoms/calendar/calendar.component.tsx +10 -6
  6. package/src/components/atoms/calendar/calendar.preview.tsx +4 -3
  7. package/src/components/molecules/amount/amount.component.tsx +5 -4
  8. package/src/components/molecules/calendar-select/calendar-select.component.d.ts +4 -4
  9. package/src/components/molecules/calendar-select/calendar-select.component.tsx +17 -16
  10. package/src/components/molecules/calendar-select/calendar-select.preview.tsx +16 -5
  11. package/src/components/molecules/date-input/date-input.component.d.ts +2 -2
  12. package/src/components/molecules/date-input/date-input.component.tsx +3 -3
  13. package/src/components/molecules/date-input/date-input.preview.tsx +5 -5
  14. package/src/components/molecules/day/day.component.d.ts +3 -3
  15. package/src/components/molecules/day/day.component.tsx +22 -17
  16. package/src/components/molecules/selectable-list-item/selectable-list-item.component.tsx +12 -7
  17. package/src/components/molecules/timestamp/timestamp.component.d.ts +2 -2
  18. package/src/components/molecules/timestamp/timestamp.component.tsx +12 -5
  19. package/src/components/organisms/journal-entry/components/journal-entry-type/journal-entry-type.component.d.ts +2 -2
  20. package/src/components/organisms/journal-entry/components/journal-entry-type/journal-entry-type.component.tsx +5 -5
  21. package/src/components/organisms/journal-entry/journal-entry.component.d.ts +3 -3
  22. package/src/components/organisms/journal-entry/journal-entry.component.tsx +7 -3
  23. package/src/components/organisms/journal-entry/journal-entry.preview.tsx +7 -3
  24. package/src/components/organisms/text-bubble/text-bubble.component.d.ts +2 -2
  25. package/src/components/organisms/text-bubble/text-bubble.component.tsx +6 -3
  26. package/src/components/organisms/text-bubble/text-bubble.preview.tsx +19 -7
  27. package/src/components/templates/popover-action/popover-action.component.tsx +9 -8
  28. package/src/icons/solid/cloud-download/cloud-download.icon.tsx +1 -1
  29. package/src/icons/solid/refresh/refresh-solid.icon.tsx +2 -2
  30. package/src/utilities/datetime/clock.class.tsx +14 -0
  31. package/src/utilities/datetime/dateonly.class.tsx +287 -0
  32. package/src/utilities/datetime/datetime.class.tsx +288 -0
  33. package/src/utilities/datetime/day.class.tsx +48 -0
  34. package/src/utilities/datetime/dayjs-config.ts +96 -0
  35. package/src/utilities/datetime/dayoftheweek.class.tsx +242 -0
  36. package/src/utilities/datetime/hour.class.tsx +60 -0
  37. package/src/utilities/datetime/locale.tsx +6 -0
  38. package/src/utilities/datetime/millisecond.class.tsx +48 -0
  39. package/src/utilities/datetime/minute.class.tsx +55 -0
  40. package/src/utilities/datetime/month.class.tsx +74 -0
  41. package/src/utilities/datetime/second.class.tsx +52 -0
  42. package/src/utilities/datetime/time.class.tsx +190 -0
  43. package/src/utilities/datetime/timezone.class.tsx +36 -0
  44. package/src/utilities/datetime/year.class.tsx +78 -0
  45. package/src/utilities/datetime/yearandmonth.class.tsx +80 -0
  46. package/src/components/atoms/background-gradient/__snapshots__/background-gradient.test.js.snap +0 -40
  47. package/src/components/atoms/background-gradient/background-gradient.test.js +0 -10
  48. package/src/components/atoms/calendar/__snapshots__/calendar.test.js.snap +0 -6817
  49. package/src/components/atoms/calendar/calendar.test.js +0 -35
  50. package/src/components/atoms/check-switch/__snapshots__/check-switch.test.js.snap +0 -84
  51. package/src/components/atoms/check-switch/check-switch.test.js +0 -13
  52. package/src/components/atoms/heading-components/all-caps-heading/__snapshots__/all-caps-heading.test.js.snap +0 -113
  53. package/src/components/atoms/heading-components/all-caps-heading/all-caps-heading.test.js +0 -44
  54. package/src/components/atoms/heading-components/heading1/__snapshots__/heading1.test.js.snap +0 -121
  55. package/src/components/atoms/heading-components/heading1/heading1.test.js +0 -51
  56. package/src/components/atoms/heading-components/heading2/__snapshots__/heading2.test.js.snap +0 -121
  57. package/src/components/atoms/heading-components/heading2/heading2.test.js +0 -51
  58. package/src/components/atoms/heading-components/heading3/__snapshots__/heading3.test.js.snap +0 -121
  59. package/src/components/atoms/heading-components/heading3/heading3.test.js +0 -51
  60. package/src/components/atoms/heading-components/heading4/__snapshots__/heading4.test.js.snap +0 -121
  61. package/src/components/atoms/heading-components/heading4/heading4.test.js +0 -51
  62. package/src/components/atoms/image-bubble/__snapshots__/image-bubble.test.js.snap +0 -67
  63. package/src/components/atoms/image-bubble/image-bubble.test.js +0 -20
  64. package/src/components/atoms/increment-input/__snapshots__/increment-input.test.js.snap +0 -269
  65. package/src/components/atoms/increment-input/increment-input.test.js +0 -14
  66. package/src/components/atoms/logo/__snapshots__/logo.test.js.snap +0 -113
  67. package/src/components/atoms/logo/logo.test.js +0 -16
  68. package/src/components/atoms/paragraph-components/paragraph/__snapshots__/paragraph.test.js.snap +0 -121
  69. package/src/components/atoms/paragraph-components/paragraph/paragraph.test.js +0 -76
  70. package/src/components/atoms/paragraph-components/small-text/__snapshots__/small-text.test.js.snap +0 -121
  71. package/src/components/atoms/paragraph-components/small-text/small-text.test.js +0 -76
  72. package/src/components/atoms/paragraph-components/tiny-text/__snapshots__/tiny-text.test.js.snap +0 -121
  73. package/src/components/atoms/paragraph-components/tiny-text/tiny-text.test.js +0 -76
  74. package/src/components/atoms/quick-message/__snapshots__/quick-message.test.js.snap +0 -143
  75. package/src/components/atoms/quick-message/quick-message.test.js +0 -58
  76. package/src/components/atoms/split-container/__snapshots__/split-container.test.js.snap +0 -333
  77. package/src/components/atoms/split-container/split-container.test.js +0 -45
  78. package/src/components/atoms/text-input/__snapshots__/text-input.test.js.snap +0 -123
  79. package/src/components/atoms/text-input/text-input.test.js +0 -59
  80. package/src/components/molecules/avatar/__snapshots__/avatar.test.js.snap +0 -97
  81. package/src/components/molecules/avatar/avatar.test.js +0 -22
  82. package/src/components/molecules/blocked-message/__snapshots__/blocked-message.test.js.snap +0 -107
  83. package/src/components/molecules/blocked-message/blocked-message.test.js +0 -12
  84. package/src/components/molecules/button/__snapshots__/button.test.js.snap +0 -652
  85. package/src/components/molecules/button/button.test.js +0 -56
  86. package/src/components/molecules/calendar-select/__snapshots__/calendar-select.test.js.snap +0 -343
  87. package/src/components/molecules/calendar-select/calendar-select.test.js +0 -20
  88. package/src/components/molecules/cancel-link/__snapshots__/cancel-link.test.js.snap +0 -139
  89. package/src/components/molecules/cancel-link/cancel-link.test.js +0 -28
  90. package/src/components/molecules/checkbox/__snapshots__/checkbox.test.js.snap +0 -176
  91. package/src/components/molecules/checkbox/checkbox.test.js +0 -30
  92. package/src/components/molecules/contact-address/__snapshots__/contact-address.test.js.snap +0 -113
  93. package/src/components/molecules/contact-address/contact-address.test.js +0 -18
  94. package/src/components/molecules/contact-role/__snapshots__/contact-role.test.js.snap +0 -113
  95. package/src/components/molecules/contact-role/contact-role.test.js +0 -18
  96. package/src/components/molecules/date-input/__snapshots__/date-input.test.js.snap +0 -140
  97. package/src/components/molecules/date-input/date-input.test.js +0 -23
  98. package/src/components/molecules/day/__snapshots__/day.test.js.snap +0 -263
  99. package/src/components/molecules/day/day.test.js +0 -37
  100. package/src/components/molecules/default-select/__snapshots__/default-select.test.js.snap +0 -140
  101. package/src/components/molecules/default-select/default-select.test.js +0 -17
  102. package/src/components/molecules/department_logo/__snapshots__/department-logo.test.js.snap +0 -27
  103. package/src/components/molecules/department_logo/department-logo.test.js +0 -12
  104. package/src/components/molecules/failed-to-send/__snapshots__/failed-bubble.test.js.snap +0 -386
  105. package/src/components/molecules/failed-to-send/failed-bubble.test.js +0 -75
  106. package/src/components/molecules/filter-range/__snapshots__/filter-range.test.js.snap +0 -208
  107. package/src/components/molecules/filter-range/filter-range.test.js +0 -20
  108. package/src/components/molecules/filter-tab/__snapshots__/filter-tab.test.js.snap +0 -536
  109. package/src/components/molecules/filter-tab/filter-tab.test.js +0 -42
  110. package/src/components/molecules/info/__snapshots__/info.test.js.snap +0 -64
  111. package/src/components/molecules/info/info.test.js +0 -18
  112. package/src/components/molecules/language-button/__snapshots__/language-button.test.js.snap +0 -129
  113. package/src/components/molecules/language-button/language-button.test.js +0 -29
  114. package/src/components/molecules/message-input/__snapshots__/message-input.test.js.snap +0 -611
  115. package/src/components/molecules/message-input/message-input.test.js +0 -63
  116. package/src/components/molecules/more-info-button/__snapshots__/more-info-button.test.js.snap +0 -133
  117. package/src/components/molecules/more-info-button/more-info-button.test.js +0 -29
  118. package/src/components/molecules/password-input/__snapshots__/password-input.test.js.snap +0 -504
  119. package/src/components/molecules/password-input/password-input.test.js +0 -46
  120. package/src/components/molecules/pill/__snapshots__/pill.test.js.snap +0 -226
  121. package/src/components/molecules/pill/pill.test.js +0 -42
  122. package/src/components/molecules/pressable-icon/__snapshots__/pressable-icon.test.js.snap +0 -460
  123. package/src/components/molecules/pressable-icon/pressable-icon.test.js +0 -51
  124. package/src/components/molecules/quick-filter/__snapshots__/quick-filter.test.js.snap +0 -557
  125. package/src/components/molecules/quick-filter/quick-filter.test.js +0 -134
  126. package/src/components/molecules/search-input/__snapshots__/search.test.js.snap +0 -145
  127. package/src/components/molecules/search-input/search.test.js +0 -22
  128. package/src/components/molecules/select-link/__snapshots__/select-link.test.js.snap +0 -70
  129. package/src/components/molecules/select-link/select-link.test.js +0 -17
  130. package/src/components/molecules/select-list-item/__snapshots__/select-list-item.test.js.snap +0 -762
  131. package/src/components/molecules/select-list-item/select-list-item.test.js +0 -38
  132. package/src/components/molecules/select-picker/__snapshots__/select-picker.test.js.snap +0 -407
  133. package/src/components/molecules/select-picker/select-picker.test.js +0 -31
  134. package/src/components/molecules/send-bubble/__snapshots__/send-text-bubble.test.js.snap +0 -1979
  135. package/src/components/molecules/send-bubble/send-text-bubble.test.js +0 -156
  136. package/src/components/molecules/snackbar/__snapshots__/snackbar.test.js.snap +0 -557
  137. package/src/components/molecules/snackbar/snackbar.test.js +0 -35
  138. package/src/components/molecules/swipe/__snapshots__/swipe.test.js.snap +0 -340
  139. package/src/components/molecules/swipe/swipe.test.js +0 -46
  140. package/src/components/molecules/tag/__snapshots__/tag.test.js.snap +0 -139
  141. package/src/components/molecules/tag/tag.test.js +0 -34
  142. package/src/components/molecules/time-picker/__snapshots__/time-picker.test.js.snap +0 -2221
  143. package/src/components/molecules/time-picker/time-picker.test.js +0 -18
  144. package/src/components/molecules/time-tracker/__snapshots__/time-tracker.test.js.snap +0 -266
  145. package/src/components/molecules/time-tracker/time-tracker.test.js +0 -36
  146. package/src/components/molecules/timeline/__snapshots__/timeline.test.js.snap +0 -257
  147. package/src/components/molecules/timeline/timeline.test.js +0 -18
  148. package/src/components/molecules/timestamp/__snapshots__/timestamp.test.js.snap +0 -28
  149. package/src/components/molecules/timestamp/timestamp.test.js +0 -16
  150. package/src/components/molecules/wave-background/__snapshots__/wave.test.js.snap +0 -173
  151. package/src/components/molecules/wave-background/wave.test.js +0 -25
  152. package/src/components/molecules/wide-button/__snapshots__/wide-button.test.js.snap +0 -269
  153. package/src/components/molecules/wide-button/wide-button.test.js +0 -30
  154. package/src/components/organisms/child-list-item/__snapshots__/child-list-item.test.js.snap +0 -1040
  155. package/src/components/organisms/child-list-item/child-list-item.test.js +0 -75
  156. package/src/components/organisms/contact-item/__snapshots__/contact-item.test.js.snap +0 -404
  157. package/src/components/organisms/contact-item/contact-item.test.js +0 -22
  158. package/src/components/organisms/loading-indicator/__snapshots__/loading-indicator.test.js.snap +0 -474
  159. package/src/components/organisms/loading-indicator/loading-indicator.test.js +0 -41
  160. package/src/components/organisms/my-child-list-item/__snapshots__/my-child-list-item.test.js.snap +0 -293
  161. package/src/components/organisms/my-child-list-item/my-child-list-item.test.js +0 -23
  162. package/src/components/organisms/person-info-card/__snapshots__/person-info-card.test.js.snap +0 -709
  163. package/src/components/organisms/person-info-card/person-info-card.test.js +0 -85
  164. package/src/components/organisms/text-bubble/__snapshots__/text-bubble.test.js.snap +0 -3046
  165. package/src/components/organisms/text-bubble/text-bubble.test.js +0 -144
  166. package/src/utilities/toddle-datetime/interfaces/duration.interface.d.ts +0 -22
  167. package/src/utilities/toddle-datetime/interfaces/duration.interface.tsx +0 -23
  168. package/src/utilities/toddle-datetime/interfaces/toddle-datetime.interface.d.ts +0 -22
  169. package/src/utilities/toddle-datetime/interfaces/toddle-datetime.interface.tsx +0 -25
  170. package/src/utilities/toddle-datetime/toddle-datetime.class.d.ts +0 -50
  171. package/src/utilities/toddle-datetime/toddle-datetime.class.tsx +0 -206
  172. package/src/utilities/toddle-datetime/toddle-datetime.preview.d.ts +0 -2
  173. package/src/utilities/toddle-datetime/toddle-datetime.preview.tsx +0 -160
  174. package/src/utilities/toddle-datetime/toddle-datetime.test.js +0 -127
  175. package/src/utilities/toddle-datetime/types/duration.type.d.ts +0 -4
  176. package/src/utilities/toddle-datetime/types/duration.type.tsx +0 -6
  177. package/src/utilities/toddle-datetime/types/toddle-datetime.type.d.ts +0 -5
  178. package/src/utilities/toddle-datetime/types/toddle-datetime.type.tsx +0 -23
@@ -0,0 +1,96 @@
1
+ // dayjs.ts
2
+ import dayjs from 'dayjs';
3
+
4
+ // 🔌 Import plugins
5
+ import utc from 'dayjs/plugin/utc';
6
+ import timezone from 'dayjs/plugin/timezone';
7
+ import customParseFormat from 'dayjs/plugin/customParseFormat';
8
+ import localizedFormat from 'dayjs/plugin/localizedFormat';
9
+ import localeData from 'dayjs/plugin/localeData';
10
+ import updateLocale from 'dayjs/plugin/updateLocale';
11
+
12
+ // 🌍 Import languages
13
+ import 'dayjs/locale/en';
14
+ import 'dayjs/locale/fr';
15
+ import 'dayjs/locale/de';
16
+ import 'dayjs/locale/nl';
17
+ import {Locale} from "./locale";
18
+
19
+ // ✅ Extend plugins
20
+ dayjs.extend(utc);
21
+ dayjs.extend(timezone);
22
+ dayjs.extend(customParseFormat);
23
+ dayjs.extend(localizedFormat);
24
+ dayjs.extend(localeData);
25
+ dayjs.extend(updateLocale);
26
+
27
+
28
+ // 🌍 Import and set locale if needed
29
+ dayjs.updateLocale(Locale.en, {
30
+ months: [
31
+ "January", "February", "March", "April", "May", "June",
32
+ "July", "August", "September", "October", "November", "December"
33
+ ],
34
+ monthsShort: [
35
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
36
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
37
+ ],
38
+ weekdays: [
39
+ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
40
+ ],
41
+ weekdaysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
42
+ weekdaysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
43
+ });
44
+
45
+ dayjs.updateLocale(Locale.fr, {
46
+ months: [
47
+ "janvier", "février", "mars", "avril", "mai", "juin",
48
+ "juillet", "août", "septembre", "octobre", "novembre", "décembre"
49
+ ],
50
+ monthsShort: [
51
+ "janv.", "févr.", "mars", "avr.", "mai", "juin",
52
+ "juil.", "août", "sept.", "oct.", "nov.", "déc."
53
+ ],
54
+ weekdays: [
55
+ "dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"
56
+ ],
57
+ weekdaysShort: ["dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam."],
58
+ weekdaysMin: ["di", "lu", "ma", "me", "je", "ve", "sa"]
59
+ });
60
+
61
+ dayjs.updateLocale(Locale.nl, {
62
+ months: [
63
+ "januari", "februari", "maart", "april", "mei", "juni",
64
+ "juli", "augustus", "september", "oktober", "november", "december"
65
+ ],
66
+ monthsShort: [
67
+ "jan", "feb", "mrt", "apr", "mei", "jun",
68
+ "jul", "aug", "sep", "okt", "nov", "dec"
69
+ ],
70
+ weekdays: [
71
+ "zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"
72
+ ],
73
+ weekdaysShort: ["zo", "ma", "di", "wo", "do", "vr", "za"],
74
+ weekdaysMin: ["zo", "ma", "di", "wo", "do", "vr", "za"]
75
+ });
76
+
77
+ dayjs.updateLocale(Locale.de, {
78
+ months: [
79
+ "Januar", "Februar", "März", "April", "Mai", "Juni",
80
+ "Juli", "August", "September", "Oktober", "November", "Dezember"
81
+ ],
82
+ monthsShort: [
83
+ "Jan", "Feb", "Mär", "Apr", "Mai", "Jun",
84
+ "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"
85
+ ],
86
+ weekdays: [
87
+ "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"
88
+ ],
89
+ weekdaysShort: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"],
90
+ weekdaysMin: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"]
91
+ });
92
+
93
+ // ✅ Set default locale
94
+ dayjs.locale(Locale.nl);
95
+
96
+ export default dayjs;
@@ -0,0 +1,242 @@
1
+ import {Locale} from './locale';
2
+ import dayjs from './dayjs-config';
3
+
4
+ export type Iso8601WeekdayNumbers = 1 | 2 | 3 | 4 | 5 | 6 | 7;
5
+ export type ZeroBasedWeekdayNumbers = 0 | 2 | 3 | 4 | 5 | 6;
6
+
7
+ export class InvalidDayOfWeek extends Error {
8
+ static invalidDayOfWeek() {
9
+ return new InvalidDayOfWeek("The provided day of week is invalid.");
10
+ }
11
+ }
12
+
13
+ export enum DayOfWeekLocaleAwareOutputFormat {
14
+ DAY_OF_WEEK_LONG = "long",
15
+ DAY_OF_WEEK_SHORT = "short",
16
+ DAY_OF_WEEK_NARROW = "narrow",
17
+ }
18
+
19
+ export enum DayOfWeekOutputFormat {
20
+ DAY_OF_WEEK_NUMERIC_ZERO_BASED = "numeric-zero-based",
21
+ DAY_OF_WEEK_NUMERIC_ISO8601 = "numeric-iso8601",
22
+ }
23
+
24
+ export enum DayOfWeekIndex {
25
+ ZERO_BASED = "zero-based", // Sunday = 0, Monday = 6
26
+ ISO8601 = "iso8601", // Monday = 1, Sunday = 7
27
+ }
28
+
29
+ export interface IDayOfWeek {
30
+ asInt(index: DayOfWeekIndex): number;
31
+ isMonday(): boolean;
32
+ isTuesday(): boolean;
33
+ isWednesday(): boolean;
34
+ isThursday(): boolean;
35
+ isFriday(): boolean;
36
+ isSaturday(): boolean;
37
+ isSunday(): boolean;
38
+ isWeekend(): boolean;
39
+ isWeekday(): boolean;
40
+ offset(): 0 | 1 | 2 | 3 | 4 | 5 | 6; // The offset from Monday
41
+ format(format: DayOfWeekOutputFormat): string;
42
+ formatLocale(format: DayOfWeekLocaleAwareOutputFormat, locale: Locale): string;
43
+ }
44
+
45
+ export class DayOfWeek implements IDayOfWeek {
46
+ public readonly dayOfWeek: number;
47
+
48
+ private constructor(day: Iso8601WeekdayNumbers) {
49
+ this.dayOfWeek = day;
50
+ }
51
+
52
+ static from(
53
+ day: Iso8601WeekdayNumbers | ZeroBasedWeekdayNumbers,
54
+ index: DayOfWeekIndex = DayOfWeekIndex.ISO8601,
55
+ ): DayOfWeek {
56
+ if (index === DayOfWeekIndex.ZERO_BASED) {
57
+ if (day === 7) {
58
+ throw InvalidDayOfWeek.invalidDayOfWeek();
59
+ }
60
+ return DayOfWeek.fromZeroBased(day as ZeroBasedWeekdayNumbers);
61
+ }
62
+
63
+ if (day === 0) {
64
+ throw InvalidDayOfWeek.invalidDayOfWeek();
65
+ }
66
+
67
+ return DayOfWeek.fromIso8601(day);
68
+ }
69
+
70
+ static fromIso8601(day: Iso8601WeekdayNumbers): DayOfWeek {
71
+ return new DayOfWeek(day);
72
+ }
73
+
74
+ static fromZeroBased(day: ZeroBasedWeekdayNumbers): DayOfWeek {
75
+ return new DayOfWeek((day + 1) as Iso8601WeekdayNumbers);
76
+ }
77
+
78
+ asInt(index: DayOfWeekIndex = DayOfWeekIndex.ISO8601): number {
79
+ return index === DayOfWeekIndex.ISO8601
80
+ ? this.dayOfWeek
81
+ : this.dayOfWeek - 1;
82
+ }
83
+
84
+ isMonday(): boolean {
85
+ return this.dayOfWeek === 1;
86
+ }
87
+
88
+ isTuesday(): boolean {
89
+ return this.dayOfWeek === 2;
90
+ }
91
+
92
+ isWednesday(): boolean {
93
+ return this.dayOfWeek === 3;
94
+ }
95
+
96
+ isThursday(): boolean {
97
+ return this.dayOfWeek === 4;
98
+ }
99
+
100
+ isFriday(): boolean {
101
+ return this.dayOfWeek === 5;
102
+ }
103
+
104
+ isSaturday(): boolean {
105
+ return this.dayOfWeek === 6;
106
+ }
107
+
108
+ isSunday(): boolean {
109
+ return this.dayOfWeek === 7;
110
+ }
111
+
112
+ isWeekend(): boolean {
113
+ return this.isSaturday() || this.isSunday();
114
+ }
115
+
116
+ isWeekday(): boolean {
117
+ return !this.isWeekend();
118
+ }
119
+
120
+ offset(): 0 | 1 | 2 | 3 | 4 | 5 | 6 {
121
+ return this.asInt(DayOfWeekIndex.ZERO_BASED) as 0 | 1 | 2 | 3 | 4 | 5 | 6;
122
+ }
123
+
124
+ formatLocale(format: DayOfWeekLocaleAwareOutputFormat, locale: Locale): string {
125
+ if (!Object.values(DayOfWeekLocaleAwareOutputFormat).includes(format)) {
126
+ throw new Error(`Unsupported format: ${format}`);
127
+ }
128
+
129
+ if (this.isMonday()) {
130
+ // Fixed days in the past to represent a monday.
131
+ const monday = dayjs("2021-03-01T12:00:00");
132
+ switch (format) {
133
+ case DayOfWeekLocaleAwareOutputFormat.DAY_OF_WEEK_SHORT:
134
+ return monday.locale(locale).format('dd')
135
+ case DayOfWeekLocaleAwareOutputFormat.DAY_OF_WEEK_NARROW:
136
+ return monday.locale(locale).format('ddd')
137
+ case DayOfWeekLocaleAwareOutputFormat.DAY_OF_WEEK_LONG:
138
+ return monday.locale(locale).format('dddd')
139
+ default:
140
+ throw new Error(`Unsupported format: ${format}`);
141
+ }
142
+ }
143
+
144
+ if (this.isTuesday()) {
145
+ const tuesday = dayjs("2021-03-02T12:00:00");
146
+ switch (format) {
147
+ case DayOfWeekLocaleAwareOutputFormat.DAY_OF_WEEK_SHORT:
148
+ return tuesday.locale(locale).format('dd')
149
+ case DayOfWeekLocaleAwareOutputFormat.DAY_OF_WEEK_NARROW:
150
+ return tuesday.locale(locale).format('ddd')
151
+ case DayOfWeekLocaleAwareOutputFormat.DAY_OF_WEEK_LONG:
152
+ return tuesday.locale(locale).format('dddd')
153
+ default:
154
+ throw new Error(`Unsupported format: ${format}`);
155
+ }
156
+ }
157
+
158
+ if (this.isWednesday()) {
159
+ const wednesday = dayjs("2021-03-03T12:00:00");
160
+ switch (format) {
161
+ case DayOfWeekLocaleAwareOutputFormat.DAY_OF_WEEK_SHORT:
162
+ return wednesday.locale(locale).format('dd')
163
+ case DayOfWeekLocaleAwareOutputFormat.DAY_OF_WEEK_NARROW:
164
+ return wednesday.locale(locale).format('ddd')
165
+ case DayOfWeekLocaleAwareOutputFormat.DAY_OF_WEEK_LONG:
166
+ return wednesday.locale(locale).format('dddd')
167
+ default:
168
+ throw new Error(`Unsupported format: ${format}`);
169
+ }
170
+ }
171
+
172
+ if (this.isThursday()) {
173
+ const thursday = dayjs("2021-03-04T12:00:00");
174
+ switch (format) {
175
+ case DayOfWeekLocaleAwareOutputFormat.DAY_OF_WEEK_SHORT:
176
+ return thursday.locale(locale).format('dd')
177
+ case DayOfWeekLocaleAwareOutputFormat.DAY_OF_WEEK_NARROW:
178
+ return thursday.locale(locale).format('ddd')
179
+ case DayOfWeekLocaleAwareOutputFormat.DAY_OF_WEEK_LONG:
180
+ return thursday.locale(locale).format('dddd')
181
+ default:
182
+ throw new Error(`Unsupported format: ${format}`);
183
+ }
184
+ }
185
+
186
+ if (this.isFriday()) {
187
+ const friday = dayjs("2021-03-05T12:00:00");
188
+ switch (format) {
189
+ case DayOfWeekLocaleAwareOutputFormat.DAY_OF_WEEK_SHORT:
190
+ return friday.locale(locale).format('dd')
191
+ case DayOfWeekLocaleAwareOutputFormat.DAY_OF_WEEK_NARROW:
192
+ return friday.locale(locale).format('ddd')
193
+ case DayOfWeekLocaleAwareOutputFormat.DAY_OF_WEEK_LONG:
194
+ return friday.locale(locale).format('dddd')
195
+ default:
196
+ throw new Error(`Unsupported format: ${format}`);
197
+ }
198
+ }
199
+
200
+ if (this.isSaturday()) {
201
+ const saturday = dayjs("2021-03-06T12:00:00");
202
+ switch (format) {
203
+ case DayOfWeekLocaleAwareOutputFormat.DAY_OF_WEEK_SHORT:
204
+ return saturday.locale(locale).format('dd')
205
+ case DayOfWeekLocaleAwareOutputFormat.DAY_OF_WEEK_NARROW:
206
+ return saturday.locale(locale).format('ddd')
207
+ case DayOfWeekLocaleAwareOutputFormat.DAY_OF_WEEK_LONG:
208
+ return saturday.locale(locale).format('dddd')
209
+ default:
210
+ throw new Error(`Unsupported format: ${format}`);
211
+ }
212
+ }
213
+
214
+ if (this.isSunday()) {
215
+ const sunday = dayjs("2021-03-07T12:00:00");
216
+ switch (format) {
217
+ case DayOfWeekLocaleAwareOutputFormat.DAY_OF_WEEK_SHORT:
218
+ return sunday.locale(locale).format('dd')
219
+ case DayOfWeekLocaleAwareOutputFormat.DAY_OF_WEEK_NARROW:
220
+ return sunday.locale(locale).format('ddd')
221
+ case DayOfWeekLocaleAwareOutputFormat.DAY_OF_WEEK_LONG:
222
+ return sunday.locale(locale).format('dddd')
223
+ default:
224
+ throw new Error(`Unsupported format: ${format}`);
225
+ }
226
+ }
227
+
228
+ throw new Error(`Unsupported format: ${format}`);
229
+ }
230
+
231
+ format(format: DayOfWeekOutputFormat): string {
232
+
233
+ switch (format) {
234
+ case DayOfWeekOutputFormat.DAY_OF_WEEK_NUMERIC_ZERO_BASED:
235
+ return String(this.dayOfWeek - 1);
236
+ case DayOfWeekOutputFormat.DAY_OF_WEEK_NUMERIC_ISO8601:
237
+ return String(this.dayOfWeek);
238
+ default:
239
+ throw new Error(`Unsupported format: ${format}`);
240
+ }
241
+ }
242
+ }
@@ -0,0 +1,60 @@
1
+ import {MinuteOutputFormat} from './minute.class';
2
+ import {SecondOutputFormat} from './second.class';
3
+
4
+ export class InvalidHour extends Error {
5
+ static outOfRange() {
6
+ return new InvalidHour("Hour must be between 0 and 23.");
7
+ }
8
+ }
9
+
10
+ export enum HourOutputFormat {
11
+ HOUR_NUMERIC = "hour-numeric",
12
+ HOUR_TWO_DIGIT = "hour-2-digit",
13
+ }
14
+
15
+ export interface HourInterface {
16
+ isSame(other: Hour): boolean;
17
+ asInt(): number;
18
+ format(format: HourOutputFormat): string;
19
+ // formatLocale is not included since seconds don't get formatted local.
20
+ toSeconds(): number;
21
+ }
22
+
23
+ export class Hour implements HourInterface {
24
+ private constructor(private readonly hour: number) {
25
+ if (hour < 0 || hour > 23) {
26
+ throw InvalidHour.outOfRange();
27
+ }
28
+ }
29
+
30
+ static from(hour: number): Hour {
31
+ return new Hour(hour);
32
+ }
33
+
34
+ asInt(): number {
35
+ return this.hour;
36
+ }
37
+
38
+ isSame(other: Hour): boolean {
39
+ return this.asInt() === other.asInt();
40
+ }
41
+
42
+ toSeconds(): number {
43
+ return this.toMinutes() * 60;
44
+ }
45
+
46
+ toMinutes(): number {
47
+ return this.hour * 60;
48
+ }
49
+
50
+ format(format: HourOutputFormat): string {
51
+ switch (format) {
52
+ case HourOutputFormat.HOUR_NUMERIC:
53
+ return String(this.hour);
54
+ case HourOutputFormat.HOUR_TWO_DIGIT:
55
+ return this.hour.toString().padStart(2, "0");
56
+ default:
57
+ throw new Error(`Unsupported format: ${format}`);
58
+ }
59
+ }
60
+ }
@@ -0,0 +1,6 @@
1
+ export enum Locale {
2
+ en = "en",
3
+ nl = "nl",
4
+ fr = "fr",
5
+ de = "de",
6
+ }
@@ -0,0 +1,48 @@
1
+ export class InvalidMilliSecond extends Error {
2
+ static outOfRange() {
3
+ return new InvalidMilliSecond("MilliSecond must be between 0 and 999.");
4
+ }
5
+ }
6
+
7
+ export enum MilliSecondOutputFormat {
8
+ MILLISECOND_NUMERIC = "millisecond-numeric",
9
+ MILLISECOND_THREE_DIGIT = "millisecond-3-digit",
10
+ }
11
+
12
+ export interface MillisecondInterface {
13
+ isSame(other: Millisecond): boolean;
14
+ asInt(): number;
15
+ format(format: MilliSecondOutputFormat): string;
16
+ // formatLocale is not included since seconds don't get formatted local.
17
+ }
18
+
19
+ export class Millisecond implements MillisecondInterface {
20
+ private constructor(private readonly millisecond: number) {
21
+ if (millisecond < 0 || millisecond > 999) {
22
+ throw InvalidMilliSecond.outOfRange();
23
+ }
24
+ }
25
+
26
+ static from(millisecond: number): Millisecond {
27
+ return new Millisecond(millisecond);
28
+ }
29
+
30
+ asInt(): number {
31
+ return this.millisecond;
32
+ }
33
+
34
+ isSame(other: Millisecond): boolean {
35
+ return this.asInt() === other.asInt();
36
+ }
37
+
38
+ format(format: MilliSecondOutputFormat): string {
39
+ switch (format) {
40
+ case MilliSecondOutputFormat.MILLISECOND_NUMERIC:
41
+ return String(this.millisecond);
42
+ case MilliSecondOutputFormat.MILLISECOND_THREE_DIGIT:
43
+ return this.millisecond.toString().padStart(3, "0");
44
+ default:
45
+ throw new Error(`Unsupported format: ${format}`);
46
+ }
47
+ }
48
+ }
@@ -0,0 +1,55 @@
1
+ import {SecondOutputFormat} from './second.class';
2
+
3
+ export class InvalidMinute extends Error {
4
+ static outOfRange() {
5
+ return new InvalidMinute("Minute must be between 0 and 59.");
6
+ }
7
+ }
8
+
9
+ export enum MinuteOutputFormat {
10
+ MINUTE_NUMERIC = "minute-numeric",
11
+ MINUTE_TWO_DIGIT = "minute-2-digit",
12
+ }
13
+
14
+ export interface MinuteInterface {
15
+ isSame(other: Minute): boolean;
16
+ asInt(): number;
17
+ toSeconds(): number;
18
+ format(format: MinuteOutputFormat): string;
19
+ // formatLocale is not included since seconds don't get formatted local.
20
+ }
21
+
22
+ export class Minute {
23
+ private constructor(private readonly minute: number) {
24
+ if (minute < 0 || minute > 59) {
25
+ throw InvalidMinute.outOfRange();
26
+ }
27
+ }
28
+
29
+ static from(minute: number): Minute {
30
+ return new Minute(minute);
31
+ }
32
+
33
+ asInt(): number {
34
+ return this.minute;
35
+ }
36
+
37
+ format(format: MinuteOutputFormat): string {
38
+ switch (format) {
39
+ case MinuteOutputFormat.MINUTE_NUMERIC:
40
+ return String(this.minute);
41
+ case MinuteOutputFormat.MINUTE_TWO_DIGIT:
42
+ return this.minute.toString().padStart(2, "0");
43
+ default:
44
+ throw new Error(`Unsupported format: ${format}`);
45
+ }
46
+ }
47
+
48
+ isSame(other: Minute): boolean {
49
+ return this.asInt() === other.asInt();
50
+ }
51
+
52
+ toSeconds(): number {
53
+ return this.minute * 60;
54
+ }
55
+ }
@@ -0,0 +1,74 @@
1
+ import {Locale} from './locale';
2
+ import dayjs from './dayjs-config';
3
+
4
+ export class InvalidMonth extends Error {
5
+ static notInScope() {
6
+ return new InvalidMonth("Month must be between 0 and 11.");
7
+ }
8
+ }
9
+
10
+ export enum MonthOutputFormat {
11
+ MONTH_NUMERIC = "month-numeric",
12
+ MONTH_TWO_DIGIT = "month-2-digit",
13
+ }
14
+
15
+ export enum MonthLocalAwareOutputFormat {
16
+ MONTH_LONG = "month-long",
17
+ MONTH_SHORT = "month-short",
18
+ }
19
+
20
+ export interface MonthInterface {
21
+ isSame(month: Month): boolean;
22
+ asInt(): number;
23
+ format(format: MonthOutputFormat): string;
24
+ formatLocale(format: MonthLocalAwareOutputFormat, locale: Locale): string;
25
+ }
26
+
27
+ export enum MonthIndex {
28
+ ZERO_BASED = "zero-based", // January = 0, December = 11
29
+ ONE_BASED = "one-based", // January = 1, December = 12
30
+ }
31
+
32
+ export class Month implements MonthInterface {
33
+ private constructor(private readonly month: number) {
34
+ if (this.month < 0 || this.month > 11) {
35
+ throw InvalidMonth.notInScope();
36
+ }
37
+ }
38
+
39
+ static from(month: number, index: MonthIndex = MonthIndex.ZERO_BASED): Month {
40
+ return new Month(index === MonthIndex.ONE_BASED ? month - 1 : month);
41
+ }
42
+
43
+ asInt(index: MonthIndex = MonthIndex.ZERO_BASED): number {
44
+ return index === MonthIndex.ONE_BASED ? this.month + 1 : this.month;
45
+ }
46
+
47
+ isSame(month: Month): boolean {
48
+ return this.asInt() === month.asInt();
49
+ }
50
+
51
+ format(format: MonthOutputFormat): string {
52
+ const month = this.month + 1; // Stored 0 based.
53
+ switch (format) {
54
+ case MonthOutputFormat.MONTH_NUMERIC:
55
+ return month.toString();
56
+ case MonthOutputFormat.MONTH_TWO_DIGIT:
57
+ return month.toString().padStart(2, "0");
58
+ }
59
+ }
60
+
61
+ formatLocale(format: MonthLocalAwareOutputFormat, locale: Locale): string {
62
+ // Fake date the format month in locale.
63
+ const date = dayjs('2023-' + this.format(MonthOutputFormat.MONTH_TWO_DIGIT) + '-01T' + '12:00:00')
64
+
65
+ switch (format) {
66
+ case MonthLocalAwareOutputFormat.MONTH_LONG:
67
+ return date.locale(locale).format('MMMM');
68
+ case MonthLocalAwareOutputFormat.MONTH_SHORT:
69
+ return date.locale(locale).format('MMM');
70
+ default:
71
+ throw new Error(`Unsupported format: ${format}`);
72
+ }
73
+ }
74
+ }
@@ -0,0 +1,52 @@
1
+ import {Locale} from './locale';
2
+ import {MonthLocalAwareOutputFormat, MonthOutputFormat} from './month.class';
3
+ import {YearOutputFormat} from './year.class';
4
+
5
+ export class InvalidSecond extends Error {
6
+ static outOfRange() {
7
+ return new InvalidSecond("Second must be between 0 and 59.");
8
+ }
9
+ }
10
+
11
+ export enum SecondOutputFormat {
12
+ SECOND_NUMERIC = "second-numeric",
13
+ SECOND_TWO_DIGIT = "second-2-digit",
14
+ }
15
+
16
+ export interface SecondInterface {
17
+ isSame(other: Second): boolean;
18
+ asInt(): number;
19
+ format(format: SecondOutputFormat): string;
20
+ // formatLocale is not included since seconds don't get formatted local.
21
+ }
22
+
23
+ export class Second implements SecondInterface {
24
+ private constructor(private readonly second: number) {
25
+ if (second < 0 || second > 59) {
26
+ throw InvalidSecond.outOfRange();
27
+ }
28
+ }
29
+
30
+ static from(second: number): Second {
31
+ return new Second(second);
32
+ }
33
+
34
+ asInt(): number {
35
+ return this.second;
36
+ }
37
+
38
+ isSame(other: Second): boolean {
39
+ return this.asInt() === other.asInt();
40
+ }
41
+
42
+ format(format: SecondOutputFormat): string {
43
+ switch (format) {
44
+ case SecondOutputFormat.SECOND_NUMERIC:
45
+ return String(this.second);
46
+ case SecondOutputFormat.SECOND_TWO_DIGIT:
47
+ return this.second.toString().padStart(2, "0");
48
+ default:
49
+ throw new Error(`Unsupported format: ${format}`);
50
+ }
51
+ }
52
+ }