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

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 +1 -1
  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,202 @@
1
+ @use './../../../../../assets/styles/scss/variables' as *;
2
+
3
+ :host {
4
+ display: block;
5
+
6
+ .frg-pulse-loader {
7
+ position: relative;
8
+ display: inline-flex;
9
+ flex-direction: column;
10
+ align-items: center;
11
+ justify-content: center;
12
+ width: $frg-loader-size-md;
13
+ color: $frg-loader-color-primary;
14
+ isolation: isolate;
15
+ overflow: visible;
16
+
17
+ &__core {
18
+ position: relative;
19
+ width: 35%;
20
+ aspect-ratio: 1;
21
+ background-color: currentColor;
22
+ border-radius: 50%;
23
+ z-index: 2;
24
+ box-shadow: 0 0 8px currentColor;
25
+
26
+ &::before,
27
+ &::after {
28
+ content: '';
29
+ position: absolute;
30
+ inset: 0;
31
+ border-radius: 50%;
32
+ background-color: currentColor;
33
+ opacity: 0.5;
34
+ z-index: -1;
35
+ filter: blur(0.5px);
36
+ transform: scale(1);
37
+ transform-origin: center;
38
+ animation: frg-dual-pulse 1.4s cubic-bezier(0.4, 0, 0.3, 1) infinite;
39
+ }
40
+
41
+ &::after {
42
+ animation-delay: 0.7s;
43
+ }
44
+ }
45
+
46
+ &__percent {
47
+ margin-top: 0.6rem;
48
+ font-weight: 600;
49
+ color: currentColor;
50
+ z-index: 3;
51
+ text-align: center;
52
+ pointer-events: none;
53
+ user-select: none;
54
+ opacity: 0.95;
55
+ transition: opacity 0.3s ease;
56
+ text-shadow: 0 0 3px rgba(0, 0, 0, 0.25);
57
+ }
58
+
59
+ &--small {
60
+ width: $frg-loader-size-sm;
61
+
62
+ .frg-pulse-loader__core {
63
+ width: 45%;
64
+
65
+ &::before,
66
+ &::after {
67
+ animation-duration: 1.2s;
68
+ }
69
+ }
70
+
71
+ .frg-pulse-loader__percent {
72
+ font-size: $font-size-sm;
73
+ margin-top: 1rem;
74
+ }
75
+ }
76
+
77
+ &--medium {
78
+ width: calc($frg-loader-size-md * 1.25);
79
+
80
+ .frg-pulse-loader__core {
81
+ width: 35%;
82
+ }
83
+
84
+ .frg-pulse-loader__percent {
85
+ font-size: $font-size-md;
86
+ margin-top: 1.5rem;
87
+ }
88
+ }
89
+
90
+ &--large {
91
+ width: calc($frg-loader-size-lg * 1.5);
92
+
93
+ .frg-pulse-loader__core {
94
+ width: 30%;
95
+ box-shadow: 0 0 14px currentColor;
96
+
97
+ &::before,
98
+ &::after {
99
+ animation-duration: 1.6s;
100
+ }
101
+ }
102
+
103
+ .frg-pulse-loader__percent {
104
+ font-size: $font-size-lg;
105
+ margin-top: 2rem;
106
+ }
107
+ }
108
+
109
+ &--primary { color: $frg-loader-color-primary; }
110
+ &--secondary { color: $frg-loader-color-secondary; }
111
+ &--tertiary { color: $frg-loader-color-tertiary; }
112
+
113
+ &--secondary,
114
+ &--tertiary {
115
+ .frg-pulse-loader__percent {
116
+ text-shadow: 0 0 2px rgba(255, 255, 255, 0.5);
117
+ opacity: 1;
118
+ }
119
+ }
120
+
121
+ &--light {
122
+ color: $frg-loader-color-light;
123
+
124
+ .frg-pulse-loader__percent {
125
+ text-shadow: 0 0 3px rgba(0, 0, 0, 0.4);
126
+ }
127
+ }
128
+
129
+ &--dark {
130
+ color: $frg-loader-color-dark;
131
+
132
+ .frg-pulse-loader__percent {
133
+ text-shadow: 0 0 3px rgba(255, 255, 255, 0.25);
134
+ }
135
+ }
136
+
137
+ &--overlay {
138
+ position: fixed;
139
+ top: 0;
140
+ left: 0;
141
+ width: 100vw;
142
+ height: 100vh;
143
+ display: flex;
144
+ align-items: center;
145
+ justify-content: center;
146
+ background: rgba($color-light-neutral, 0.6);
147
+ z-index: 9999;
148
+ backdrop-filter: blur(0.2rem);
149
+
150
+ &.frg-pulse-loader--small .frg-pulse-loader__core {
151
+ width: $frg-loader-size-sm;
152
+ }
153
+
154
+ &.frg-pulse-loader--medium .frg-pulse-loader__core {
155
+ width: $frg-loader-size-md;
156
+ }
157
+
158
+ &.frg-pulse-loader--large .frg-pulse-loader__core {
159
+ width: $frg-loader-size-lg;
160
+ }
161
+
162
+ &.frg-pulse-loader--small .frg-pulse-loader__percent {
163
+ margin-top: calc($frg-loader-size-sm * 1.25);
164
+ }
165
+
166
+ &.frg-pulse-loader--medium .frg-pulse-loader__percent {
167
+ margin-top: calc($frg-loader-size-md * 1.25);
168
+ }
169
+
170
+ &.frg-pulse-loader--large .frg-pulse-loader__percent {
171
+ margin-top: calc($frg-loader-size-lg * 1.25);
172
+ }
173
+ }
174
+
175
+ &--overlay-item {
176
+ position: absolute;
177
+ inset: 0;
178
+ display: flex;
179
+ align-items: center;
180
+ justify-content: center;
181
+ z-index: 1;
182
+ }
183
+ }
184
+
185
+ @keyframes frg-dual-pulse {
186
+ 0% {
187
+ transform: scale(1);
188
+ opacity: 0.5;
189
+ filter: blur(0);
190
+ }
191
+ 60% {
192
+ transform: scale(3);
193
+ opacity: 0.25;
194
+ filter: blur(0.5px);
195
+ }
196
+ 100% {
197
+ transform: scale(4);
198
+ opacity: 0;
199
+ filter: blur(1px);
200
+ }
201
+ }
202
+ }
@@ -0,0 +1,55 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+ import { SimpleChange } from '@angular/core';
3
+ import { By } from '@angular/platform-browser';
4
+ import { PulseLoaderComponent } from './pulse-loader.component';
5
+
6
+ describe('PulseLoaderComponent', () => {
7
+ let fixture: ComponentFixture<PulseLoaderComponent>;
8
+ let component: PulseLoaderComponent;
9
+
10
+ beforeEach(async () => {
11
+ await TestBed.configureTestingModule({
12
+ imports: [PulseLoaderComponent]
13
+ }).compileComponents();
14
+
15
+ fixture = TestBed.createComponent(PulseLoaderComponent);
16
+ component = fixture.componentInstance;
17
+ });
18
+
19
+ afterEach(() => {
20
+ document.body.style.overflow = '';
21
+ });
22
+
23
+ it('renders percentage when enabled', () => {
24
+ component.showPercentage = true;
25
+ component.progress = 42;
26
+
27
+ fixture.detectChanges();
28
+
29
+ const label = fixture.debugElement.query(By.css('.frg-pulse-loader__percent'));
30
+ expect(label.nativeElement.textContent).toContain('42%');
31
+ });
32
+
33
+ it('applies size and style classes', () => {
34
+ component.size = 'large';
35
+ component.styleType = 'secondary';
36
+
37
+ fixture.detectChanges();
38
+
39
+ const output = fixture.debugElement.query(By.css('output'));
40
+ expect(output.nativeElement.classList).toContain('frg-pulse-loader--large');
41
+ expect(output.nativeElement.classList).toContain('frg-pulse-loader--secondary');
42
+ });
43
+
44
+ it('toggles body scroll when overlay changes', () => {
45
+ component.isOverlay = true;
46
+ component.ngOnChanges({
47
+ isOverlay: new SimpleChange(false, true, false)
48
+ });
49
+
50
+ expect(document.body.style.overflow).toBe('hidden');
51
+
52
+ component.ngOnDestroy();
53
+ expect(document.body.style.overflow).toBe('');
54
+ });
55
+ });
@@ -0,0 +1,73 @@
1
+ import { NgClass } from '@angular/common';
2
+ import { Component, Input, OnChanges, OnDestroy, SimpleChanges } from '@angular/core';
3
+ import { TPulseLoaderSize, TPulseLoaderType } from './pulse-loader.type';
4
+
5
+ /**
6
+ * Component representing a pulse loader with customizable size, style, and progress display.
7
+ * Usage example:
8
+ * ```html
9
+ * <frg-pulse-loader [progress]="progressValue" [styleType]="'primary'" [size]="'medium'" [showPercentage]="true"></frg-pulse-loader>
10
+ * ```
11
+ */
12
+ @Component({
13
+ selector: 'frg-pulse-loader',
14
+ standalone: true,
15
+ imports: [NgClass],
16
+ templateUrl: './pulse-loader.component.html',
17
+ styleUrls: ['./pulse-loader.component.scss'],
18
+ })
19
+ export class PulseLoaderComponent implements OnChanges, OnDestroy {
20
+ /**
21
+ * ARIA label for accessibility purposes.
22
+ * Default is 'Loading...'.
23
+ */
24
+ @Input() ariaLabel: string = 'Loading...';
25
+ @Input() isOverlay = false;
26
+ @Input() isOverlayItem = false;
27
+ /**
28
+ * The current progress value (0-100) to be displayed by the loader.
29
+ */
30
+ @Input() progress: number = 0;
31
+ /**
32
+ * The style type of the loader, affecting its color scheme.
33
+ * Options: 'primary', 'secondary', 'tertiary', 'success', 'warning', 'danger', 'info', 'light', 'dark'
34
+ */
35
+ @Input() styleType: TPulseLoaderType = 'primary';
36
+ /**
37
+ * The size of the loader.
38
+ * Options: 'small', 'medium', 'large'
39
+ */
40
+ @Input() size: TPulseLoaderSize = 'medium';
41
+ /**
42
+ * Whether to display the percentage text inside the loader.
43
+ * Default is false.
44
+ */
45
+ @Input() showPercentage: boolean = false;
46
+
47
+ /**
48
+ * Gets the CSS classes for the loader based on its size and style type.
49
+ */
50
+ public get classes() {
51
+ return {
52
+ 'frg-pulse-loader': true,
53
+ [`frg-pulse-loader--${this.size}`]: true,
54
+ [`frg-pulse-loader--${this.styleType}`]: true,
55
+ 'frg-pulse-loader--overlay': this.isOverlay,
56
+ 'frg-pulse-loader--overlay-item': this.isOverlayItem,
57
+ };
58
+ }
59
+
60
+ ngOnChanges(changes: SimpleChanges): void {
61
+ if (changes['isOverlay']) {
62
+ this.toggleBodyScroll(this.isOverlay);
63
+ }
64
+ }
65
+
66
+ ngOnDestroy(): void {
67
+ this.toggleBodyScroll(false);
68
+ }
69
+
70
+ private toggleBodyScroll(disable: boolean): void {
71
+ document.body.style.overflow = disable ? 'hidden' : '';
72
+ }
73
+ }
@@ -0,0 +1,6 @@
1
+ import { TBaseSize } from "../../../types/base.types";
2
+ import { TBaseLoaderStyle } from "../loader.type";
3
+
4
+ export type TPulseLoaderSize = TBaseSize;
5
+
6
+ export type TPulseLoaderType = TBaseLoaderStyle;
@@ -0,0 +1,13 @@
1
+ <div
2
+ class="skeleton-root"
3
+ [style.width]="isCircle ? size : width"
4
+ [style.height]="isCircle ? size : (isMultiRow ? null : height)"
5
+ >
6
+ @if (rows <= 1) {
7
+ <div class="skeleton-block" [style.height]="height"></div>
8
+ } @else {
9
+ @for (_ of rowArray; let i = $index; track i) {
10
+ <div class="skeleton-block" [style.height]="height"></div>
11
+ }
12
+ }
13
+ </div>
@@ -0,0 +1,113 @@
1
+ @use './../../../../../assets/styles/scss/variables' as *;
2
+
3
+ :host {
4
+ display: inline-block;
5
+
6
+ .skeleton-root {
7
+ display: flex;
8
+ flex-direction: column;
9
+ gap: 0.5rem;
10
+ width: 100%;
11
+ }
12
+
13
+ .skeleton-block {
14
+ width: 100%;
15
+ height: 1rem;
16
+ border-radius: 6px;
17
+ background: linear-gradient(
18
+ 90deg,
19
+ #e0e0e0 0%,
20
+ #f5f5f5 50%,
21
+ #e0e0e0 100%
22
+ );
23
+ background-size: 200% 100%;
24
+ }
25
+
26
+ &.circle {
27
+ .skeleton-root {
28
+ width: auto;
29
+ height: auto;
30
+ }
31
+
32
+ .skeleton-block {
33
+ border-radius: 50%;
34
+ width: 100%;
35
+ height: 100%;
36
+ aspect-ratio: 1 / 1;
37
+ }
38
+ }
39
+
40
+ &.animated .skeleton-block {
41
+ animation: shimmer 1.4s linear infinite;
42
+ }
43
+
44
+ &.skeleton--primary .skeleton-block {
45
+ background: linear-gradient(
46
+ 90deg,
47
+ $color-primary-dark 0%,
48
+ $color-primary-light 50%,
49
+ $color-primary-dark 100%
50
+ );
51
+ background-size: 200% 100%;
52
+ background-position: 0 0;
53
+ }
54
+
55
+ &.skeleton--secondary .skeleton-block {
56
+ background: linear-gradient(
57
+ 90deg,
58
+ $color-secondary-dark 0%,
59
+ $color-secondary-light 50%,
60
+ $color-secondary-dark 100%
61
+ );
62
+ background-size: 200% 100%;
63
+ background-position: 0 0;
64
+ }
65
+
66
+ &.skeleton--tertiary .skeleton-block {
67
+ background: linear-gradient(
68
+ 90deg,
69
+ $color-tertiary-dark 0%,
70
+ $color-tertiary-light 50%,
71
+ $color-tertiary-dark 100%
72
+ );
73
+ background-size: 200% 100%;
74
+ background-position: 0 0;
75
+ }
76
+
77
+ &.skeleton--dark .skeleton-block {
78
+ background: linear-gradient(
79
+ 90deg,
80
+ $color-dark-neutral 0%,
81
+ $color-dark 50%,
82
+ $color-dark-neutral 100%
83
+ );
84
+ background-size: 200% 100%;
85
+ background-position: 0 0;
86
+ }
87
+
88
+ &.skeleton--light .skeleton-block {
89
+ background: linear-gradient(
90
+ 90deg,
91
+ $color-light-soft 0%,
92
+ $color-light 50%,
93
+ $color-light-soft 100%
94
+ );
95
+ background-size: 200% 100%;
96
+ background-position: 0 0;
97
+ }
98
+
99
+ @keyframes shimmer {
100
+ 0% {
101
+ background-position: -200% 0;
102
+ }
103
+ 100% {
104
+ background-position: 200% 0;
105
+ }
106
+ }
107
+
108
+ @media (prefers-reduced-motion: reduce) {
109
+ &.animated .skeleton-block {
110
+ animation: none;
111
+ }
112
+ }
113
+ }
@@ -0,0 +1,37 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+ import { By } from '@angular/platform-browser';
3
+ import { SkeletonLoaderComponent } from './skeleton-loader.component';
4
+
5
+ describe('SkeletonLoaderComponent', () => {
6
+ let fixture: ComponentFixture<SkeletonLoaderComponent>;
7
+ let component: SkeletonLoaderComponent;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ imports: [SkeletonLoaderComponent]
12
+ }).compileComponents();
13
+
14
+ fixture = TestBed.createComponent(SkeletonLoaderComponent);
15
+ component = fixture.componentInstance;
16
+ });
17
+
18
+ it('renders the requested number of rows', () => {
19
+ component.rows = 3;
20
+
21
+ fixture.detectChanges();
22
+
23
+ const blocks = fixture.debugElement.queryAll(By.css('.skeleton-block'));
24
+ expect(blocks.length).toBe(3);
25
+ });
26
+
27
+ it('applies circle class when shape is circle', () => {
28
+ component.shape = 'circle';
29
+ component.animated = false;
30
+
31
+ fixture.detectChanges();
32
+
33
+ const host = fixture.debugElement.nativeElement as HTMLElement;
34
+ expect(host.classList).toContain('circle');
35
+ expect(host.classList).not.toContain('animated');
36
+ });
37
+ });
@@ -0,0 +1,51 @@
1
+ import { Component, HostBinding, Input } from '@angular/core';
2
+ import { TSkeletonLoaderType } from './skeleton-loader.type';
3
+
4
+ @Component({
5
+ selector: 'frg-skeleton-loader',
6
+ standalone: true,
7
+ templateUrl: './skeleton-loader.component.html',
8
+ styleUrls: ['./skeleton-loader.component.scss'],
9
+ })
10
+ export class SkeletonLoaderComponent {
11
+ /** Enables shimmer animation */
12
+ @Input() animated = true;
13
+
14
+ /** Rectangle height for a single row */
15
+ @Input() height?: string;
16
+
17
+ /** Number of skeleton rows (for multi-line placeholders) */
18
+ @Input() rows = 1;
19
+
20
+ /** Shape of the skeleton: rectangle or circle */
21
+ @Input() shape: 'rect' | 'circle' = 'rect';
22
+
23
+ /** Circle size (sets both width & height) */
24
+ @Input() size?: string;
25
+
26
+ /** Style type (color scheme) */
27
+ @Input() styleType: TSkeletonLoaderType = 'default';
28
+
29
+ /** Rectangle width (ignored for circle unless explicitly given) */
30
+ @Input() width?: string;
31
+
32
+ @HostBinding('class')
33
+ get hostClasses(): string {
34
+ const classes = ['skeleton', `skeleton--${this.styleType}`];
35
+ if (this.shape === 'circle') classes.push('circle');
36
+ if (this.animated) classes.push('animated');
37
+ return classes.join(' ');
38
+ }
39
+
40
+ get rowArray() {
41
+ return Array.from({ length: this.rows });
42
+ }
43
+
44
+ get isMultiRow() {
45
+ return this.rows > 1;
46
+ }
47
+
48
+ get isCircle() {
49
+ return this.shape === 'circle';
50
+ }
51
+ }
@@ -0,0 +1,6 @@
1
+ import { TBaseSize } from "../../../types/base.types";
2
+ import { TBaseLoaderStyle } from "../loader.type";
3
+
4
+ export type TSkeletonLoaderSize = TBaseSize | 'full';
5
+
6
+ export type TSkeletonLoaderType = TBaseLoaderStyle | 'default';
@@ -0,0 +1,20 @@
1
+ <output class="frg-spinner" aria-label="{{label}}"
2
+ [ngClass]="{
3
+ 'frg-spinner--xs' : size === 'extra-small',
4
+ 'frg-spinner--sm' : size === 'small',
5
+ 'frg-spinner--md' : size === 'medium',
6
+ 'frg-spinner--lg' : size === 'large',
7
+ 'frg-spinner--xl' : size === 'extra-large',
8
+ 'frg-spinner--primary': styleType === 'primary',
9
+ 'frg-spinner--secondary': styleType === 'secondary',
10
+ 'frg-spinner--tertiary': styleType === 'tertiary',
11
+ 'frg-spinner--dark': styleType === 'dark',
12
+ 'frg-spinner--light': styleType === 'light',
13
+ 'frg-spinner--center': isCentered,
14
+ 'frg-spinner--overlay': isOverlay,
15
+ 'frg-spinner--overlay-item': isOverlayItem
16
+ }"
17
+ >
18
+ <div class="frg-spinner__circle" aria-hidden="true"></div>
19
+ <span class="sr-only">{{label}}</span>
20
+ </output>