@tacdaed/fragments 1.0.0-beta.0 → 1.0.0-beta.2

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 (248) hide show
  1. package/README.md +2 -18
  2. package/ng-package.json +25 -0
  3. package/package.json +22 -29
  4. package/src/lib/components/accordion/accordion.component.html +103 -0
  5. package/src/lib/components/accordion/accordion.component.scss +382 -0
  6. package/src/lib/components/accordion/accordion.component.spec.ts +147 -0
  7. package/src/lib/components/accordion/accordion.component.ts +211 -0
  8. package/src/lib/components/accordion/accordion.type.ts +82 -0
  9. package/src/lib/components/breadcrumb/breadcrumb.component.html +43 -0
  10. package/src/lib/components/breadcrumb/breadcrumb.component.scss +112 -0
  11. package/src/lib/components/breadcrumb/breadcrumb.component.spec.ts +33 -0
  12. package/src/lib/components/breadcrumb/breadcrumb.component.ts +103 -0
  13. package/src/lib/components/breadcrumb/breadcrumb.interface.ts +7 -0
  14. package/src/lib/components/button/button.component.html +57 -0
  15. package/src/lib/components/button/button.component.scss +445 -0
  16. package/src/lib/components/button/button.component.spec.ts +99 -0
  17. package/src/lib/components/button/button.component.ts +143 -0
  18. package/src/lib/components/button/button.type.ts +7 -0
  19. package/src/lib/components/card/card.component.html +44 -0
  20. package/src/lib/components/card/card.component.scss +114 -0
  21. package/src/lib/components/card/card.component.spec.ts +65 -0
  22. package/src/lib/components/card/card.component.ts +21 -0
  23. package/src/lib/components/card/card.type.ts +3 -0
  24. package/src/lib/components/code-block/code-block.component.html +55 -0
  25. package/src/lib/components/code-block/code-block.component.scss +122 -0
  26. package/src/lib/components/code-block/code-block.component.spec.ts +81 -0
  27. package/src/lib/components/code-block/code-block.component.ts +302 -0
  28. package/src/lib/components/code-block/code-block.interface.ts +28 -0
  29. package/src/lib/components/code-block/code-block.type.ts +73 -0
  30. package/src/lib/components/decorative/sparkle-field/sparkle-field.component.html +14 -0
  31. package/src/lib/components/decorative/sparkle-field/sparkle-field.component.scss +20 -0
  32. package/src/lib/components/decorative/sparkle-field/sparkle-field.component.spec.ts +38 -0
  33. package/src/lib/components/decorative/sparkle-field/sparkle-field.component.ts +181 -0
  34. package/src/lib/components/input/input-base.ts +187 -0
  35. package/src/lib/components/input/input-calendar/input-calendar.component.html +76 -0
  36. package/src/lib/components/input/input-calendar/input-calendar.component.scss +179 -0
  37. package/src/lib/components/input/input-calendar/input-calendar.component.spec.ts +44 -0
  38. package/src/lib/components/input/input-calendar/input-calendar.component.ts +299 -0
  39. package/src/lib/components/input/input-checkbox/input-checkbox.component.html +37 -0
  40. package/src/lib/components/input/input-checkbox/input-checkbox.component.scss +128 -0
  41. package/src/lib/components/input/input-checkbox/input-checkbox.component.spec.ts +43 -0
  42. package/src/lib/components/input/input-checkbox/input-checkbox.component.ts +112 -0
  43. package/src/lib/components/input/input-checkbox-group/input-checkbox-group.component.html +43 -0
  44. package/src/lib/components/input/input-checkbox-group/input-checkbox-group.component.scss +140 -0
  45. package/src/lib/components/input/input-checkbox-group/input-checkbox-group.component.spec.ts +62 -0
  46. package/src/lib/components/input/input-checkbox-group/input-checkbox-group.component.ts +136 -0
  47. package/src/lib/components/input/input-clock-picker/input-clock-picker.component.html +81 -0
  48. package/src/lib/components/input/input-clock-picker/input-clock-picker.component.scss +228 -0
  49. package/src/lib/components/input/input-clock-picker/input-clock-picker.component.spec.ts +62 -0
  50. package/src/lib/components/input/input-clock-picker/input-clock-picker.component.ts +178 -0
  51. package/src/lib/components/input/input-consts.ts +132 -0
  52. package/src/lib/components/input/input-date/input-date-validators.ts +41 -0
  53. package/src/lib/components/input/input-date/input-date.component.html +41 -0
  54. package/src/lib/components/input/input-date/input-date.component.scss +95 -0
  55. package/src/lib/components/input/input-date/input-date.component.spec.ts +43 -0
  56. package/src/lib/components/input/input-date/input-date.component.ts +359 -0
  57. package/src/lib/components/input/input-date-time/input-date-time.component.html +70 -0
  58. package/src/lib/components/input/input-date-time/input-date-time.component.scss +133 -0
  59. package/src/lib/components/input/input-date-time/input-date-time.component.spec.ts +36 -0
  60. package/src/lib/components/input/input-date-time/input-date-time.component.ts +387 -0
  61. package/src/lib/components/input/input-file-upload/input-file-upload.component.html +89 -0
  62. package/src/lib/components/input/input-file-upload/input-file-upload.component.scss +171 -0
  63. package/src/lib/components/input/input-file-upload/input-file-upload.component.spec.ts +43 -0
  64. package/src/lib/components/input/input-file-upload/input-file-upload.component.ts +351 -0
  65. package/src/lib/components/input/input-interface.ts +8 -0
  66. package/src/lib/components/input/input-number/input-number-validators.ts +0 -0
  67. package/src/lib/components/input/input-number/input-number.component.html +51 -0
  68. package/src/lib/components/input/input-number/input-number.component.scss +140 -0
  69. package/src/lib/components/input/input-number/input-number.component.spec.ts +44 -0
  70. package/src/lib/components/input/input-number/input-number.component.ts +343 -0
  71. package/src/lib/components/input/input-radio-group/input-radio-group.component.html +44 -0
  72. package/src/lib/components/input/input-radio-group/input-radio-group.component.scss +139 -0
  73. package/src/lib/components/input/input-radio-group/input-radio-group.component.spec.ts +58 -0
  74. package/src/lib/components/input/input-radio-group/input-radio-group.component.ts +132 -0
  75. package/src/lib/components/input/input-slider/input-slider.component.html +111 -0
  76. package/src/lib/components/input/input-slider/input-slider.component.scss +203 -0
  77. package/src/lib/components/input/input-slider/input-slider.component.spec.ts +46 -0
  78. package/src/lib/components/input/input-slider/input-slider.component.ts +410 -0
  79. package/src/lib/components/input/input-text/input-text-validators.ts +67 -0
  80. package/src/lib/components/input/input-text/input-text.component.html +71 -0
  81. package/src/lib/components/input/input-text/input-text.component.scss +118 -0
  82. package/src/lib/components/input/input-text/input-text.component.spec.ts +55 -0
  83. package/src/lib/components/input/input-text/input-text.component.ts +215 -0
  84. package/src/lib/components/input/input-time/input-time-validators.ts +42 -0
  85. package/src/lib/components/input/input-time/input-time.component.html +92 -0
  86. package/src/lib/components/input/input-time/input-time.component.scss +191 -0
  87. package/src/lib/components/input/input-time/input-time.component.spec.ts +39 -0
  88. package/src/lib/components/input/input-time/input-time.component.ts +691 -0
  89. package/src/lib/components/input/input-toggle-switch/input-toggle-switch.component.html +36 -0
  90. package/src/lib/components/input/input-toggle-switch/input-toggle-switch.component.scss +121 -0
  91. package/src/lib/components/input/input-toggle-switch/input-toggle-switch.component.spec.ts +54 -0
  92. package/src/lib/components/input/input-toggle-switch/input-toggle-switch.component.ts +117 -0
  93. package/src/lib/components/input/input-type.ts +18 -0
  94. package/src/lib/components/input/input-validation/input-validation.component.html +19 -0
  95. package/src/lib/components/input/input-validation/input-validation.component.scss +39 -0
  96. package/src/lib/components/input/input-validation/input-validation.component.spec.ts +45 -0
  97. package/src/lib/components/input/input-validation/input-validation.component.ts +13 -0
  98. package/src/lib/components/input/input.pipe.ts +14 -0
  99. package/src/lib/components/layout/container/container.component.html +1 -0
  100. package/src/lib/components/layout/container/container.component.scss +33 -0
  101. package/src/lib/components/layout/container/container.component.ts +32 -0
  102. package/src/lib/components/layout/container/container.type.ts +1 -0
  103. package/src/lib/components/layout/divider/divider.component.html +1 -0
  104. package/src/lib/components/layout/divider/divider.component.scss +60 -0
  105. package/src/lib/components/layout/divider/divider.component.ts +38 -0
  106. package/src/lib/components/layout/divider/divider.type.ts +2 -0
  107. package/src/lib/components/layout/section/section.component.html +21 -0
  108. package/src/lib/components/layout/section/section.component.scss +43 -0
  109. package/src/lib/components/layout/section/section.component.ts +33 -0
  110. package/src/lib/components/layout/section/section.type.ts +2 -0
  111. package/src/lib/components/layout/separator/separator.component.html +9 -0
  112. package/src/lib/components/layout/separator/separator.component.scss +52 -0
  113. package/src/lib/components/layout/separator/separator.component.ts +25 -0
  114. package/src/lib/components/layout/separator/separator.type.ts +1 -0
  115. package/src/lib/components/loader/content-blur/content-blur.component.html +13 -0
  116. package/src/lib/components/loader/content-blur/content-blur.component.scss +43 -0
  117. package/src/lib/components/loader/content-blur/content-blur.component.spec.ts +42 -0
  118. package/src/lib/components/loader/content-blur/content-blur.component.ts +34 -0
  119. package/src/lib/components/loader/loader.type.ts +2 -0
  120. package/src/lib/components/loader/progress-bar/progress-bar.component.html +26 -0
  121. package/src/lib/components/loader/progress-bar/progress-bar.component.scss +151 -0
  122. package/src/lib/components/loader/progress-bar/progress-bar.component.spec.ts +47 -0
  123. package/src/lib/components/loader/progress-bar/progress-bar.component.ts +28 -0
  124. package/src/lib/components/loader/progress-bar/progress-bar.type.ts +8 -0
  125. package/src/lib/components/loader/pulse-loader/pulse-loader.component.html +12 -0
  126. package/src/lib/components/loader/pulse-loader/pulse-loader.component.scss +202 -0
  127. package/src/lib/components/loader/pulse-loader/pulse-loader.component.spec.ts +55 -0
  128. package/src/lib/components/loader/pulse-loader/pulse-loader.component.ts +73 -0
  129. package/src/lib/components/loader/pulse-loader/pulse-loader.type.ts +6 -0
  130. package/src/lib/components/loader/skeleton-loader/skeleton-loader.component.html +13 -0
  131. package/src/lib/components/loader/skeleton-loader/skeleton-loader.component.scss +113 -0
  132. package/src/lib/components/loader/skeleton-loader/skeleton-loader.component.spec.ts +37 -0
  133. package/src/lib/components/loader/skeleton-loader/skeleton-loader.component.ts +51 -0
  134. package/src/lib/components/loader/skeleton-loader/skeleton-loader.type.ts +6 -0
  135. package/src/lib/components/loader/spinner/spinner.component.html +20 -0
  136. package/src/lib/components/loader/spinner/spinner.component.scss +137 -0
  137. package/src/lib/components/loader/spinner/spinner.component.spec.ts +43 -0
  138. package/src/lib/components/loader/spinner/spinner.component.ts +32 -0
  139. package/src/lib/components/loader/spinner/spinner.type.ts +6 -0
  140. package/src/lib/components/modal/modal.component.html +47 -0
  141. package/src/lib/components/modal/modal.component.scss +139 -0
  142. package/src/lib/components/modal/modal.component.spec.ts +60 -0
  143. package/src/lib/components/modal/modal.component.ts +83 -0
  144. package/src/lib/components/modal/modal.type.ts +9 -0
  145. package/src/lib/components/morph/blob-moph/blob-moprh.component.spec.ts +79 -0
  146. package/src/lib/components/morph/blob-moph/blob-moprh.component.ts +96 -0
  147. package/src/lib/components/morph/blob-moph/blob-morph.component.html +34 -0
  148. package/src/lib/components/morph/blob-moph/blob-morph.component.scss +7 -0
  149. package/src/lib/components/morph/morph.abstract.ts +13 -0
  150. package/src/lib/components/pagination/pagination.interface.ts +4 -0
  151. package/src/lib/components/pagination/small-pagination/small-pagination.component.html +61 -0
  152. package/src/lib/components/pagination/small-pagination/small-pagination.component.scss +187 -0
  153. package/src/lib/components/pagination/small-pagination/small-pagination.component.spec.ts +88 -0
  154. package/src/lib/components/pagination/small-pagination/small-pagination.component.ts +177 -0
  155. package/src/lib/components/selection-lists/multi-select/multi-select.component.html +170 -0
  156. package/src/lib/components/selection-lists/multi-select/multi-select.component.scss +312 -0
  157. package/src/lib/components/selection-lists/multi-select/multi-select.component.spec.ts +61 -0
  158. package/src/lib/components/selection-lists/multi-select/multi-select.component.ts +372 -0
  159. package/src/lib/components/selection-lists/selection-list/selection-list.component.html +125 -0
  160. package/src/lib/components/selection-lists/selection-list/selection-list.component.scss +267 -0
  161. package/src/lib/components/selection-lists/selection-list/selection-list.component.spec.ts +66 -0
  162. package/src/lib/components/selection-lists/selection-list/selection-list.component.ts +315 -0
  163. package/src/lib/components/selection-lists/selection-lists-base.ts +35 -0
  164. package/src/lib/components/selection-lists/selection-lists-const.ts +17 -0
  165. package/src/lib/components/selection-lists/selection-lists-interface.ts +7 -0
  166. package/src/lib/components/selection-lists/selection-lists.type.ts +1 -0
  167. package/src/lib/components/side-nav/side-nav.component.html +101 -0
  168. package/src/lib/components/side-nav/side-nav.component.scss +295 -0
  169. package/src/lib/components/side-nav/side-nav.component.spec.ts +0 -0
  170. package/src/lib/components/side-nav/side-nav.component.ts +18 -0
  171. package/src/lib/components/side-nav/side-nav.type.ts +28 -0
  172. package/src/lib/components/snackbar/snackbar.component.html +33 -0
  173. package/src/lib/components/snackbar/snackbar.component.scss +195 -0
  174. package/src/lib/components/snackbar/snackbar.component.ts +112 -0
  175. package/src/lib/components/snackbar/snackbar.type.ts +27 -0
  176. package/src/lib/components/status/chip/chip.component.html +51 -0
  177. package/src/lib/components/status/chip/chip.component.scss +149 -0
  178. package/src/lib/components/status/chip/chip.component.spec.ts +62 -0
  179. package/src/lib/components/status/chip/chip.component.ts +83 -0
  180. package/src/lib/components/status/chip/chip.type.ts +42 -0
  181. package/src/lib/components/status/directives/badge/badge.directive.spec.ts +60 -0
  182. package/src/lib/components/status/directives/badge/badge.directive.ts +190 -0
  183. package/src/lib/components/status/directives/badge/badge.interface.ts +19 -0
  184. package/src/lib/components/status/pill/pill.component.html +40 -0
  185. package/src/lib/components/status/pill/pill.component.scss +113 -0
  186. package/src/lib/components/status/pill/pill.component.spec.ts +47 -0
  187. package/src/lib/components/status/pill/pill.component.ts +83 -0
  188. package/src/lib/components/status/pill/pill.type.ts +42 -0
  189. package/src/lib/components/status/status.interface.ts +57 -0
  190. package/src/lib/components/status/status.type.ts +62 -0
  191. package/src/lib/components/status/tag/tag.component.html +39 -0
  192. package/src/lib/components/status/tag/tag.component.scss +140 -0
  193. package/src/lib/components/status/tag/tag.component.spec.ts +47 -0
  194. package/src/lib/components/status/tag/tag.component.ts +83 -0
  195. package/src/lib/components/status/tag/tag.type.ts +42 -0
  196. package/src/lib/components/stepper/stepper.component.html +83 -0
  197. package/src/lib/components/stepper/stepper.component.scss +196 -0
  198. package/src/lib/components/stepper/stepper.component.ts +482 -0
  199. package/src/lib/components/stepper/stepper.type.ts +60 -0
  200. package/src/lib/components/table/table.component.html +438 -0
  201. package/src/lib/components/table/table.component.scss +259 -0
  202. package/src/lib/components/table/table.component.spec.ts +117 -0
  203. package/src/lib/components/table/table.component.ts +215 -0
  204. package/src/lib/components/table/table.enum.ts +4 -0
  205. package/src/lib/components/table/table.function.ts +47 -0
  206. package/src/lib/components/table/table.interface.ts +143 -0
  207. package/src/lib/components/table/table.pipe.ts +62 -0
  208. package/src/lib/components/table/table.type.ts +15 -0
  209. package/src/lib/components/tabs/tabs.component.html +88 -0
  210. package/src/lib/components/tabs/tabs.component.scss +305 -0
  211. package/src/lib/components/tabs/tabs.component.spec.ts +94 -0
  212. package/src/lib/components/tabs/tabs.component.ts +282 -0
  213. package/src/lib/components/tabs/tabs.type.ts +81 -0
  214. package/src/lib/components/title-bar/title-bar.component.html +21 -0
  215. package/src/lib/components/title-bar/title-bar.component.scss +139 -0
  216. package/src/lib/components/title-bar/title-bar.component.spec.ts +44 -0
  217. package/src/lib/components/title-bar/title-bar.component.ts +13 -0
  218. package/src/lib/components/toast/toast.component.html +36 -0
  219. package/src/lib/components/toast/toast.component.scss +241 -0
  220. package/src/lib/components/toast/toast.component.ts +165 -0
  221. package/src/lib/components/toast/toast.type.ts +37 -0
  222. package/src/lib/components/toast-stack/toast-stack.component.html +30 -0
  223. package/src/lib/components/toast-stack/toast-stack.component.scss +35 -0
  224. package/src/lib/components/toast-stack/toast-stack.component.ts +51 -0
  225. package/src/lib/consts/country-prefix.ts +244 -0
  226. package/src/lib/directives/tooltip/popover.directive.ts +274 -0
  227. package/src/lib/directives/tooltip/tooltip.directive.spec.ts +86 -0
  228. package/src/lib/directives/tooltip/tooltip.directive.ts +234 -0
  229. package/src/lib/directives/tooltip/tooltip.interface.ts +29 -0
  230. package/src/lib/directives/tooltip/tooltip.type.ts +9 -0
  231. package/src/lib/interfaces/common.interfaces.ts +4 -0
  232. package/src/lib/pipes/chunk.pipe.ts +16 -0
  233. package/src/lib/pipes/safe-html.pipe.ts +14 -0
  234. package/src/lib/pipes/sanitize-html.pipe.ts +23 -0
  235. package/src/lib/types/base.types.ts +23 -0
  236. package/src/lib/types/common.types.ts +98 -0
  237. package/src/lib/types/form.types.ts +5 -0
  238. package/src/lib/utils/common.utils.ts +53 -0
  239. package/src/lib/utils/date.utils.ts +474 -0
  240. package/src/lib/utils/number.utils.ts +16 -0
  241. package/src/lib/utils/uuid.utils.ts +39 -0
  242. package/src/public-api.ts +114 -0
  243. package/tsconfig.lib.json +17 -0
  244. package/tsconfig.lib.prod.json +10 -0
  245. package/tsconfig.spec.json +9 -0
  246. package/fesm2022/fragments.mjs +0 -8928
  247. package/fesm2022/fragments.mjs.map +0 -1
  248. package/index.d.ts +0 -3929
