@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,140 @@
1
+ @use './../../../../../assets/styles/scss/variables' as *;
2
+
3
+ :host {
4
+ display: block;
5
+
6
+ @mixin checkbox-group-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-group__wrapper {
22
+ display: flex;
23
+ flex-direction: column;
24
+ gap: 0.5rem;
25
+ }
26
+
27
+ .frg-checkbox-group__wrapper.frg-checkbox-group__primary {
28
+ @include checkbox-group-style($color-primary);
29
+ }
30
+
31
+ .frg-checkbox-group__wrapper.frg-checkbox-group__secondary {
32
+ @include checkbox-group-style($color-secondary);
33
+ }
34
+
35
+ .frg-checkbox-group__wrapper.frg-checkbox-group__tertiary {
36
+ @include checkbox-group-style($color-tertiary);
37
+ }
38
+
39
+ .frg-checkbox-group__wrapper.frg-checkbox-group__success {
40
+ @include checkbox-group-style($color-success);
41
+ }
42
+
43
+ .frg-checkbox-group__wrapper.frg-checkbox-group__warning {
44
+ @include checkbox-group-style($color-warning);
45
+ }
46
+
47
+ .frg-checkbox-group__wrapper.frg-checkbox-group__danger {
48
+ @include checkbox-group-style($color-danger);
49
+ }
50
+
51
+ .frg-checkbox-group__wrapper.frg-checkbox-group__light {
52
+ @include checkbox-group-style($color-light);
53
+ }
54
+
55
+ .frg-checkbox-group__wrapper.frg-checkbox-group__dark {
56
+ @include checkbox-group-style($color-dark);
57
+ }
58
+
59
+ .frg-checkbox-group__label {
60
+ font-size: $font-size-xs;
61
+ color: $input-text-color;
62
+ }
63
+
64
+ .frg-checkbox-group__list {
65
+ display: grid;
66
+ gap: 0.5rem;
67
+ }
68
+
69
+ .frg-checkbox {
70
+ display: inline-flex;
71
+ align-items: center;
72
+ gap: 0.5rem;
73
+ cursor: pointer;
74
+ font-size: $font-size-xs;
75
+ color: $input-text-color;
76
+ }
77
+
78
+ .input-error .frg-checkbox-group__label,
79
+ .input-error .frg-checkbox {
80
+ color: $color-danger;
81
+ }
82
+
83
+ .input-warning .frg-checkbox-group__label,
84
+ .input-warning .frg-checkbox {
85
+ color: $color-warning;
86
+ }
87
+
88
+ input[type="checkbox"] {
89
+ appearance: none;
90
+ -webkit-appearance: none;
91
+ width: 1.1rem;
92
+ height: 1.1rem;
93
+ border-radius: 0.25rem;
94
+ background: transparent;
95
+ border: 1px solid $input-border-color;
96
+ display: inline-grid;
97
+ place-content: center;
98
+ transition: background 160ms ease, border-color 160ms ease, box-shadow 160ms ease;
99
+ cursor: pointer;
100
+ }
101
+
102
+ input[type="checkbox"]::after {
103
+ content: "";
104
+ width: 0.5rem;
105
+ height: 0.75rem;
106
+ border-right: 2px solid $color-primary;
107
+ border-bottom: 2px solid $color-primary;
108
+ transform: translateY(-1px) rotate(45deg) scale(0);
109
+ transform-origin: center;
110
+ transition: transform 140ms ease;
111
+ }
112
+
113
+ input[type="checkbox"]:checked {
114
+ background: transparent;
115
+ border-color: $color-primary;
116
+ }
117
+
118
+ input[type="checkbox"]:checked::after {
119
+ transform: translateY(-1px) rotate(45deg) scale(1);
120
+ }
121
+
122
+ input[type="checkbox"]:focus {
123
+ outline: none;
124
+ }
125
+
126
+ input[type="checkbox"]:focus-visible {
127
+ box-shadow: 0 0 0 4px rgba($color-primary, 0.14);
128
+ }
129
+
130
+ input[type="checkbox"]:disabled {
131
+ cursor: not-allowed;
132
+ opacity: 0.65;
133
+ background: transparent;
134
+ border-color: $input-disabled-border-color;
135
+ }
136
+
137
+ .frg-checkbox.disabled {
138
+ cursor: not-allowed;
139
+ }
140
+ }
@@ -0,0 +1,62 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+ import { By } from '@angular/platform-browser';
3
+ import { InputCheckboxGroupComponent, InputCheckboxGroupItem } from './input-checkbox-group.component';
4
+
5
+ describe('InputCheckboxGroupComponent', () => {
6
+ let fixture: ComponentFixture<InputCheckboxGroupComponent<string>>;
7
+ let component: InputCheckboxGroupComponent<string>;
8
+
9
+ const items: Array<InputCheckboxGroupItem<string>> = [
10
+ { id: 'a', label: 'Option A', value: 'a' },
11
+ { id: 'b', label: 'Option B', value: 'b' }
12
+ ];
13
+
14
+ beforeEach(async () => {
15
+ await TestBed.configureTestingModule({
16
+ imports: [InputCheckboxGroupComponent]
17
+ }).compileComponents();
18
+
19
+ fixture = TestBed.createComponent(InputCheckboxGroupComponent<string>);
20
+ component = fixture.componentInstance;
21
+ component.items = items;
22
+ });
23
+
24
+ it('adds a value when checked', () => {
25
+ component.value = [];
26
+
27
+ fixture.detectChanges();
28
+
29
+ const input = fixture.debugElement.query(By.css('input[type="checkbox"]'));
30
+ input.nativeElement.checked = true;
31
+ input.nativeElement.dispatchEvent(new Event('change'));
32
+ fixture.detectChanges();
33
+
34
+ expect(component.value).toEqual(['a']);
35
+ });
36
+
37
+ it('removes a value when unchecked', () => {
38
+ component.value = ['a'];
39
+
40
+ fixture.detectChanges();
41
+
42
+ const input = fixture.debugElement.query(By.css('input[type="checkbox"]'));
43
+ input.nativeElement.checked = false;
44
+ input.nativeElement.dispatchEvent(new Event('change'));
45
+ fixture.detectChanges();
46
+
47
+ expect(component.value).toEqual([]);
48
+ });
49
+
50
+ it('does not toggle when disabled', () => {
51
+ component.value = [];
52
+ component.disabled = true;
53
+
54
+ fixture.detectChanges();
55
+
56
+ const input = fixture.debugElement.query(By.css('input[type="checkbox"]'));
57
+ input.nativeElement.checked = true;
58
+ input.nativeElement.dispatchEvent(new Event('change'));
59
+
60
+ expect(component.value).toEqual([]);
61
+ });
62
+ });
@@ -0,0 +1,136 @@
1
+ import { Component, Input } from '@angular/core';
2
+ import { InputBase } from '../input-base';
3
+ import { DEFAULT_INPUT_CHECKBOX_GROUP_ERROR_MESSAGES, DEFAULT_INPUT_CHECKBOX_GROUP_WARNINGS_MESSAGES } from '../input-consts';
4
+ import { InputChoiceStyleType } from '../input-type';
5
+ import { InputValidationComponent } from '../input-validation/input-validation.component';
6
+ import { InputRequiredLabelPipe } from '../input.pipe';
7
+ import { NgClass } from '@angular/common';
8
+
9
+ export interface InputCheckboxGroupItem<T> {
10
+ id: string;
11
+ label: string;
12
+ value: T;
13
+ disabled?: boolean;
14
+ }
15
+
16
+ @Component({
17
+ selector: 'frg-input-checkbox-group',
18
+ imports: [NgClass, InputRequiredLabelPipe, InputValidationComponent],
19
+ templateUrl: './input-checkbox-group.component.html',
20
+ styleUrl: './input-checkbox-group.component.scss',
21
+ })
22
+ export class InputCheckboxGroupComponent<T> extends InputBase<Array<T>> {
23
+ /**
24
+ * @inheritdoc
25
+ */
26
+ @Input() public override label: string = '';
27
+ /**
28
+ * @inheritdoc
29
+ */
30
+ @Input() public override required: boolean = false;
31
+ /**
32
+ * @inheritdoc
33
+ */
34
+ @Input() public override disabled: boolean = false;
35
+ /**
36
+ * @inheritdoc
37
+ */
38
+ @Input() public override errorMessages: Record<string, string> = {};
39
+ /**
40
+ * @inheritdoc
41
+ */
42
+ @Input() public override warningMessages: Record<string, string> = {};
43
+ /**
44
+ * @inheritdoc
45
+ */
46
+ @Input() public override showValidation: boolean = true;
47
+ /**
48
+ * Sets the visual style of the checkbox group.
49
+ */
50
+ @Input() public styleType: InputChoiceStyleType = 'primary';
51
+
52
+ @Input() public items: Array<InputCheckboxGroupItem<T>> = [];
53
+ @Input() public compareWith: (a: T, b: T) => boolean = (a, b) => a === b;
54
+
55
+ /**
56
+ * Toggles a checkbox item value.
57
+ */
58
+ public toggleItem(item: InputCheckboxGroupItem<T>, event: Event): void {
59
+ if (this.disabled || item.disabled) return;
60
+
61
+ const input = event.target as HTMLInputElement;
62
+ const current = this.value ? [...this.value] : [];
63
+ const isSelected = current.some(value => this.compareWith(value, item.value));
64
+
65
+ const next = input.checked
66
+ ? (isSelected ? current : [...current, item.value])
67
+ : current.filter(value => !this.compareWith(value, item.value));
68
+
69
+ this.value = next;
70
+ this.onChange(this.value);
71
+ this.onTouched();
72
+ }
73
+
74
+ /**
75
+ * Checks if the item is selected.
76
+ */
77
+ public isSelected(item: InputCheckboxGroupItem<T>): boolean {
78
+ return (this.value ?? []).some(value => this.compareWith(value, item.value));
79
+ }
80
+
81
+ /**
82
+ * @inheritdoc
83
+ */
84
+ public override onBlur(): void {
85
+ this.onTouched();
86
+ }
87
+
88
+ /**
89
+ * @inheritdoc
90
+ */
91
+ protected updateView(_value: Array<T> | null): void {
92
+ // Handled by Angular binding
93
+ }
94
+
95
+ /**
96
+ * @inheritdoc
97
+ */
98
+ protected updateDisabledState(_isDisabled: boolean): void {
99
+ // Handled by Angular binding
100
+ }
101
+
102
+ /**
103
+ * @inheritdoc
104
+ */
105
+ protected override get errorList(): string[] {
106
+ if (!this.control?.errors) return [];
107
+ const errors = this.control.errors;
108
+ return Object.keys(errors).map(key => {
109
+ if (this.errorMessages[key]) {
110
+ return this.errorMessages[key];
111
+ }
112
+ return DEFAULT_INPUT_CHECKBOX_GROUP_ERROR_MESSAGES[key] || 'Invalid field.';
113
+ });
114
+ }
115
+
116
+ /**
117
+ * Returns warning messages. Consumers may pass arbitrary warnings via `warningMessages`.
118
+ * Falls back to DEFAULT_INPUT_CHECKBOX_GROUP_WARNINGS_MESSAGES or a generic message.
119
+ */
120
+ protected override get warningList(): string[] {
121
+ return Object.keys(this.warningMessages).map(key => {
122
+ return (
123
+ this.warningMessages[key] ||
124
+ DEFAULT_INPUT_CHECKBOX_GROUP_WARNINGS_MESSAGES[key] ||
125
+ ''
126
+ );
127
+ });
128
+ }
129
+
130
+ /**
131
+ * Returns whether any warnings are active.
132
+ */
133
+ protected get hasWarning(): boolean {
134
+ return this.warningList.length > 0;
135
+ }
136
+ }
@@ -0,0 +1,81 @@
1
+ <div class="clock-mode-toggle">
2
+ <button
3
+ type="button"
4
+ class="clock-mode-toggle__btn"
5
+ [class.is-active]="showHoursPicker$ | async"
6
+ (click)="showHours()">
7
+ Hours
8
+ </button>
9
+ <button
10
+ type="button"
11
+ class="clock-mode-toggle__btn"
12
+ [class.is-active]="showMinutesPicker$ | async"
13
+ (click)="showMinutes()">
14
+ Minutes
15
+ </button>
16
+ </div>
17
+
18
+ <div class="clock-picker">
19
+ <div class="clock-face">
20
+ @if(showHoursPicker$ | async){
21
+ @for(hour of clockHours; track hour){
22
+ <button
23
+ class="clock-hour"
24
+ [class.is-selected]="hour === selectedHour"
25
+ (mouseenter)="onHourHover(hour)"
26
+ (mouseleave)="onHourLeave()"
27
+ (click)="onHourClick($event, hour)">
28
+ {{hour}}
29
+ </button>
30
+ }
31
+ @if(!isMeridiemFormat){
32
+ @for(hour of fullClockHours; track hour){
33
+ <button
34
+ class="clock-hour"
35
+ [class.is-selected]="hour === selectedHour"
36
+ (mouseenter)="onHourHover(hour)"
37
+ (mouseleave)="onHourLeave()"
38
+ (click)="onHourClick($event, hour)">
39
+ {{hour}}
40
+ </button>
41
+ }
42
+ }
43
+ }
44
+
45
+ @if(showMinutesPicker$ | async){
46
+ @for(minute of clockMinutes; track minute){
47
+ <button
48
+ class="clock-minute"
49
+ [class.is-selected]="minute === selectedMinute"
50
+ (mouseenter)="onMinuteHover(minute)"
51
+ (mouseleave)="onMinuteLeave()"
52
+ (click)="onMinuteClick($event, minute)">
53
+ {{minute}}
54
+ </button>
55
+ }
56
+ }
57
+
58
+ <div class="clock-hand clock-hand--minutes" [class.clock-hand--opacity]="showHoursPicker$ | async" #handMinutes></div>
59
+ <div class="clock-hand clock-hand--hours" #handHours></div>
60
+ </div>
61
+ </div>
62
+
63
+ @if(isMeridiemFormat){
64
+ <div class="clock-footer">
65
+ <div class="clock-picker__meridiem">
66
+ <input
67
+ [id]="'meridiem'"
68
+ [attr.data-partialTime]="'meridiem'"
69
+ type="checkbox"
70
+ tabindex="0"
71
+ role="switch"
72
+ [checked]="selectedMeridiem === 'PM'"
73
+ aria-checked="{{ selectedMeridiem === 'PM' }}"
74
+ placeholder="AM/PM"
75
+ (change)="onMeridiemChange($event)"
76
+ (keydown.enter)="onMeridiemChange($event)"
77
+ />
78
+ </div>
79
+ <span class="focus-line"></span>
80
+ </div>
81
+ }
@@ -0,0 +1,228 @@
1
+ @use "sass:color";
2
+ @use './../../../../../assets/styles/scss/variables' as *;
3
+
4
+ :host {
5
+ display: block;
6
+ position: relative;
7
+
8
+ .clock-picker {
9
+ display: flex;
10
+ flex-direction: column;
11
+ align-items: center;
12
+ font-family: $input-font-family;
13
+ margin: 0.5rem;
14
+ padding: 0.5rem;
15
+ background: $color-primary-light;
16
+ border-radius: 200px;
17
+ box-shadow: $box-shadow-md;
18
+
19
+ .clock-face {
20
+ position: relative;
21
+ width: 15rem;
22
+ height: 15rem;
23
+ border-radius: 50%;
24
+ background: $input-background;
25
+
26
+ /* ------------------- HOURS ------------------- */
27
+ .clock-hour {
28
+ position: absolute;
29
+ width: 30px;
30
+ height: 30px;
31
+ text-align: center;
32
+ padding: 0;
33
+ top: 50%;
34
+ left: 50%;
35
+ margin: -15px;
36
+ color: $input-text-color;
37
+ font-size: $font-size-md;
38
+ border-radius: 50px;
39
+ border: 0.1rem solid transparent;
40
+ background: transparent;
41
+ cursor: pointer;
42
+ transition: all 0.2s ease-in-out;
43
+
44
+ &.is-selected {
45
+ border: 0.15rem solid $color-primary;
46
+ color: $color-light;
47
+ background-color: $color-primary;
48
+ }
49
+
50
+ &:hover {
51
+ border: 0.15rem solid $color-primary;
52
+ }
53
+
54
+ @for $i from 1 through 12 {
55
+ $angle: ($i - 1) * 30deg - 90deg;
56
+ &:nth-child(#{$i}) {
57
+ transform: rotate($angle) translate(6.25rem) rotate(-$angle);
58
+ }
59
+ }
60
+
61
+ @for $i from 13 through 24 {
62
+ $angle: ($i - 13) * 30deg - 90deg;
63
+ &:nth-child(#{$i}) {
64
+ transform: rotate($angle) translate(3.75rem) rotate(-$angle);
65
+ }
66
+ }
67
+ }
68
+
69
+ /* ------------------- MINUTES ------------------- */
70
+ .clock-minute {
71
+ position: absolute;
72
+ width: 30px;
73
+ height: 30px;
74
+ text-align: center;
75
+ padding: 0;
76
+ top: 50%;
77
+ left: 50%;
78
+ margin: -15px;
79
+ color: $input-text-color;
80
+ font-size: $font-size-md;
81
+ border-radius: 50px;
82
+ border: 0.1rem solid transparent;
83
+ background: transparent;
84
+ cursor: pointer;
85
+ transition: all 0.2s ease-in-out;
86
+
87
+ &.is-selected {
88
+ border: 0.15rem solid $color-primary;
89
+ color: $color-light;
90
+ background-color: $color-primary;
91
+ }
92
+
93
+ &:hover {
94
+ border: 0.15rem solid $color-primary;
95
+ }
96
+
97
+ @for $i from 0 through 11 {
98
+ $angle: ($i * 5 * 6deg) - 90deg;
99
+ &:nth-child(#{$i + 1}) {
100
+ transform: rotate($angle) translate(6.25rem) rotate(-$angle);
101
+ }
102
+ }
103
+ }
104
+
105
+ /* ------------------- CENTER PIN ------------------- */
106
+ &::after {
107
+ content: '';
108
+ position: absolute;
109
+ top: 50%;
110
+ left: 50%;
111
+ border-radius: 2px;
112
+ transform: translate(-50%, -50%);
113
+ padding: 0.3rem;
114
+ background-color: $color-primary-dark;
115
+ }
116
+ }
117
+
118
+ /* ------------------- CLOCK HANDS ------------------- */
119
+ .clock-hand {
120
+ position: absolute;
121
+ height: 0.25rem;
122
+ top: 50%;
123
+ left: 50%;
124
+ transform-origin: 0 50%;
125
+ transition: transform 0.25s ease-in-out, opacity 0.25s ease-in-out;
126
+ transform: translateY(-50%) rotate(var(--angle, -90deg));
127
+
128
+ &--hours {
129
+ width: 15%;
130
+ background: $color-primary;
131
+ }
132
+
133
+ &--minutes {
134
+ width: 25%;
135
+ background: $color-primary-dark;
136
+ }
137
+
138
+ &--opacity {
139
+ opacity: 0.3;
140
+ }
141
+ }
142
+
143
+ }
144
+
145
+ .clock-mode-toggle {
146
+ display: inline-flex;
147
+ gap: 0.5rem;
148
+ margin-bottom: 0.5rem;
149
+ justify-content: center;
150
+ width: 100%;
151
+
152
+ &__btn {
153
+ border: 1px solid $input-border-color;
154
+ background: $color-light;
155
+ color: $input-text-color;
156
+ border-radius: 0.25rem;
157
+ padding: 0.2rem 0.6rem;
158
+ cursor: pointer;
159
+ font-size: $font-size-xs;
160
+
161
+ &.is-active {
162
+ background: $color-primary;
163
+ border-color: $color-primary;
164
+ color: $color-light;
165
+ }
166
+ }
167
+ }
168
+
169
+ /* ------------------- FOOTER ------------------- */
170
+ .clock-footer {
171
+ display: flex;
172
+ justify-content: center;
173
+ width: 100%;
174
+ }
175
+
176
+ /* ------------------- MERIDIEM SWITCH ------------------- */
177
+ .clock-picker__meridiem {
178
+ width: 3.5rem;
179
+ height: 1.5rem;
180
+ margin-top: 0.5rem;
181
+
182
+ input[type="checkbox"] {
183
+ appearance: none;
184
+ width: 100%;
185
+ height: 100%;
186
+ border-radius: 0.25rem;
187
+ background-color: $color-light-soft;
188
+ cursor: pointer;
189
+ position: relative;
190
+ overflow: hidden;
191
+ transition: background-color 0.25s ease;
192
+
193
+ &:before,
194
+ &:after {
195
+ content: "AM";
196
+ position: absolute;
197
+ top: 50%;
198
+ left: 50%;
199
+ transform: translate(-50%, -50%);
200
+ font-size: $font-size-md;
201
+ font-weight: 600;
202
+ color: $color-dark-neutral;
203
+ transition: transform 0.25s ease, opacity 0.25s ease;
204
+ }
205
+
206
+ &:after {
207
+ content: "PM";
208
+ opacity: 0;
209
+ transform: translate(-50%, 150%);
210
+ color: $color-light;
211
+ }
212
+
213
+ &:checked {
214
+ background-color: $color-primary;
215
+
216
+ &:before {
217
+ transform: translate(-50%, -150%);
218
+ opacity: 0;
219
+ }
220
+
221
+ &:after {
222
+ transform: translate(-50%, -50%);
223
+ opacity: 1;
224
+ }
225
+ }
226
+ }
227
+ }
228
+ }
@@ -0,0 +1,62 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+ import { By } from '@angular/platform-browser';
3
+ import { InputClockPickerComponent } from './input-clock-picker.component';
4
+
5
+ describe('InputClockPickerComponent', () => {
6
+ let fixture: ComponentFixture<InputClockPickerComponent>;
7
+ let component: InputClockPickerComponent;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ imports: [InputClockPickerComponent]
12
+ }).compileComponents();
13
+
14
+ fixture = TestBed.createComponent(InputClockPickerComponent);
15
+ component = fixture.componentInstance;
16
+ });
17
+
18
+ it('emits hour selection and switches to minutes', () => {
19
+ const emitSpy = spyOn(component.selectHour, 'emit');
20
+
21
+ fixture.detectChanges();
22
+
23
+ const hourButtons = fixture.debugElement.queryAll(By.css('.clock-hour'));
24
+ hourButtons[0].nativeElement.click();
25
+ fixture.detectChanges();
26
+
27
+ expect(emitSpy).toHaveBeenCalled();
28
+ expect(component.showHoursPicker$.value).toBeFalse();
29
+ expect(component.showMinutesPicker$.value).toBeTrue();
30
+ });
31
+
32
+ it('emits minute selection and closes picker', () => {
33
+ const emitSpy = spyOn(component.closePicker, 'emit');
34
+
35
+ fixture.detectChanges();
36
+
37
+ const hourButtons = fixture.debugElement.queryAll(By.css('.clock-hour'));
38
+ hourButtons[0].nativeElement.click();
39
+ fixture.detectChanges();
40
+
41
+ const minuteButtons = fixture.debugElement.queryAll(By.css('.clock-minute'));
42
+ minuteButtons[0].nativeElement.click();
43
+ fixture.detectChanges();
44
+
45
+ expect(component.showMinutesPicker$.value).toBeTrue();
46
+ expect(emitSpy).toHaveBeenCalled();
47
+ });
48
+
49
+ it('toggles meridiem when format is 12h', () => {
50
+ component.timeFormat = 'hh:mm a';
51
+ const emitSpy = spyOn(component.selectMeridiem, 'emit');
52
+
53
+ fixture.detectChanges();
54
+
55
+ const meridiemInput = fixture.debugElement.query(By.css('input[role="switch"]')).nativeElement as HTMLInputElement;
56
+ meridiemInput.checked = true;
57
+ meridiemInput.dispatchEvent(new Event('change'));
58
+
59
+ expect(component.selectedMeridiem).toBe('PM');
60
+ expect(emitSpy).toHaveBeenCalledWith('PM');
61
+ });
62
+ });