@@ -0,0 +1,299 @@
1
+ import { AsyncPipe, formatDate } from '@angular/common';
2
+ import { Component, EventEmitter, inject, Input, LOCALE_ID, OnInit, Output } from '@angular/core';
3
+ import { BehaviorSubject } from 'rxjs';
4
+ import { ChunkPipe } from '../../../pipes/chunk.pipe';
5
+
6
+ @Component({
7
+ selector: 'frg-input-calendar',
8
+ imports: [ChunkPipe, AsyncPipe],
9
+ templateUrl: './input-calendar.component.html',
10
+ styleUrl: './input-calendar.component.scss',
11
+ })
12
+ export class InputCalendarComponent implements OnInit {
13
+ private readonly locale: string = inject(LOCALE_ID);
14
+
15
+ /**
16
+ * Current day
17
+ */
18
+ public currentDay: number = new Date().getDate();
19
+ /**
20
+ * Month is 0 indexed in JavaScript Date, so we add 1 to make it 1 indexed
21
+ */
22
+ public currentMonth: number = new Date().getMonth() + 1;
23
+ /**
24
+ * Current year
25
+ */
26
+ public currentYear: number = new Date().getFullYear();
27
+
28
+ /**
29
+ * Minimum date selectable in the calendar
30
+ * @default 0
31
+ */
32
+ @Input() public minDate: Date = new Date(0, 0, 1);
33
+ /**
34
+ * Maximum date selectable in the calendar
35
+ * @default 9999-12-31
36
+ */
37
+ @Input() public maxDate: Date = new Date(9999, 11, 31);
38
+ /**
39
+ * The currently selected date
40
+ * @default null
41
+ */
42
+ @Input() public selectedValue: Date | null = null;
43
+ /**
44
+ * Event emitted when a date is selected
45
+ * @type {EventEmitter<Date>}
46
+ */
47
+ @Output() selectDate = new EventEmitter<Date>();
48
+ /**
49
+ * Event emitted when value is hi than max date
50
+ * @type {EventEmitter<Date>}
51
+ */
52
+ @Output() handleMaxDate = new EventEmitter<Date>();
53
+ /**
54
+ * Event emitted when value is less than min date
55
+ * @type {EventEmitter<Date>}
56
+ */
57
+ @Output() handleMinDate = new EventEmitter<Date>();
58
+
59
+ /**
60
+ * Used for show month selection
61
+ */
62
+ public hasMonthSelectionOpen$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
63
+
64
+ /**
65
+ * Used for show year selection
66
+ */
67
+ public hasYearSelectionOpen$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
68
+
69
+ /**
70
+ * Array of dates to display in the calendar
71
+ */
72
+ public get calendarDays(): Date[] {
73
+ const days: Date[] = [];
74
+ const monthIndex = this.currentMonth - 1;
75
+ const firstDayOfMonth = new Date(this.currentYear, monthIndex, 1);
76
+ const lastDayOfMonth = new Date(this.currentYear, monthIndex + 1, 0);
77
+
78
+ const startDayOfWeek = firstDayOfMonth.getDay();
79
+ for (let i = startDayOfWeek - 1; i >= 0; i--) {
80
+ days.push(new Date(this.currentYear, monthIndex, -i));
81
+ }
82
+
83
+ for (let day = 1; day <= lastDayOfMonth.getDate(); day++) {
84
+ days.push(new Date(this.currentYear, monthIndex, day));
85
+ }
86
+
87
+ const endDayOfWeek = lastDayOfMonth.getDay();
88
+ for (let i = 1; i < 7 - endDayOfWeek; i++) {
89
+ days.push(new Date(this.currentYear, monthIndex + 1, i));
90
+ }
91
+ return days;
92
+ }
93
+
94
+ /**
95
+ * Get the short names of the weekdays based on the current locale
96
+ */
97
+ public get weekDays(): string[] {
98
+ const referenceDate = new Date(2025, 0, 5);
99
+ const week: string[] = [];
100
+
101
+ for (let i = 0; i < 7; i++) {
102
+ const day = new Date(referenceDate);
103
+ day.setDate(referenceDate.getDate() + i);
104
+ week.push(formatDate(day, 'EEE', this.locale));
105
+ }
106
+
107
+ return week;
108
+ }
109
+
110
+ public get years(): number[] {
111
+ const years: number[] = [];
112
+ for (let y = this.minDate.getFullYear(); y <= this.maxDate.getFullYear(); y++) {
113
+ years.push(y);
114
+ }
115
+ return years;
116
+ }
117
+
118
+ public get months(): string[] {
119
+ const months: string[] = [];
120
+ for (let m = 0; m < 12; m++) {
121
+ const date = new Date(this.currentYear, m, 1);
122
+ months.push(formatDate(date, 'LLLL', this.locale));
123
+ }
124
+ return months;
125
+ }
126
+
127
+ /**
128
+ * Get the current month in long format (e.g., January, February)
129
+ */
130
+ public get month(): string {
131
+ const date = new Date(this.currentYear, this.currentMonth - 1);
132
+ return formatDate(date, 'LLLL', this.locale);
133
+ }
134
+
135
+ /**
136
+ * Get the current year as a string
137
+ */
138
+ public get year(): string {
139
+ return this.currentYear.toString();
140
+ }
141
+
142
+ ngOnInit() {
143
+ if (this.selectedValue) {
144
+ this.currentDay = this.selectedValue.getDate();
145
+ this.currentMonth = this.selectedValue.getMonth() + 1;
146
+ this.currentYear = this.selectedValue.getFullYear();
147
+ } else {
148
+ const today = new Date();
149
+ this.currentDay = today.getDate();
150
+ this.currentMonth = today.getMonth() + 1;
151
+ this.currentYear = today.getFullYear();
152
+ }
153
+ }
154
+
155
+ /**
156
+ * Check if a given day is today
157
+ * @param day - The date to check
158
+ * @returns True if the given day is today, false otherwise
159
+ */
160
+ protected isToday(day: Date): boolean {
161
+ const today = new Date();
162
+ return day.getDate() === today.getDate() &&
163
+ day.getMonth() === today.getMonth() &&
164
+ day.getFullYear() === today.getFullYear();
165
+ }
166
+
167
+ /**
168
+ * Change the current month, adjusting the year if necessary
169
+ * @param month - The new month to set (1-12)
170
+ */
171
+ protected changeMonth(month: number){
172
+ if(month >= 13){
173
+ this.currentMonth = 1;
174
+ this.currentYear++;
175
+ } else if(month <= 0){
176
+ this.currentMonth = 12;
177
+ this.currentYear--;
178
+ } else {
179
+ this.currentMonth = month;
180
+ }
181
+
182
+ if(this.currentYear > this.maxDate.getFullYear()){
183
+ this.currentDay = this.maxDate.getDate();
184
+ this.currentMonth = this.maxDate.getMonth() + 1;
185
+ this.currentYear = this.maxDate.getFullYear();
186
+ this.handleMaxDate.emit(this.maxDate);
187
+ }
188
+
189
+ if(this.currentYear < this.minDate.getFullYear()){
190
+ this.currentDay = this.minDate.getDate();
191
+ this.currentMonth = this.minDate.getMonth() + 1;
192
+ this.currentYear = this.minDate.getFullYear();
193
+ this.handleMinDate.emit(this.minDate);
194
+ }
195
+ }
196
+
197
+ /**
198
+ * Open or close the month selection dropdown
199
+ */
200
+ protected openYearSelection() {
201
+ this.hasYearSelectionOpen$.next(!this.hasYearSelectionOpen$.value);
202
+ this.hasMonthSelectionOpen$.next(false);
203
+
204
+ if (this.hasYearSelectionOpen$.value) {
205
+ requestAnimationFrame(() => {
206
+ const yearButtons = document.querySelectorAll<HTMLButtonElement>(
207
+ '.frg-date-selection__year__item-list button'
208
+ );
209
+
210
+ yearButtons.forEach(btn => {
211
+ if (this.currentYear === parseInt(btn.textContent || '', 10)) {
212
+ btn.focus();
213
+ }
214
+ });
215
+ });
216
+ }
217
+ }
218
+ /**
219
+ * Open or close the month selection dropdown
220
+ */
221
+ protected openMonthSelection() {
222
+ this.hasMonthSelectionOpen$.next(!this.hasMonthSelectionOpen$.value);
223
+ this.hasYearSelectionOpen$.next(false);
224
+
225
+ if (this.hasMonthSelectionOpen$.value) {
226
+ requestAnimationFrame(() => {
227
+ const monthButtons = document.querySelectorAll<HTMLButtonElement>(
228
+ '.frg-date-selection__month__item-list button'
229
+ );
230
+
231
+ monthButtons.forEach((btn, index) => {
232
+ if (this.currentMonth === index + 1) {
233
+ btn.focus();
234
+ }
235
+ });
236
+ });
237
+ }
238
+ }
239
+
240
+ /**
241
+ * Handle the selection of a date and emit the selected date
242
+ * @param date - The date that was selected
243
+ */
244
+ protected onSelectDate(event: PointerEvent, date: Date): void {
245
+ event.stopPropagation();
246
+ this.selectDate.emit(date);
247
+ }
248
+
249
+ /**
250
+ * Check if a date is disabled based on minDate and maxDate
251
+ * @param a - The date to check
252
+ * @returns True if the date is disabled, false otherwise
253
+ */
254
+ protected isDisabled(a: Date): boolean {
255
+ if (this.minDate && this.maxDate) {
256
+ return a < this.minDate || a > this.maxDate;
257
+ }
258
+
259
+ return false;
260
+ }
261
+
262
+ /**
263
+ * Check if a date is the currently selected date
264
+ * @param a - The date to check
265
+ * @param b - The currently selected date
266
+ * @returns True if the dates are the same, false otherwise
267
+ */
268
+ protected isSelected(a: Date, b: Date | null): boolean {
269
+ if (b) {
270
+ return a.getDate() === b.getDate()
271
+ && a.getMonth() === b.getMonth()
272
+ && a.getFullYear() === b.getFullYear();
273
+ }
274
+
275
+ return false;
276
+ }
277
+
278
+ /**
279
+ * Check if a date is the currently selected date
280
+ * @param a - The date to check
281
+ * @param b - The currently selected date
282
+ * @returns True if the dates are the same, false otherwise
283
+ */
284
+ protected isSelectedYearOrMonth(a: number, b: number | null): boolean {
285
+ return Boolean(b && a === b);
286
+ }
287
+
288
+ protected selectMonth(event: MouseEvent, month: number): void {
289
+ event.stopPropagation();
290
+ this.currentMonth = month;
291
+ this.hasMonthSelectionOpen$.next(false);
292
+ }
293
+
294
+ protected selectYear(event: MouseEvent, year: number): void {
295
+ event.stopPropagation();
296
+ this.currentYear = year;
297
+ this.hasYearSelectionOpen$.next(false);
298
+ }
299
+ }
@@ -0,0 +1,37 @@
1
+ <div
2
+ class="frg-checkbox__wrapper"
3
+ [class.input-error]="hasError"
4
+ [class.input-warning]="hasWarning"
5
+ [ngClass]="{
6
+ 'frg-checkbox__primary': styleType === 'primary',
7
+ 'frg-checkbox__secondary': styleType === 'secondary',
8
+ 'frg-checkbox__tertiary': styleType === 'tertiary',
9
+ 'frg-checkbox__success': styleType === 'success',
10
+ 'frg-checkbox__warning': styleType === 'warning',
11
+ 'frg-checkbox__danger': styleType === 'danger',
12
+ 'frg-checkbox__light': styleType === 'light',
13
+ 'frg-checkbox__dark': styleType === 'dark'
14
+ }"
15
+ >
16
+ <label class="frg-checkbox" [class.disabled]="disabled">
17
+ <input
18
+ type="checkbox"
19
+ [id]="id"
20
+ [checked]="value"
21
+ [disabled]="disabled"
22
+ (change)="onToggle($event)"
23
+ (blur)="onBlur()"
24
+ />
25
+ @if (label) {
26
+ <span class="frg-checkbox__label">{{ label | inputRequiredLabel: required }}</span>
27
+ }
28
+ </label>
29
+
30
+ @if(showValidation) {
31
+ <frg-input-validation
32
+ [errorList]="errorList"
33
+ [warningList]="warningList"
34
+ [isFormInvalid]="hasError"
35
+ ></frg-input-validation>
36
+ }
37
+ </div>
@@ -0,0 +1,128 @@
1
+ @use './../../../../../assets/styles/scss/variables' as *;
2
+
3
+ :host {
4
+ display: block;
5
+
6
+ @mixin checkbox-style($color) {
7
+ input[type="checkbox"]::after {
8
+ border-right-color: $color;
9
+ border-bottom-color: $color;
10
+ }
11
+
12
+ input[type="checkbox"]:checked {
13
+ border-color: $color;
14
+ }
15
+
16
+ input[type="checkbox"]:focus-visible {
17
+ box-shadow: 0 0 0 4px rgba($color, 0.14);
18
+ }
19
+ }
20
+
21
+ .frg-checkbox__wrapper {
22
+ display: flex;
23
+ flex-direction: column;
24
+ gap: 0.35rem;
25
+ }
26
+
27
+ .frg-checkbox__wrapper.frg-checkbox__primary {
28
+ @include checkbox-style($color-primary);
29
+ }
30
+
31
+ .frg-checkbox__wrapper.frg-checkbox__secondary {
32
+ @include checkbox-style($color-secondary);
33
+ }
34
+
35
+ .frg-checkbox__wrapper.frg-checkbox__tertiary {
36
+ @include checkbox-style($color-tertiary);
37
+ }
38
+
39
+ .frg-checkbox__wrapper.frg-checkbox__success {
40
+ @include checkbox-style($color-success);
41
+ }
42
+
43
+ .frg-checkbox__wrapper.frg-checkbox__warning {
44
+ @include checkbox-style($color-warning);
45
+ }
46
+
47
+ .frg-checkbox__wrapper.frg-checkbox__danger {
48
+ @include checkbox-style($color-danger);
49
+ }
50
+
51
+ .frg-checkbox__wrapper.frg-checkbox__light {
52
+ @include checkbox-style($color-light);
53
+ }
54
+
55
+ .frg-checkbox__wrapper.frg-checkbox__dark {
56
+ @include checkbox-style($color-dark);
57
+ }
58
+
59
+ .frg-checkbox {
60
+ display: inline-flex;
61
+ align-items: center;
62
+ gap: 0.5rem;
63
+ cursor: pointer;
64
+ font-size: $font-size-xs;
65
+ color: $input-text-color;
66
+ }
67
+
68
+ .input-error .frg-checkbox {
69
+ color: $color-danger;
70
+ }
71
+
72
+ .input-warning .frg-checkbox {
73
+ color: $color-warning;
74
+ }
75
+
76
+ input[type="checkbox"] {
77
+ appearance: none;
78
+ -webkit-appearance: none;
79
+ width: 1.1rem;
80
+ height: 1.1rem;
81
+ border-radius: 0.25rem;
82
+ background: transparent;
83
+ border: 1px solid $input-border-color;
84
+ display: inline-grid;
85
+ place-content: center;
86
+ transition: background 160ms ease, border-color 160ms ease, box-shadow 160ms ease;
87
+ cursor: pointer;
88
+ }
89
+
90
+ input[type="checkbox"]::after {
91
+ content: "";
92
+ width: 0.5rem;
93
+ height: 0.75rem;
94
+ border-right: 2px solid $color-primary;
95
+ border-bottom: 2px solid $color-primary;
96
+ transform: translateY(-1px) rotate(45deg) scale(0);
97
+ transform-origin: center;
98
+ transition: transform 140ms ease;
99
+ }
100
+
101
+ input[type="checkbox"]:checked {
102
+ background: transparent;
103
+ border-color: $color-primary;
104
+ }
105
+
106
+ input[type="checkbox"]:checked::after {
107
+ transform: translateY(-1px) rotate(45deg) scale(1);
108
+ }
109
+
110
+ input[type="checkbox"]:focus {
111
+ outline: none;
112
+ }
113
+
114
+ input[type="checkbox"]:focus-visible {
115
+ box-shadow: 0 0 0 4px rgba($color-primary, 0.14);
116
+ }
117
+
118
+ input[type="checkbox"]:disabled {
119
+ cursor: not-allowed;
120
+ opacity: 0.65;
121
+ background: transparent;
122
+ border-color: $input-disabled-border-color;
123
+ }
124
+
125
+ .frg-checkbox.disabled {
126
+ cursor: not-allowed;
127
+ }
128
+ }
@@ -0,0 +1,43 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+ import { By } from '@angular/platform-browser';
3
+ import { InputCheckboxComponent } from './input-checkbox.component';
4
+
5
+ describe('InputCheckboxComponent', () => {
6
+ let fixture: ComponentFixture<InputCheckboxComponent>;
7
+ let component: InputCheckboxComponent;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ imports: [InputCheckboxComponent]
12
+ }).compileComponents();
13
+
14
+ fixture = TestBed.createComponent(InputCheckboxComponent);
15
+ component = fixture.componentInstance;
16
+ });
17
+
18
+ it('toggles on change', () => {
19
+ component.value = false;
20
+
21
+ fixture.detectChanges();
22
+
23
+ const input = fixture.debugElement.query(By.css('input[type="checkbox"]'));
24
+ input.nativeElement.checked = true;
25
+ input.nativeElement.dispatchEvent(new Event('change'));
26
+ fixture.detectChanges();
27
+
28
+ expect(component.value).toBeTrue();
29
+ });
30
+
31
+ it('does not toggle when disabled', () => {
32
+ component.value = false;
33
+ component.disabled = true;
34
+
35
+ fixture.detectChanges();
36
+
37
+ const input = fixture.debugElement.query(By.css('input[type="checkbox"]'));
38
+ input.nativeElement.checked = true;
39
+ input.nativeElement.dispatchEvent(new Event('change'));
40
+
41
+ expect(component.value).toBeFalse();
42
+ });
43
+ });
@@ -0,0 +1,112 @@
1
+ import { NgClass } from '@angular/common';
2
+ import { Component, Input } from '@angular/core';
3
+ import { InputBase } from '../input-base';
4
+ import { DEFAULT_INPUT_CHECKBOX_ERROR_MESSAGES, DEFAULT_INPUT_CHECKBOX_WARNINGS_MESSAGES } from '../input-consts';
5
+ import { InputChoiceStyleType } from '../input-type';
6
+ import { InputValidationComponent } from '../input-validation/input-validation.component';
7
+ import { InputRequiredLabelPipe } from '../input.pipe';
8
+
9
+ @Component({
10
+ selector: 'frg-input-checkbox',
11
+ imports: [InputRequiredLabelPipe, InputValidationComponent, NgClass],
12
+ templateUrl: './input-checkbox.component.html',
13
+ styleUrl: './input-checkbox.component.scss',
14
+ })
15
+ export class InputCheckboxComponent extends InputBase<boolean> {
16
+ /**
17
+ * @inheritdoc
18
+ */
19
+ @Input() public override label: string = '';
20
+ /**
21
+ * @inheritdoc
22
+ */
23
+ @Input() public override required: boolean = false;
24
+ /**
25
+ * @inheritdoc
26
+ */
27
+ @Input() public override disabled: boolean = false;
28
+ /**
29
+ * @inheritdoc
30
+ */
31
+ @Input() public override errorMessages: Record<string, string> = {};
32
+ /**
33
+ * @inheritdoc
34
+ */
35
+ @Input() public override warningMessages: Record<string, string> = {};
36
+ /**
37
+ * @inheritdoc
38
+ */
39
+ @Input() public override showValidation: boolean = true;
40
+ /**
41
+ * Sets the visual style of the checkbox.
42
+ */
43
+ @Input() public styleType: InputChoiceStyleType = 'primary';
44
+
45
+ /**
46
+ * Toggles the checkbox value.
47
+ */
48
+ public onToggle(event: Event): void {
49
+ if (this.disabled) return;
50
+
51
+ const input = event.target as HTMLInputElement;
52
+ this.value = input.checked;
53
+ this.onChange(this.value);
54
+ this.onTouched();
55
+ }
56
+
57
+ /**
58
+ * @inheritdoc
59
+ */
60
+ public override onBlur(): void {
61
+ this.onTouched();
62
+ }
63
+
64
+ /**
65
+ * @inheritdoc
66
+ */
67
+ protected updateView(_value: boolean | null): void {
68
+ // Handled by Angular binding
69
+ }
70
+
71
+ /**
72
+ * @inheritdoc
73
+ */
74
+ protected updateDisabledState(_isDisabled: boolean): void {
75
+ // Handled by Angular binding
76
+ }
77
+
78
+ /**
79
+ * @inheritdoc
80
+ */
81
+ protected override get errorList(): string[] {
82
+ if (!this.control?.errors) return [];
83
+ const errors = this.control.errors;
84
+ return Object.keys(errors).map(key => {
85
+ if (this.errorMessages[key]) {
86
+ return this.errorMessages[key];
87
+ }
88
+ return DEFAULT_INPUT_CHECKBOX_ERROR_MESSAGES[key] || 'Invalid field.';
89
+ });
90
+ }
91
+
92
+ /**
93
+ * Returns warning messages. Consumers may pass arbitrary warnings via `warningMessages`.
94
+ * Falls back to DEFAULT_INPUT_CHECKBOX_WARNINGS_MESSAGES or a generic message.
95
+ */
96
+ protected override get warningList(): string[] {
97
+ return Object.keys(this.warningMessages).map(key => {
98
+ return (
99
+ this.warningMessages[key] ||
100
+ DEFAULT_INPUT_CHECKBOX_WARNINGS_MESSAGES[key] ||
101
+ ''
102
+ );
103
+ });
104
+ }
105
+
106
+ /**
107
+ * Returns whether any warnings are active.
108
+ */
109
+ protected get hasWarning(): boolean {
110
+ return this.warningList.length > 0;
111
+ }
112
+ }
@@ -0,0 +1,43 @@
1
+ <div
2
+ class="frg-checkbox-group__wrapper"
3
+ [class.input-error]="hasError"
4
+ [class.input-warning]="hasWarning"
5
+ [ngClass]="{
6
+ 'frg-checkbox-group__primary': styleType === 'primary',
7
+ 'frg-checkbox-group__secondary': styleType === 'secondary',
8
+ 'frg-checkbox-group__tertiary': styleType === 'tertiary',
9
+ 'frg-checkbox-group__success': styleType === 'success',
10
+ 'frg-checkbox-group__warning': styleType === 'warning',
11
+ 'frg-checkbox-group__danger': styleType === 'danger',
12
+ 'frg-checkbox-group__light': styleType === 'light',
13
+ 'frg-checkbox-group__dark': styleType === 'dark'
14
+ }"
15
+ >
16
+ @if(label){
17
+ <span class="frg-checkbox-group__label">{{ label | inputRequiredLabel: required }}</span>
18
+ }
19
+
20
+ <div class="frg-checkbox-group__list">
21
+ @for (item of items; track item.id) {
22
+ <label class="frg-checkbox" [class.disabled]="disabled || item.disabled">
23
+ <input
24
+ type="checkbox"
25
+ [id]="id + '-' + item.id"
26
+ [checked]="isSelected(item)"
27
+ [disabled]="disabled || item.disabled"
28
+ (change)="toggleItem(item, $event)"
29
+ (blur)="onBlur()"
30
+ />
31
+ <span class="frg-checkbox__label">{{ item.label }}</span>
32
+ </label>
33
+ }
34
+ </div>
35
+
36
+ @if(showValidation) {
37
+ <frg-input-validation
38
+ [errorList]="errorList"
39
+ [warningList]="warningList"
40
+ [isFormInvalid]="hasError"
41
+ ></frg-input-validation>
42
+ }
43
+ </div>