@skyux/core 5.9.4 → 6.0.0-beta.10

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 (267) hide show
  1. package/documentation.json +727 -503
  2. package/esm2020/index.mjs +64 -0
  3. package/esm2020/lib/modules/adapter-service/adapter.module.mjs +16 -0
  4. package/esm2020/lib/modules/adapter-service/adapter.service.mjs +225 -0
  5. package/esm2020/lib/modules/adapter-service/focusable-children-options.mjs +2 -0
  6. package/esm2020/lib/modules/affix/affix-auto-fit-context.mjs +12 -0
  7. package/esm2020/lib/modules/affix/affix-config.mjs +2 -0
  8. package/esm2020/lib/modules/affix/affix-horizontal-alignment.mjs +2 -0
  9. package/esm2020/lib/modules/affix/affix-offset-change.mjs +2 -0
  10. package/esm2020/lib/modules/affix/affix-offset.mjs +2 -0
  11. package/esm2020/lib/modules/affix/affix-placement-change.mjs +2 -0
  12. package/esm2020/lib/modules/affix/affix-placement.mjs +2 -0
  13. package/esm2020/lib/modules/affix/affix-utils.mjs +18 -0
  14. package/esm2020/lib/modules/affix/affix-vertical-alignment.mjs +2 -0
  15. package/esm2020/lib/modules/affix/affix.directive.mjs +100 -0
  16. package/esm2020/lib/modules/affix/affix.module.mjs +18 -0
  17. package/esm2020/lib/modules/affix/affix.service.mjs +24 -0
  18. package/esm2020/lib/modules/affix/affixer.mjs +346 -0
  19. package/esm2020/lib/modules/affix/dom-utils.mjs +77 -0
  20. package/esm2020/lib/modules/dock/dock-dom-adapter.service.mjs +80 -0
  21. package/esm2020/lib/modules/dock/dock-insert-component-config.mjs +2 -0
  22. package/esm2020/lib/modules/dock/dock-item-config.mjs +2 -0
  23. package/esm2020/lib/modules/dock/dock-item-reference.mjs +2 -0
  24. package/esm2020/lib/modules/dock/dock-item.mjs +29 -0
  25. package/esm2020/lib/modules/dock/dock-location.mjs +19 -0
  26. package/esm2020/lib/modules/dock/dock-options.mjs +2 -0
  27. package/esm2020/lib/modules/dock/dock.component.mjs +88 -0
  28. package/esm2020/lib/modules/dock/dock.module.mjs +19 -0
  29. package/esm2020/lib/modules/dock/dock.service.mjs +95 -0
  30. package/esm2020/lib/modules/dock/sort-by-stack-order.mjs +13 -0
  31. package/esm2020/lib/modules/dynamic-component/dynamic-component-location.mjs +27 -0
  32. package/esm2020/lib/modules/dynamic-component/dynamic-component-options.mjs +2 -0
  33. package/esm2020/lib/modules/dynamic-component/dynamic-component.module.mjs +17 -0
  34. package/esm2020/lib/modules/dynamic-component/dynamic-component.service.mjs +83 -0
  35. package/esm2020/lib/modules/format/app-format.mjs +18 -0
  36. package/esm2020/lib/modules/id/id.directive.mjs +34 -0
  37. package/esm2020/lib/modules/id/id.module.mjs +16 -0
  38. package/esm2020/lib/modules/log/log.module.mjs +16 -0
  39. package/esm2020/lib/modules/log/log.service.mjs +132 -0
  40. package/esm2020/lib/modules/log/types/log-deprecation-args.mjs +2 -0
  41. package/esm2020/lib/modules/log/types/log-level-token.mjs +6 -0
  42. package/esm2020/lib/modules/log/types/log-level.mjs +2 -0
  43. package/esm2020/lib/modules/media-query/media-breakpoints.mjs +20 -0
  44. package/esm2020/lib/modules/media-query/media-query-listener.mjs +2 -0
  45. package/esm2020/lib/modules/media-query/media-query.module.mjs +16 -0
  46. package/esm2020/lib/modules/media-query/media-query.service.mjs +121 -0
  47. package/esm2020/lib/modules/mutation/mutation-observer-service.mjs +16 -0
  48. package/esm2020/lib/modules/numeric/numeric-symbol.mjs +2 -0
  49. package/esm2020/lib/modules/numeric/numeric.module.mjs +20 -0
  50. package/esm2020/lib/modules/numeric/numeric.options.mjs +46 -0
  51. package/esm2020/lib/modules/numeric/numeric.pipe.mjs +80 -0
  52. package/esm2020/lib/modules/numeric/numeric.service.mjs +186 -0
  53. package/esm2020/lib/modules/overlay/overlay-adapter.service.mjs +41 -0
  54. package/esm2020/lib/modules/overlay/overlay-config.mjs +2 -0
  55. package/esm2020/lib/modules/overlay/overlay-context.mjs +10 -0
  56. package/esm2020/lib/modules/overlay/overlay-instance.mjs +55 -0
  57. package/esm2020/lib/modules/overlay/overlay.component.mjs +149 -0
  58. package/esm2020/lib/modules/overlay/overlay.module.mjs +17 -0
  59. package/esm2020/lib/modules/overlay/overlay.service.mjs +120 -0
  60. package/esm2020/lib/modules/percent-pipe/percent-pipe.module.mjs +20 -0
  61. package/esm2020/lib/modules/percent-pipe/percent.pipe.mjs +48 -0
  62. package/esm2020/lib/modules/resize-observer/resize-observer-media-query.service.mjs +117 -0
  63. package/esm2020/lib/modules/resize-observer/resize-observer.service.mjs +73 -0
  64. package/esm2020/lib/modules/scrollable-host/scrollable-host.service.mjs +184 -0
  65. package/esm2020/lib/modules/shared/number-format/number-format-utility.mjs +71 -0
  66. package/esm2020/lib/modules/shared/sky-core-resources.module.mjs +50 -0
  67. package/esm2020/lib/modules/title/set-title-args.mjs +2 -0
  68. package/esm2020/lib/modules/title/title.service.mjs +31 -0
  69. package/esm2020/lib/modules/ui-config/ui-config.service.mjs +21 -0
  70. package/esm2020/lib/modules/viewkeeper/viewkeeper-boundary-info.mjs +2 -0
  71. package/esm2020/lib/modules/viewkeeper/viewkeeper-fixed-styles.mjs +2 -0
  72. package/esm2020/lib/modules/viewkeeper/viewkeeper-host-options.mjs +10 -0
  73. package/esm2020/lib/modules/viewkeeper/viewkeeper-offset.mjs +2 -0
  74. package/esm2020/lib/modules/viewkeeper/viewkeeper-options.mjs +2 -0
  75. package/esm2020/lib/modules/viewkeeper/viewkeeper.directive.mjs +116 -0
  76. package/esm2020/lib/modules/viewkeeper/viewkeeper.mjs +251 -0
  77. package/esm2020/lib/modules/viewkeeper/viewkeeper.module.mjs +16 -0
  78. package/esm2020/lib/modules/viewkeeper/viewkeeper.service.mjs +39 -0
  79. package/esm2020/lib/modules/window/window-ref.mjs +30 -0
  80. package/esm2020/skyux-core.mjs +5 -0
  81. package/esm2020/testing/mock-media-query.service.mjs +41 -0
  82. package/esm2020/testing/mock-ui-config.service.mjs +59 -0
  83. package/esm2020/testing/public-api.mjs +3 -0
  84. package/esm2020/testing/skyux-core-testing.mjs +5 -0
  85. package/fesm2015/{skyux-core-testing.js → skyux-core-testing.mjs} +7 -7
  86. package/fesm2015/skyux-core-testing.mjs.map +1 -0
  87. package/fesm2015/skyux-core.mjs +3343 -0
  88. package/fesm2015/skyux-core.mjs.map +1 -0
  89. package/fesm2020/skyux-core-testing.mjs +103 -0
  90. package/fesm2020/skyux-core-testing.mjs.map +1 -0
  91. package/{fesm2015/skyux-core.js → fesm2020/skyux-core.mjs} +270 -178
  92. package/fesm2020/skyux-core.mjs.map +1 -0
  93. package/index.d.ts +2 -0
  94. package/lib/modules/log/log.service.d.ts +37 -3
  95. package/lib/modules/log/types/log-deprecation-args.d.ts +27 -0
  96. package/lib/modules/log/types/log-level-token.d.ts +6 -0
  97. package/lib/modules/log/types/log-level.d.ts +8 -0
  98. package/lib/modules/numeric/numeric.options.d.ts +6 -1
  99. package/lib/modules/numeric/numeric.pipe.d.ts +2 -4
  100. package/lib/modules/numeric/numeric.service.d.ts +2 -2
  101. package/lib/modules/resize-observer/resize-observer-media-query.service.d.ts +0 -1
  102. package/package.json +35 -11
  103. package/testing/package.json +5 -5
  104. package/bundles/skyux-core-testing.umd.js +0 -459
  105. package/bundles/skyux-core.umd.js +0 -3848
  106. package/esm2015/index.js +0 -62
  107. package/esm2015/index.js.map +0 -1
  108. package/esm2015/lib/modules/adapter-service/adapter.module.js +0 -16
  109. package/esm2015/lib/modules/adapter-service/adapter.module.js.map +0 -1
  110. package/esm2015/lib/modules/adapter-service/adapter.service.js +0 -226
  111. package/esm2015/lib/modules/adapter-service/adapter.service.js.map +0 -1
  112. package/esm2015/lib/modules/adapter-service/focusable-children-options.js +0 -2
  113. package/esm2015/lib/modules/adapter-service/focusable-children-options.js.map +0 -1
  114. package/esm2015/lib/modules/affix/affix-auto-fit-context.js +0 -12
  115. package/esm2015/lib/modules/affix/affix-auto-fit-context.js.map +0 -1
  116. package/esm2015/lib/modules/affix/affix-config.js +0 -2
  117. package/esm2015/lib/modules/affix/affix-config.js.map +0 -1
  118. package/esm2015/lib/modules/affix/affix-horizontal-alignment.js +0 -2
  119. package/esm2015/lib/modules/affix/affix-horizontal-alignment.js.map +0 -1
  120. package/esm2015/lib/modules/affix/affix-offset-change.js +0 -2
  121. package/esm2015/lib/modules/affix/affix-offset-change.js.map +0 -1
  122. package/esm2015/lib/modules/affix/affix-offset.js +0 -2
  123. package/esm2015/lib/modules/affix/affix-offset.js.map +0 -1
  124. package/esm2015/lib/modules/affix/affix-placement-change.js +0 -2
  125. package/esm2015/lib/modules/affix/affix-placement-change.js.map +0 -1
  126. package/esm2015/lib/modules/affix/affix-placement.js +0 -2
  127. package/esm2015/lib/modules/affix/affix-placement.js.map +0 -1
  128. package/esm2015/lib/modules/affix/affix-utils.js +0 -18
  129. package/esm2015/lib/modules/affix/affix-utils.js.map +0 -1
  130. package/esm2015/lib/modules/affix/affix-vertical-alignment.js +0 -2
  131. package/esm2015/lib/modules/affix/affix-vertical-alignment.js.map +0 -1
  132. package/esm2015/lib/modules/affix/affix.directive.js +0 -100
  133. package/esm2015/lib/modules/affix/affix.directive.js.map +0 -1
  134. package/esm2015/lib/modules/affix/affix.module.js +0 -18
  135. package/esm2015/lib/modules/affix/affix.module.js.map +0 -1
  136. package/esm2015/lib/modules/affix/affix.service.js +0 -24
  137. package/esm2015/lib/modules/affix/affix.service.js.map +0 -1
  138. package/esm2015/lib/modules/affix/affixer.js +0 -349
  139. package/esm2015/lib/modules/affix/affixer.js.map +0 -1
  140. package/esm2015/lib/modules/affix/dom-utils.js +0 -77
  141. package/esm2015/lib/modules/affix/dom-utils.js.map +0 -1
  142. package/esm2015/lib/modules/dock/dock-dom-adapter.service.js +0 -80
  143. package/esm2015/lib/modules/dock/dock-dom-adapter.service.js.map +0 -1
  144. package/esm2015/lib/modules/dock/dock-insert-component-config.js +0 -2
  145. package/esm2015/lib/modules/dock/dock-insert-component-config.js.map +0 -1
  146. package/esm2015/lib/modules/dock/dock-item-config.js +0 -2
  147. package/esm2015/lib/modules/dock/dock-item-config.js.map +0 -1
  148. package/esm2015/lib/modules/dock/dock-item-reference.js +0 -2
  149. package/esm2015/lib/modules/dock/dock-item-reference.js.map +0 -1
  150. package/esm2015/lib/modules/dock/dock-item.js +0 -29
  151. package/esm2015/lib/modules/dock/dock-item.js.map +0 -1
  152. package/esm2015/lib/modules/dock/dock-location.js +0 -19
  153. package/esm2015/lib/modules/dock/dock-location.js.map +0 -1
  154. package/esm2015/lib/modules/dock/dock-options.js +0 -2
  155. package/esm2015/lib/modules/dock/dock-options.js.map +0 -1
  156. package/esm2015/lib/modules/dock/dock.component.js +0 -95
  157. package/esm2015/lib/modules/dock/dock.component.js.map +0 -1
  158. package/esm2015/lib/modules/dock/dock.module.js +0 -20
  159. package/esm2015/lib/modules/dock/dock.module.js.map +0 -1
  160. package/esm2015/lib/modules/dock/dock.service.js +0 -95
  161. package/esm2015/lib/modules/dock/dock.service.js.map +0 -1
  162. package/esm2015/lib/modules/dock/sort-by-stack-order.js +0 -13
  163. package/esm2015/lib/modules/dock/sort-by-stack-order.js.map +0 -1
  164. package/esm2015/lib/modules/dynamic-component/dynamic-component-location.js +0 -27
  165. package/esm2015/lib/modules/dynamic-component/dynamic-component-location.js.map +0 -1
  166. package/esm2015/lib/modules/dynamic-component/dynamic-component-options.js +0 -2
  167. package/esm2015/lib/modules/dynamic-component/dynamic-component-options.js.map +0 -1
  168. package/esm2015/lib/modules/dynamic-component/dynamic-component.module.js +0 -17
  169. package/esm2015/lib/modules/dynamic-component/dynamic-component.module.js.map +0 -1
  170. package/esm2015/lib/modules/dynamic-component/dynamic-component.service.js +0 -83
  171. package/esm2015/lib/modules/dynamic-component/dynamic-component.service.js.map +0 -1
  172. package/esm2015/lib/modules/format/app-format.js +0 -18
  173. package/esm2015/lib/modules/format/app-format.js.map +0 -1
  174. package/esm2015/lib/modules/id/id.directive.js +0 -34
  175. package/esm2015/lib/modules/id/id.directive.js.map +0 -1
  176. package/esm2015/lib/modules/id/id.module.js +0 -16
  177. package/esm2015/lib/modules/id/id.module.js.map +0 -1
  178. package/esm2015/lib/modules/log/log.module.js +0 -16
  179. package/esm2015/lib/modules/log/log.module.js.map +0 -1
  180. package/esm2015/lib/modules/log/log.service.js +0 -23
  181. package/esm2015/lib/modules/log/log.service.js.map +0 -1
  182. package/esm2015/lib/modules/media-query/media-breakpoints.js +0 -20
  183. package/esm2015/lib/modules/media-query/media-breakpoints.js.map +0 -1
  184. package/esm2015/lib/modules/media-query/media-query-listener.js +0 -2
  185. package/esm2015/lib/modules/media-query/media-query-listener.js.map +0 -1
  186. package/esm2015/lib/modules/media-query/media-query.module.js +0 -16
  187. package/esm2015/lib/modules/media-query/media-query.module.js.map +0 -1
  188. package/esm2015/lib/modules/media-query/media-query.service.js +0 -121
  189. package/esm2015/lib/modules/media-query/media-query.service.js.map +0 -1
  190. package/esm2015/lib/modules/mutation/mutation-observer-service.js +0 -16
  191. package/esm2015/lib/modules/mutation/mutation-observer-service.js.map +0 -1
  192. package/esm2015/lib/modules/numeric/numeric-symbol.js +0 -2
  193. package/esm2015/lib/modules/numeric/numeric-symbol.js.map +0 -1
  194. package/esm2015/lib/modules/numeric/numeric.module.js +0 -20
  195. package/esm2015/lib/modules/numeric/numeric.module.js.map +0 -1
  196. package/esm2015/lib/modules/numeric/numeric.options.js +0 -41
  197. package/esm2015/lib/modules/numeric/numeric.options.js.map +0 -1
  198. package/esm2015/lib/modules/numeric/numeric.pipe.js +0 -83
  199. package/esm2015/lib/modules/numeric/numeric.pipe.js.map +0 -1
  200. package/esm2015/lib/modules/numeric/numeric.service.js +0 -189
  201. package/esm2015/lib/modules/numeric/numeric.service.js.map +0 -1
  202. package/esm2015/lib/modules/overlay/overlay-adapter.service.js +0 -41
  203. package/esm2015/lib/modules/overlay/overlay-adapter.service.js.map +0 -1
  204. package/esm2015/lib/modules/overlay/overlay-config.js +0 -2
  205. package/esm2015/lib/modules/overlay/overlay-config.js.map +0 -1
  206. package/esm2015/lib/modules/overlay/overlay-context.js +0 -10
  207. package/esm2015/lib/modules/overlay/overlay-context.js.map +0 -1
  208. package/esm2015/lib/modules/overlay/overlay-instance.js +0 -55
  209. package/esm2015/lib/modules/overlay/overlay-instance.js.map +0 -1
  210. package/esm2015/lib/modules/overlay/overlay.component.js +0 -154
  211. package/esm2015/lib/modules/overlay/overlay.component.js.map +0 -1
  212. package/esm2015/lib/modules/overlay/overlay.module.js +0 -18
  213. package/esm2015/lib/modules/overlay/overlay.module.js.map +0 -1
  214. package/esm2015/lib/modules/overlay/overlay.service.js +0 -120
  215. package/esm2015/lib/modules/overlay/overlay.service.js.map +0 -1
  216. package/esm2015/lib/modules/percent-pipe/percent-pipe.module.js +0 -20
  217. package/esm2015/lib/modules/percent-pipe/percent-pipe.module.js.map +0 -1
  218. package/esm2015/lib/modules/percent-pipe/percent.pipe.js +0 -48
  219. package/esm2015/lib/modules/percent-pipe/percent.pipe.js.map +0 -1
  220. package/esm2015/lib/modules/resize-observer/resize-observer-media-query.service.js +0 -117
  221. package/esm2015/lib/modules/resize-observer/resize-observer-media-query.service.js.map +0 -1
  222. package/esm2015/lib/modules/resize-observer/resize-observer.service.js +0 -73
  223. package/esm2015/lib/modules/resize-observer/resize-observer.service.js.map +0 -1
  224. package/esm2015/lib/modules/scrollable-host/scrollable-host.service.js +0 -184
  225. package/esm2015/lib/modules/scrollable-host/scrollable-host.service.js.map +0 -1
  226. package/esm2015/lib/modules/shared/number-format/number-format-utility.js +0 -72
  227. package/esm2015/lib/modules/shared/number-format/number-format-utility.js.map +0 -1
  228. package/esm2015/lib/modules/shared/sky-core-resources.module.js +0 -50
  229. package/esm2015/lib/modules/shared/sky-core-resources.module.js.map +0 -1
  230. package/esm2015/lib/modules/title/set-title-args.js +0 -2
  231. package/esm2015/lib/modules/title/set-title-args.js.map +0 -1
  232. package/esm2015/lib/modules/title/title.service.js +0 -31
  233. package/esm2015/lib/modules/title/title.service.js.map +0 -1
  234. package/esm2015/lib/modules/ui-config/ui-config.service.js +0 -21
  235. package/esm2015/lib/modules/ui-config/ui-config.service.js.map +0 -1
  236. package/esm2015/lib/modules/viewkeeper/viewkeeper-boundary-info.js +0 -2
  237. package/esm2015/lib/modules/viewkeeper/viewkeeper-boundary-info.js.map +0 -1
  238. package/esm2015/lib/modules/viewkeeper/viewkeeper-fixed-styles.js +0 -2
  239. package/esm2015/lib/modules/viewkeeper/viewkeeper-fixed-styles.js.map +0 -1
  240. package/esm2015/lib/modules/viewkeeper/viewkeeper-host-options.js +0 -10
  241. package/esm2015/lib/modules/viewkeeper/viewkeeper-host-options.js.map +0 -1
  242. package/esm2015/lib/modules/viewkeeper/viewkeeper-offset.js +0 -2
  243. package/esm2015/lib/modules/viewkeeper/viewkeeper-offset.js.map +0 -1
  244. package/esm2015/lib/modules/viewkeeper/viewkeeper-options.js +0 -2
  245. package/esm2015/lib/modules/viewkeeper/viewkeeper-options.js.map +0 -1
  246. package/esm2015/lib/modules/viewkeeper/viewkeeper.directive.js +0 -116
  247. package/esm2015/lib/modules/viewkeeper/viewkeeper.directive.js.map +0 -1
  248. package/esm2015/lib/modules/viewkeeper/viewkeeper.js +0 -251
  249. package/esm2015/lib/modules/viewkeeper/viewkeeper.js.map +0 -1
  250. package/esm2015/lib/modules/viewkeeper/viewkeeper.module.js +0 -16
  251. package/esm2015/lib/modules/viewkeeper/viewkeeper.module.js.map +0 -1
  252. package/esm2015/lib/modules/viewkeeper/viewkeeper.service.js +0 -39
  253. package/esm2015/lib/modules/viewkeeper/viewkeeper.service.js.map +0 -1
  254. package/esm2015/lib/modules/window/window-ref.js +0 -30
  255. package/esm2015/lib/modules/window/window-ref.js.map +0 -1
  256. package/esm2015/skyux-core.js +0 -5
  257. package/esm2015/skyux-core.js.map +0 -1
  258. package/esm2015/testing/mock-media-query.service.js +0 -41
  259. package/esm2015/testing/mock-media-query.service.js.map +0 -1
  260. package/esm2015/testing/mock-ui-config.service.js +0 -59
  261. package/esm2015/testing/mock-ui-config.service.js.map +0 -1
  262. package/esm2015/testing/public-api.js +0 -3
  263. package/esm2015/testing/public-api.js.map +0 -1
  264. package/esm2015/testing/skyux-core-testing.js +0 -5
  265. package/esm2015/testing/skyux-core-testing.js.map +0 -1
  266. package/fesm2015/skyux-core-testing.js.map +0 -1
  267. package/fesm2015/skyux-core.js.map +0 -1
@@ -0,0 +1,3343 @@
1
+ import * as i0 from '@angular/core';
2
+ import { NgModule, Injectable, EventEmitter, Directive, Input, Output, Injector, ViewContainerRef, Component, ChangeDetectionStrategy, ViewChild, InjectionToken, Optional, Inject, Pipe, ElementRef } from '@angular/core';
3
+ import * as i4 from '@angular/common';
4
+ import { CommonModule } from '@angular/common';
5
+ import { Subject, fromEvent, BehaviorSubject, ReplaySubject, Observable, of } from 'rxjs';
6
+ import { takeUntil, debounceTime, finalize } from 'rxjs/operators';
7
+ import { __awaiter } from 'tslib';
8
+ import * as i1 from '@skyux/i18n';
9
+ import { getLibStringForLocale, SkyI18nModule, SKY_LIB_RESOURCES_PROVIDERS, SkyIntlNumberFormatStyle, SkyIntlNumberFormatter } from '@skyux/i18n';
10
+ import * as i3 from '@angular/router';
11
+ import { NavigationStart } from '@angular/router';
12
+ import * as i1$1 from '@angular/platform-browser';
13
+
14
+ /**
15
+ * @deprecated The `SkyCoreAdapterService` no longer needs the `SkyCoreAdapterModule`.
16
+ * The `SkyCoreAdapterModule` can be removed from your project.
17
+ */
18
+ class SkyCoreAdapterModule {
19
+ }
20
+ SkyCoreAdapterModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyCoreAdapterModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
21
+ SkyCoreAdapterModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyCoreAdapterModule });
22
+ SkyCoreAdapterModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyCoreAdapterModule });
23
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyCoreAdapterModule, decorators: [{
24
+ type: NgModule,
25
+ args: [{}]
26
+ }] });
27
+
28
+ var SkyMediaBreakpoints;
29
+ (function (SkyMediaBreakpoints) {
30
+ /**
31
+ * Indicates screen widths of 767px or less.
32
+ */
33
+ SkyMediaBreakpoints[SkyMediaBreakpoints["xs"] = 1] = "xs";
34
+ /**
35
+ * Indicates screen widths of 768px to 991px.
36
+ */
37
+ SkyMediaBreakpoints[SkyMediaBreakpoints["sm"] = 2] = "sm";
38
+ /**
39
+ * Indicates screen widths of 992px to 1199px.
40
+ */
41
+ SkyMediaBreakpoints[SkyMediaBreakpoints["md"] = 3] = "md";
42
+ /**
43
+ * Indicates screen widths of 1200px or greater.
44
+ */
45
+ SkyMediaBreakpoints[SkyMediaBreakpoints["lg"] = 4] = "lg";
46
+ })(SkyMediaBreakpoints || (SkyMediaBreakpoints = {}));
47
+
48
+ const SKY_TABBABLE_SELECTOR = [
49
+ 'a[href]',
50
+ 'area[href]',
51
+ 'input:not([disabled])',
52
+ 'button:not([disabled])',
53
+ 'select:not([disabled])',
54
+ 'textarea:not([disabled])',
55
+ 'iframe',
56
+ 'object',
57
+ 'embed',
58
+ '*[contenteditable=true]:not([disabled])',
59
+ '*[tabindex]:not([disabled])',
60
+ ].join(', ');
61
+ class SkyCoreAdapterService {
62
+ constructor(rendererFactory) {
63
+ this.rendererFactory = rendererFactory;
64
+ this.renderer = this.rendererFactory.createRenderer(undefined, undefined);
65
+ }
66
+ /**
67
+ * Set the responsive container CSS class for a given element.
68
+ *
69
+ * @param elementRef - The element that will recieve the new CSS class.
70
+ * @param breakpoint - The SkyMediaBreakpoint will determine which class
71
+ * gets set. For example a SkyMediaBreakpoint of `xs` will set a CSS class of `sky-responsive-container-xs`.
72
+ */
73
+ setResponsiveContainerClass(elementRef, breakpoint) {
74
+ const nativeEl = elementRef.nativeElement;
75
+ this.renderer.removeClass(nativeEl, 'sky-responsive-container-xs');
76
+ this.renderer.removeClass(nativeEl, 'sky-responsive-container-sm');
77
+ this.renderer.removeClass(nativeEl, 'sky-responsive-container-md');
78
+ this.renderer.removeClass(nativeEl, 'sky-responsive-container-lg');
79
+ let newClass;
80
+ switch (breakpoint) {
81
+ case SkyMediaBreakpoints.xs: {
82
+ newClass = 'sky-responsive-container-xs';
83
+ break;
84
+ }
85
+ case SkyMediaBreakpoints.sm: {
86
+ newClass = 'sky-responsive-container-sm';
87
+ break;
88
+ }
89
+ case SkyMediaBreakpoints.md: {
90
+ newClass = 'sky-responsive-container-md';
91
+ break;
92
+ }
93
+ default: {
94
+ newClass = 'sky-responsive-container-lg';
95
+ break;
96
+ }
97
+ }
98
+ this.renderer.addClass(nativeEl, newClass);
99
+ }
100
+ /**
101
+ * This method temporarily enables/disables pointer events.
102
+ * This is helpful to prevent iFrames from interfering with drag events.
103
+ *
104
+ * @param enable - Set to `true` to enable pointer events. Set to `false` to disable.
105
+ */
106
+ toggleIframePointerEvents(enable) {
107
+ const iframes = document.querySelectorAll('iframe');
108
+ for (let i = 0; i < iframes.length; i++) {
109
+ // Setting to empty string will allow iframe to fall back to its prior CSS assignment.
110
+ iframes[i].style.pointerEvents = enable ? '' : 'none';
111
+ }
112
+ }
113
+ /**
114
+ * Focuses on the first element found with an `autofocus` attribute inside the supplied `elementRef`.
115
+ *
116
+ * @param elementRef - The element to search within.
117
+ * @return Returns `true` if a child element with autofocus is found.
118
+ */
119
+ applyAutoFocus(elementRef) {
120
+ if (!elementRef) {
121
+ return false;
122
+ }
123
+ const elementWithAutoFocus = elementRef.nativeElement.querySelector('[autofocus]');
124
+ // Child was found with the autofocus property. Set focus and return true.
125
+ if (elementWithAutoFocus) {
126
+ elementWithAutoFocus.focus();
127
+ return true;
128
+ }
129
+ // No children were found with autofocus property. Return false.
130
+ return false;
131
+ }
132
+ /**
133
+ * Sets focus on the first focusable child of the `elementRef` parameter.
134
+ * If no focusable children are found, and `focusOnContainerIfNoChildrenFound` is `true`,
135
+ * focus will be set on the container element.
136
+ *
137
+ * @param elementRef - The element to search within.
138
+ * @param containerSelector - A CSS selector indicating the container that should
139
+ * recieve focus if no focusable children are found.
140
+ * @param focusOnContainerIfNoChildrenFound - It set to `true`, the container will
141
+ * recieve focus if no focusable children are found.
142
+ */
143
+ getFocusableChildrenAndApplyFocus(elementRef, containerSelector, focusOnContainerIfNoChildrenFound = false) {
144
+ const containerElement = elementRef.nativeElement.querySelector(containerSelector);
145
+ if (containerElement) {
146
+ const focusableChildren = this.getFocusableChildren(containerElement);
147
+ // Focus first focusable child if available. Otherwise, set focus on container.
148
+ if (!this.focusFirstElement(focusableChildren) &&
149
+ focusOnContainerIfNoChildrenFound) {
150
+ containerElement.focus();
151
+ }
152
+ }
153
+ }
154
+ /**
155
+ * Returns an array of all focusable children of provided `element`.
156
+ *
157
+ * @param element - The HTMLElement to search within.
158
+ * @param options - Options for getting focusable children.
159
+ */
160
+ getFocusableChildren(element, options) {
161
+ if (!element) {
162
+ return [];
163
+ }
164
+ let elements = Array.prototype.slice.call(element.querySelectorAll(SKY_TABBABLE_SELECTOR));
165
+ // Unless ignoreTabIndex = true, filter out elements with tabindex = -1.
166
+ if (!options || !options.ignoreTabIndex) {
167
+ elements = elements.filter((el) => {
168
+ return el.tabIndex !== -1;
169
+ });
170
+ }
171
+ // Unless ignoreVisibility = true, filter out elements that are not visible.
172
+ if (!options || !options.ignoreVisibility) {
173
+ elements = elements.filter((el) => {
174
+ return this.isVisible(el);
175
+ });
176
+ }
177
+ return elements;
178
+ }
179
+ /**
180
+ * Returns the clientWidth of the provided elementRef.
181
+ * @param elementRef - The element to calculate width from.
182
+ */
183
+ getWidth(elementRef) {
184
+ return elementRef.nativeElement.clientWidth;
185
+ }
186
+ /**
187
+ * Checks if an event target has a higher z-index than a given element.
188
+ * @param target The event target element.
189
+ * @param element The element to test against. A z-index must be explicitly set for this element.
190
+ */
191
+ isTargetAboveElement(target, element) {
192
+ const zIndex = getComputedStyle(element).zIndex;
193
+ let el = target;
194
+ while (el) {
195
+ // Getting the computed style only works for elements that exist in the DOM.
196
+ // In certain scenarios, an element is removed after a click event; by the time the event
197
+ // bubbles up to other elements, however, the element has been removed and the computed style returns empty.
198
+ // In this case, we'll need to check the z-index directly, via the style property.
199
+ const targetZIndex = getComputedStyle(el).zIndex || el.style.zIndex;
200
+ if (targetZIndex !== '' &&
201
+ targetZIndex !== 'auto' &&
202
+ +targetZIndex > +zIndex) {
203
+ return true;
204
+ }
205
+ el = el.parentElement;
206
+ }
207
+ return false;
208
+ }
209
+ /**
210
+ * Remove inline height styles from the provided elements.
211
+ * @param elementRef - The element to search within.
212
+ * @param selector - The CSS selector to use when finding elements for removing height.
213
+ */
214
+ resetHeight(elementRef, selector) {
215
+ const children = elementRef.nativeElement.querySelectorAll(selector);
216
+ /* istanbul ignore else */
217
+ if (children.length > 0) {
218
+ for (let i = 0; i < children.length; i++) {
219
+ // Setting style attributes with Web API requires null instead of undefined.
220
+ children[i].style.height = null;
221
+ }
222
+ }
223
+ }
224
+ /**
225
+ * Sets all element heights to match the height of the tallest element.
226
+ * @param elementRef - The element to search within.
227
+ * @param selector - The CSS selector to use when finding elements for syncing height.
228
+ */
229
+ syncMaxHeight(elementRef, selector) {
230
+ const children = elementRef.nativeElement.querySelectorAll(selector);
231
+ /* istanbul ignore else */
232
+ if (children.length > 0) {
233
+ let maxHeight = 0;
234
+ for (let i = 0; i < children.length; i++) {
235
+ maxHeight = Math.max(maxHeight, children[i].offsetHeight);
236
+ }
237
+ for (let i = 0; i < children.length; i++) {
238
+ children[i].style.height = maxHeight + 'px';
239
+ }
240
+ }
241
+ }
242
+ focusFirstElement(list) {
243
+ if (list.length > 0) {
244
+ list[0].focus();
245
+ return true;
246
+ }
247
+ return false;
248
+ }
249
+ isVisible(element) {
250
+ const style = window.getComputedStyle(element);
251
+ const isHidden = style.display === 'none' || style.visibility === 'hidden';
252
+ if (isHidden) {
253
+ return false;
254
+ }
255
+ const hasBounds = !!(element.offsetWidth ||
256
+ element.offsetHeight ||
257
+ element.getClientRects().length);
258
+ return hasBounds;
259
+ }
260
+ }
261
+ SkyCoreAdapterService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyCoreAdapterService, deps: [{ token: i0.RendererFactory2 }], target: i0.ɵɵFactoryTarget.Injectable });
262
+ SkyCoreAdapterService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyCoreAdapterService, providedIn: 'root' });
263
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyCoreAdapterService, decorators: [{
264
+ type: Injectable,
265
+ args: [{
266
+ providedIn: 'root',
267
+ }]
268
+ }], ctorParameters: function () { return [{ type: i0.RendererFactory2 }]; } });
269
+
270
+ var SkyAffixAutoFitContext;
271
+ (function (SkyAffixAutoFitContext) {
272
+ /**
273
+ * Auto-fit functionality will respect the nearest overflow parent element's dimensions.
274
+ */
275
+ SkyAffixAutoFitContext[SkyAffixAutoFitContext["OverflowParent"] = 0] = "OverflowParent";
276
+ /**
277
+ * Auto-fit functionality will respect the browser viewport dimensions.
278
+ */
279
+ SkyAffixAutoFitContext[SkyAffixAutoFitContext["Viewport"] = 1] = "Viewport";
280
+ })(SkyAffixAutoFitContext || (SkyAffixAutoFitContext = {}));
281
+
282
+ function getNextPlacement(placement) {
283
+ const placements = ['above', 'right', 'below', 'left'];
284
+ let index = placements.indexOf(placement) + 1;
285
+ if (index >= placements.length) {
286
+ index = 0;
287
+ }
288
+ return placements[index];
289
+ }
290
+ function getInversePlacement(placement) {
291
+ const pairings = {
292
+ above: 'below',
293
+ below: 'above',
294
+ right: 'left',
295
+ left: 'right',
296
+ };
297
+ return pairings[placement];
298
+ }
299
+
300
+ /**
301
+ * Returns the offset values of a given element.
302
+ * @param element The HTML element.
303
+ * @param bufferOffset An optional offset to add/subtract to the element's actual offset.
304
+ */
305
+ function getElementOffset(element, bufferOffset = {}) {
306
+ const bufferOffsetBottom = bufferOffset.bottom || 0;
307
+ const bufferOffsetLeft = bufferOffset.left || 0;
308
+ const bufferOffsetRight = bufferOffset.right || 0;
309
+ const bufferOffsetTop = bufferOffset.top || 0;
310
+ let top;
311
+ let left;
312
+ let right;
313
+ let bottom;
314
+ if (element === document.body) {
315
+ left = 0;
316
+ top = 0;
317
+ right = document.documentElement.clientWidth;
318
+ bottom = document.documentElement.clientHeight;
319
+ }
320
+ else {
321
+ const clientRect = element.getBoundingClientRect();
322
+ left = clientRect.left;
323
+ top = clientRect.top;
324
+ right = clientRect.right;
325
+ bottom = clientRect.bottom;
326
+ }
327
+ bottom -= bufferOffsetBottom;
328
+ left += bufferOffsetLeft;
329
+ right -= bufferOffsetRight;
330
+ top += bufferOffsetTop;
331
+ return {
332
+ bottom,
333
+ left,
334
+ right,
335
+ top,
336
+ };
337
+ }
338
+ function getOverflowParents(child) {
339
+ const bodyElement = window.document.body;
340
+ const results = [bodyElement];
341
+ let parentElement = child.parentNode;
342
+ while (parentElement !== undefined &&
343
+ parentElement !== bodyElement &&
344
+ parentElement instanceof HTMLElement) {
345
+ const overflowY = window
346
+ .getComputedStyle(parentElement, undefined)
347
+ .overflowY.toLowerCase();
348
+ if (overflowY === 'auto' ||
349
+ overflowY === 'hidden' ||
350
+ overflowY === 'scroll') {
351
+ results.push(parentElement);
352
+ }
353
+ parentElement = parentElement.parentNode;
354
+ }
355
+ return results;
356
+ }
357
+ /**
358
+ * Confirms offset is fully visible within a parent element.
359
+ * @param parent
360
+ * @param offset
361
+ */
362
+ function isOffsetFullyVisibleWithinParent(parent, offset, bufferOffset) {
363
+ const parentOffset = getElementOffset(parent, bufferOffset);
364
+ return !(parentOffset.top > offset.top ||
365
+ parentOffset.right < offset.right ||
366
+ parentOffset.bottom < offset.bottom ||
367
+ parentOffset.left > offset.left);
368
+ }
369
+ function isOffsetPartiallyVisibleWithinParent(parent, offset, bufferOffset) {
370
+ const parentOffset = getElementOffset(parent, bufferOffset);
371
+ return !(parentOffset.top >= offset.bottom ||
372
+ parentOffset.right <= offset.left ||
373
+ parentOffset.bottom <= offset.top ||
374
+ parentOffset.left >= offset.right);
375
+ }
376
+
377
+ const DEFAULT_AFFIX_CONFIG = {
378
+ autoFitContext: SkyAffixAutoFitContext.OverflowParent,
379
+ enableAutoFit: false,
380
+ horizontalAlignment: 'center',
381
+ isSticky: false,
382
+ placement: 'above',
383
+ };
384
+ class SkyAffixer {
385
+ constructor(affixedElement, renderer) {
386
+ this.affixedElement = affixedElement;
387
+ this.renderer = renderer;
388
+ this._offsetChange = new Subject();
389
+ this._overflowScroll = new Subject();
390
+ this._placementChange = new Subject();
391
+ }
392
+ /**
393
+ * Fires when the affixed element's offset changes.
394
+ */
395
+ get offsetChange() {
396
+ return this._offsetChange.asObservable();
397
+ }
398
+ /**
399
+ * Fires when the base element's nearest overflow parent is scrolling. This is useful if you need
400
+ * to perform an additional action during the scroll event but don't want to generate another
401
+ * event listener.
402
+ */
403
+ get overflowScroll() {
404
+ return this._overflowScroll.asObservable();
405
+ }
406
+ /**
407
+ * Fires when the placement value changes. A `null` value indicates that a suitable
408
+ * placement could not be found.
409
+ */
410
+ get placementChange() {
411
+ return this._placementChange.asObservable();
412
+ }
413
+ get config() {
414
+ return this._config;
415
+ }
416
+ set config(value) {
417
+ const merged = Object.assign(Object.assign({}, DEFAULT_AFFIX_CONFIG), value);
418
+ // Make sure none of the values are undefined.
419
+ Object.keys(merged).forEach((k) => {
420
+ if (merged[k] === undefined) {
421
+ merged[k] = DEFAULT_AFFIX_CONFIG[k];
422
+ }
423
+ });
424
+ this._config = merged;
425
+ }
426
+ /**
427
+ * Affixes an element to a base element.
428
+ * @param baseElement The base element.
429
+ * @param config Configuration for the affix action.
430
+ */
431
+ affixTo(baseElement, config) {
432
+ this.reset();
433
+ this.config = config;
434
+ this.baseElement = baseElement;
435
+ this.overflowParents = getOverflowParents(baseElement);
436
+ this.affix();
437
+ if (this.config.isSticky) {
438
+ this.addScrollListeners();
439
+ this.addResizeListener();
440
+ }
441
+ }
442
+ /**
443
+ * Re-runs the affix calculation.
444
+ */
445
+ reaffix() {
446
+ // Reset current placement to preferred placement.
447
+ this.currentPlacement = this.config.placement;
448
+ this.affix();
449
+ }
450
+ /**
451
+ * Destroys the affixer.
452
+ */
453
+ destroy() {
454
+ this.reset();
455
+ this._placementChange.complete();
456
+ this._offsetChange.complete();
457
+ this._overflowScroll.complete();
458
+ this._offsetChange =
459
+ this._placementChange =
460
+ this._overflowScroll =
461
+ undefined;
462
+ }
463
+ affix() {
464
+ this.baseRect = this.baseElement.getBoundingClientRect();
465
+ this.affixedRect = this.affixedElement.getBoundingClientRect();
466
+ const offset = this.getOffset();
467
+ if (this.isNewOffset(offset)) {
468
+ this.renderer.setStyle(this.affixedElement, 'top', `${offset.top}px`);
469
+ this.renderer.setStyle(this.affixedElement, 'left', `${offset.left}px`);
470
+ this._offsetChange.next({ offset });
471
+ }
472
+ }
473
+ getOffset() {
474
+ const parent = this.getAutoFitContextParent();
475
+ const maxAttempts = 4;
476
+ let attempts = 0;
477
+ let isAffixedElementFullyVisible = false;
478
+ let offset;
479
+ let placement = this.config.placement;
480
+ do {
481
+ offset = this.getPreferredOffset(placement);
482
+ isAffixedElementFullyVisible = isOffsetFullyVisibleWithinParent(parent, offset, this.config.autoFitOverflowOffset);
483
+ if (!this.config.enableAutoFit) {
484
+ break;
485
+ }
486
+ if (!isAffixedElementFullyVisible) {
487
+ placement =
488
+ attempts % 2 === 0
489
+ ? getInversePlacement(placement)
490
+ : getNextPlacement(placement);
491
+ }
492
+ attempts++;
493
+ } while (!isAffixedElementFullyVisible && attempts < maxAttempts);
494
+ if (isAffixedElementFullyVisible) {
495
+ if (this.isBaseElementVisible()) {
496
+ this.notifyPlacementChange(placement);
497
+ }
498
+ else {
499
+ this.notifyPlacementChange(null);
500
+ }
501
+ return offset;
502
+ }
503
+ if (this.config.enableAutoFit) {
504
+ this.notifyPlacementChange(null);
505
+ }
506
+ // No suitable placement was found, so revert to preferred placement.
507
+ return this.getPreferredOffset(this.config.placement);
508
+ }
509
+ getPreferredOffset(placement) {
510
+ const affixedRect = this.affixedRect;
511
+ const baseRect = this.baseRect;
512
+ const horizontalAlignment = this.config.horizontalAlignment;
513
+ const verticalAlignment = this.config.verticalAlignment;
514
+ const enableAutoFit = this.config.enableAutoFit;
515
+ let top;
516
+ let left;
517
+ if (placement === 'above' || placement === 'below') {
518
+ if (placement === 'above') {
519
+ top = baseRect.top - affixedRect.height;
520
+ switch (verticalAlignment) {
521
+ case 'top':
522
+ top = top + affixedRect.height;
523
+ break;
524
+ case 'middle':
525
+ top = top + affixedRect.height / 2;
526
+ break;
527
+ case 'bottom':
528
+ default:
529
+ break;
530
+ }
531
+ }
532
+ else {
533
+ top = baseRect.bottom;
534
+ switch (verticalAlignment) {
535
+ case 'top':
536
+ default:
537
+ break;
538
+ case 'middle':
539
+ top = top - affixedRect.height / 2;
540
+ break;
541
+ case 'bottom':
542
+ top = top - affixedRect.height;
543
+ break;
544
+ }
545
+ }
546
+ switch (horizontalAlignment) {
547
+ case 'left':
548
+ left = baseRect.left;
549
+ break;
550
+ case 'center':
551
+ default:
552
+ left = baseRect.left + baseRect.width / 2 - affixedRect.width / 2;
553
+ break;
554
+ case 'right':
555
+ left = baseRect.right - affixedRect.width;
556
+ break;
557
+ }
558
+ }
559
+ else {
560
+ if (placement === 'left') {
561
+ left = baseRect.left - affixedRect.width;
562
+ }
563
+ else {
564
+ left = baseRect.right;
565
+ }
566
+ switch (verticalAlignment) {
567
+ case 'top':
568
+ top = baseRect.top;
569
+ break;
570
+ case 'middle':
571
+ default:
572
+ top = baseRect.top + baseRect.height / 2 - affixedRect.height / 2;
573
+ break;
574
+ case 'bottom':
575
+ top = baseRect.bottom - affixedRect.height;
576
+ break;
577
+ }
578
+ }
579
+ let offset = { left, top };
580
+ if (enableAutoFit) {
581
+ offset = this.adjustOffsetToOverflowParent(Object.assign({}, offset), placement);
582
+ }
583
+ offset.bottom = offset.top + affixedRect.height;
584
+ offset.right = offset.left + affixedRect.width;
585
+ return offset;
586
+ }
587
+ /**
588
+ * Slightly adjust the offset to fit within the scroll parent's boundaries if
589
+ * the affixed element would otherwise be clipped.
590
+ */
591
+ adjustOffsetToOverflowParent(offset, placement) {
592
+ const parent = this.getAutoFitContextParent();
593
+ const parentOffset = getElementOffset(parent, this.config.autoFitOverflowOffset);
594
+ const affixedRect = this.affixedRect;
595
+ const baseRect = this.baseRect;
596
+ // A pixel value representing the leeway between the edge of the overflow parent and the edge
597
+ // of the base element before it dissapears from view.
598
+ // If the visible portion of the base element is less than this pixel value, the auto-fit
599
+ // functionality attempts to find another placement.
600
+ const defaultPixelTolerance = 40;
601
+ let pixelTolerance;
602
+ const originalOffsetTop = offset.top;
603
+ const originalOffsetLeft = offset.left;
604
+ switch (placement) {
605
+ case 'above':
606
+ case 'below':
607
+ // Keep the affixed element within the overflow parent.
608
+ if (offset.left < parentOffset.left) {
609
+ offset.left = parentOffset.left;
610
+ }
611
+ else if (offset.left + affixedRect.width > parentOffset.right) {
612
+ offset.left = parentOffset.right - affixedRect.width;
613
+ }
614
+ // Use a smaller pixel tolerance if the base element width is less than the default.
615
+ pixelTolerance = Math.min(defaultPixelTolerance, baseRect.width);
616
+ // Make sure the affixed element never detaches from the base element.
617
+ if (offset.left + pixelTolerance > baseRect.right ||
618
+ offset.left + affixedRect.width - pixelTolerance < baseRect.left) {
619
+ offset.left = originalOffsetLeft;
620
+ }
621
+ break;
622
+ case 'left':
623
+ case 'right':
624
+ // Keep the affixed element within the overflow parent.
625
+ if (offset.top < parentOffset.top) {
626
+ offset.top = parentOffset.top;
627
+ }
628
+ else if (offset.top + affixedRect.height > parentOffset.bottom) {
629
+ offset.top = parentOffset.bottom - affixedRect.height;
630
+ }
631
+ // Use a smaller pixel tolerance if the base element height is less than the default.
632
+ pixelTolerance = Math.min(defaultPixelTolerance, baseRect.height);
633
+ // Make sure the affixed element never detaches from the base element.
634
+ if (offset.top + pixelTolerance > baseRect.bottom ||
635
+ offset.top + affixedRect.height - pixelTolerance < baseRect.top) {
636
+ offset.top = originalOffsetTop;
637
+ }
638
+ break;
639
+ }
640
+ return offset;
641
+ }
642
+ getImmediateOverflowParent() {
643
+ return this.overflowParents[this.overflowParents.length - 1];
644
+ }
645
+ getAutoFitContextParent() {
646
+ const bodyElement = this.overflowParents[0];
647
+ return this.config.autoFitContext === SkyAffixAutoFitContext.OverflowParent
648
+ ? this.getImmediateOverflowParent()
649
+ : bodyElement;
650
+ }
651
+ notifyPlacementChange(placement) {
652
+ if (this.currentPlacement !== placement) {
653
+ this.currentPlacement = placement;
654
+ this._placementChange.next({
655
+ placement,
656
+ });
657
+ }
658
+ }
659
+ reset() {
660
+ this.removeScrollListeners();
661
+ this.removeResizeListener();
662
+ this._config =
663
+ this.affixedRect =
664
+ this.baseElement =
665
+ this.baseRect =
666
+ this.currentPlacement =
667
+ this.currentOffset =
668
+ this.overflowParents =
669
+ undefined;
670
+ }
671
+ isNewOffset(offset) {
672
+ if (this.currentOffset === undefined) {
673
+ this.currentOffset = offset;
674
+ return true;
675
+ }
676
+ if (this.currentOffset.top === offset.top &&
677
+ this.currentOffset.left === offset.left) {
678
+ return false;
679
+ }
680
+ this.currentOffset = offset;
681
+ return true;
682
+ }
683
+ isBaseElementVisible() {
684
+ return isOffsetPartiallyVisibleWithinParent(this.getImmediateOverflowParent(), {
685
+ top: this.baseRect.top,
686
+ left: this.baseRect.left,
687
+ right: this.baseRect.right,
688
+ bottom: this.baseRect.bottom,
689
+ }, this.config.autoFitOverflowOffset);
690
+ }
691
+ addScrollListeners() {
692
+ this.scrollListeners = this.overflowParents.map((parentElement) => {
693
+ const overflow = parentElement === document.body ? 'window' : parentElement;
694
+ return this.renderer.listen(overflow, 'scroll', () => {
695
+ this.affix();
696
+ this._overflowScroll.next();
697
+ });
698
+ });
699
+ }
700
+ addResizeListener() {
701
+ this.resizeListener = fromEvent(window, 'resize').subscribe(() => this.affix());
702
+ }
703
+ removeResizeListener() {
704
+ if (this.resizeListener) {
705
+ this.resizeListener.unsubscribe();
706
+ this.resizeListener = undefined;
707
+ }
708
+ }
709
+ removeScrollListeners() {
710
+ if (this.scrollListeners) {
711
+ // Remove renderer-generated listeners by calling the listener itself.
712
+ // https://github.com/angular/angular/issues/9368#issuecomment-227199778
713
+ this.scrollListeners.forEach((listener) => listener());
714
+ this.scrollListeners = undefined;
715
+ }
716
+ }
717
+ }
718
+
719
+ class SkyAffixService {
720
+ constructor(rendererFactory) {
721
+ this.renderer = rendererFactory.createRenderer(undefined, undefined);
722
+ }
723
+ /**
724
+ * Creates an instance of [[SkyAffixer]].
725
+ * @param affixed The element to be affixed.
726
+ */
727
+ createAffixer(affixed) {
728
+ return new SkyAffixer(affixed.nativeElement, this.renderer);
729
+ }
730
+ }
731
+ SkyAffixService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyAffixService, deps: [{ token: i0.RendererFactory2 }], target: i0.ɵɵFactoryTarget.Injectable });
732
+ SkyAffixService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyAffixService, providedIn: 'root' });
733
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyAffixService, decorators: [{
734
+ type: Injectable,
735
+ args: [{
736
+ providedIn: 'root',
737
+ }]
738
+ }], ctorParameters: function () { return [{ type: i0.RendererFactory2 }]; } });
739
+
740
+ /**
741
+ * Affixes the host element to a base element.
742
+ */
743
+ class SkyAffixDirective {
744
+ constructor(elementRef, affixService) {
745
+ this.affixService = affixService;
746
+ /**
747
+ * Fires when the affixed element's offset changes.
748
+ */
749
+ this.affixOffsetChange = new EventEmitter();
750
+ /**
751
+ * Fires when the affixed element's overflow container is scrolled.
752
+ */
753
+ this.affixOverflowScroll = new EventEmitter();
754
+ /**
755
+ * Fires when the placement value changes.
756
+ */
757
+ this.affixPlacementChange = new EventEmitter();
758
+ this.ngUnsubscribe = new Subject();
759
+ this.affixer = this.affixService.createAffixer(elementRef);
760
+ this.affixer.offsetChange
761
+ .pipe(takeUntil(this.ngUnsubscribe))
762
+ .subscribe((change) => this.affixOffsetChange.emit(change));
763
+ this.affixer.overflowScroll
764
+ .pipe(takeUntil(this.ngUnsubscribe))
765
+ .subscribe((change) => this.affixOverflowScroll.emit(change));
766
+ this.affixer.placementChange
767
+ .pipe(takeUntil(this.ngUnsubscribe))
768
+ .subscribe((change) => this.affixPlacementChange.emit(change));
769
+ }
770
+ ngOnChanges(changes) {
771
+ /* istanbul ignore else */
772
+ if (changes.affixAutoFitContext ||
773
+ changes.affixAutoFitOverflowOffset ||
774
+ changes.affixEnableAutoFit ||
775
+ changes.affixHorizontalAlignment ||
776
+ changes.affixIsSticky ||
777
+ changes.affixPlacement ||
778
+ changes.affixVerticalAlignment) {
779
+ this.updateAlignment();
780
+ }
781
+ }
782
+ ngOnDestroy() {
783
+ this.affixOffsetChange.complete();
784
+ this.affixOverflowScroll.complete();
785
+ this.affixPlacementChange.complete();
786
+ this.ngUnsubscribe.next();
787
+ this.ngUnsubscribe.complete();
788
+ this.affixer.destroy();
789
+ }
790
+ updateAlignment() {
791
+ this.affixer.affixTo(this.skyAffixTo, {
792
+ autoFitContext: this.affixAutoFitContext,
793
+ autoFitOverflowOffset: this.affixAutoFitOverflowOffset,
794
+ enableAutoFit: this.affixEnableAutoFit,
795
+ horizontalAlignment: this.affixHorizontalAlignment,
796
+ isSticky: this.affixIsSticky,
797
+ placement: this.affixPlacement,
798
+ verticalAlignment: this.affixVerticalAlignment,
799
+ });
800
+ }
801
+ }
802
+ SkyAffixDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyAffixDirective, deps: [{ token: i0.ElementRef }, { token: SkyAffixService }], target: i0.ɵɵFactoryTarget.Directive });
803
+ SkyAffixDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.2", type: SkyAffixDirective, selector: "[skyAffixTo]", inputs: { skyAffixTo: "skyAffixTo", affixAutoFitContext: "affixAutoFitContext", affixAutoFitOverflowOffset: "affixAutoFitOverflowOffset", affixEnableAutoFit: "affixEnableAutoFit", affixHorizontalAlignment: "affixHorizontalAlignment", affixIsSticky: "affixIsSticky", affixPlacement: "affixPlacement", affixVerticalAlignment: "affixVerticalAlignment" }, outputs: { affixOffsetChange: "affixOffsetChange", affixOverflowScroll: "affixOverflowScroll", affixPlacementChange: "affixPlacementChange" }, usesOnChanges: true, ngImport: i0 });
804
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyAffixDirective, decorators: [{
805
+ type: Directive,
806
+ args: [{
807
+ selector: '[skyAffixTo]',
808
+ }]
809
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: SkyAffixService }]; }, propDecorators: { skyAffixTo: [{
810
+ type: Input
811
+ }], affixAutoFitContext: [{
812
+ type: Input
813
+ }], affixAutoFitOverflowOffset: [{
814
+ type: Input
815
+ }], affixEnableAutoFit: [{
816
+ type: Input
817
+ }], affixHorizontalAlignment: [{
818
+ type: Input
819
+ }], affixIsSticky: [{
820
+ type: Input
821
+ }], affixPlacement: [{
822
+ type: Input
823
+ }], affixVerticalAlignment: [{
824
+ type: Input
825
+ }], affixOffsetChange: [{
826
+ type: Output
827
+ }], affixOverflowScroll: [{
828
+ type: Output
829
+ }], affixPlacementChange: [{
830
+ type: Output
831
+ }] } });
832
+
833
+ class SkyAffixModule {
834
+ }
835
+ SkyAffixModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyAffixModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
836
+ SkyAffixModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyAffixModule, declarations: [SkyAffixDirective], imports: [CommonModule], exports: [SkyAffixDirective] });
837
+ SkyAffixModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyAffixModule, imports: [[CommonModule]] });
838
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyAffixModule, decorators: [{
839
+ type: NgModule,
840
+ args: [{
841
+ imports: [CommonModule],
842
+ exports: [SkyAffixDirective],
843
+ declarations: [SkyAffixDirective],
844
+ }]
845
+ }] });
846
+
847
+ /**
848
+ * Represents a single item added to the dock.
849
+ */
850
+ class SkyDockItem {
851
+ /**
852
+ * @param componentInstance The item's component instance.
853
+ * @param stackOrder The assigned stack order of the docked item.
854
+ */
855
+ constructor(componentInstance, stackOrder) {
856
+ this.componentInstance = componentInstance;
857
+ this.stackOrder = stackOrder;
858
+ this._destroyed = new Subject();
859
+ }
860
+ /**
861
+ * An event that emits when the item is removed from the dock.
862
+ */
863
+ get destroyed() {
864
+ return this._destroyed.asObservable();
865
+ }
866
+ /**
867
+ * Removes the item from the dock.
868
+ */
869
+ destroy() {
870
+ this._destroyed.next();
871
+ this._destroyed.complete();
872
+ }
873
+ }
874
+
875
+ /**
876
+ * The location on the page where the dock component should be rendered.
877
+ */
878
+ var SkyDockLocation;
879
+ (function (SkyDockLocation) {
880
+ /**
881
+ * Renders the dock component before a given element.
882
+ */
883
+ SkyDockLocation[SkyDockLocation["BeforeElement"] = 0] = "BeforeElement";
884
+ /**
885
+ * Renders the dock component as the last element inside the BODY element.
886
+ */
887
+ SkyDockLocation[SkyDockLocation["BodyBottom"] = 1] = "BodyBottom";
888
+ /**
889
+ * Renders the dock component as the last element inside a given element.
890
+ */
891
+ SkyDockLocation[SkyDockLocation["ElementBottom"] = 2] = "ElementBottom";
892
+ })(SkyDockLocation || (SkyDockLocation = {}));
893
+
894
+ class MutationObserverService {
895
+ create(callback) {
896
+ return new MutationObserver(callback);
897
+ }
898
+ }
899
+ MutationObserverService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: MutationObserverService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
900
+ MutationObserverService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: MutationObserverService, providedIn: 'root' });
901
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: MutationObserverService, decorators: [{
902
+ type: Injectable,
903
+ args: [{
904
+ providedIn: 'root',
905
+ }]
906
+ }] });
907
+
908
+ /**
909
+ * @internal
910
+ */
911
+ class SkyDockDomAdapterService {
912
+ constructor(mutationService, rendererFactory) {
913
+ this.mutationService = mutationService;
914
+ this.ngUnsubscribe = new Subject();
915
+ this.renderer = rendererFactory.createRenderer(undefined, undefined);
916
+ }
917
+ ngOnDestroy() {
918
+ if (this.observer) {
919
+ this.observer.disconnect();
920
+ }
921
+ this.ngUnsubscribe.next();
922
+ if (this.styleElement) {
923
+ this.destroyStyleElement();
924
+ }
925
+ this.currentDockHeight =
926
+ this.ngUnsubscribe =
927
+ this.observer =
928
+ this.styleElement =
929
+ undefined;
930
+ }
931
+ setSticky(elementRef) {
932
+ this.renderer.addClass(elementRef.nativeElement, 'sky-dock-sticky');
933
+ }
934
+ setZIndex(zIndex, elementRef) {
935
+ this.renderer.setStyle(elementRef.nativeElement, 'z-index', zIndex);
936
+ }
937
+ unbindDock(elementRef) {
938
+ this.renderer.addClass(elementRef.nativeElement, 'sky-dock-unbound');
939
+ }
940
+ watchDomChanges(elementRef) {
941
+ this.observer = this.mutationService.create(() => {
942
+ this.adjustBodyStyles(elementRef);
943
+ });
944
+ this.observer.observe(elementRef.nativeElement, {
945
+ attributes: true,
946
+ childList: true,
947
+ characterData: true,
948
+ subtree: true,
949
+ });
950
+ fromEvent(window, 'resize')
951
+ .pipe(debounceTime(250), takeUntil(this.ngUnsubscribe))
952
+ .subscribe(() => this.adjustBodyStyles(elementRef));
953
+ }
954
+ adjustBodyStyles(elementRef) {
955
+ const dockHeight = elementRef.nativeElement.getBoundingClientRect().height;
956
+ if (dockHeight === this.currentDockHeight) {
957
+ return;
958
+ }
959
+ // Create a style element to avoid overwriting any existing inline body styles.
960
+ const styleElement = this.renderer.createElement('style');
961
+ const textNode = this.renderer.createText(`body { margin-bottom: ${dockHeight}px; }`);
962
+ // Apply a `data-` attribute to make unit testing easier.
963
+ this.renderer.setAttribute(styleElement, 'data-test-selector', 'sky-layout-dock-bottom-styles');
964
+ this.renderer.appendChild(styleElement, textNode);
965
+ this.renderer.appendChild(document.head, styleElement);
966
+ if (this.styleElement) {
967
+ this.destroyStyleElement();
968
+ }
969
+ this.currentDockHeight = dockHeight;
970
+ this.styleElement = styleElement;
971
+ }
972
+ destroyStyleElement() {
973
+ this.renderer.removeChild(document.head, this.styleElement);
974
+ }
975
+ }
976
+ SkyDockDomAdapterService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyDockDomAdapterService, deps: [{ token: MutationObserverService }, { token: i0.RendererFactory2 }], target: i0.ɵɵFactoryTarget.Injectable });
977
+ SkyDockDomAdapterService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyDockDomAdapterService });
978
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyDockDomAdapterService, decorators: [{
979
+ type: Injectable
980
+ }], ctorParameters: function () { return [{ type: MutationObserverService }, { type: i0.RendererFactory2 }]; } });
981
+
982
+ /**
983
+ * @internal
984
+ */
985
+ function sortByStackOrder(a, b) {
986
+ if (a.stackOrder > b.stackOrder) {
987
+ return -1;
988
+ }
989
+ if (a.stackOrder < b.stackOrder) {
990
+ return 1;
991
+ }
992
+ return 0;
993
+ }
994
+
995
+ /**
996
+ * @internal
997
+ */
998
+ class SkyDockComponent {
999
+ constructor(changeDetector, resolver, elementRef, injector, domAdapter) {
1000
+ this.changeDetector = changeDetector;
1001
+ this.resolver = resolver;
1002
+ this.elementRef = elementRef;
1003
+ this.injector = injector;
1004
+ this.domAdapter = domAdapter;
1005
+ this.itemRefs = [];
1006
+ }
1007
+ insertComponent(component, config = {}) {
1008
+ const factory = this.resolver.resolveComponentFactory(component);
1009
+ const injector = Injector.create({
1010
+ providers: config.providers || [],
1011
+ parent: this.injector,
1012
+ });
1013
+ const componentRef = this.target.createComponent(factory, undefined, injector);
1014
+ const stackOrder = config.stackOrder !== null && config.stackOrder !== undefined
1015
+ ? config.stackOrder
1016
+ : this.getHighestStackOrder();
1017
+ this.itemRefs.push({
1018
+ componentRef,
1019
+ stackOrder,
1020
+ });
1021
+ this.sortItemsByStackOrder();
1022
+ this.changeDetector.markForCheck();
1023
+ return {
1024
+ componentRef,
1025
+ stackOrder,
1026
+ };
1027
+ }
1028
+ removeItem(item) {
1029
+ const viewRef = item.componentRef.hostView;
1030
+ this.target.remove(this.target.indexOf(viewRef));
1031
+ const found = this.itemRefs.find((i) => i.componentRef.hostView === viewRef);
1032
+ this.itemRefs.splice(this.itemRefs.indexOf(found), 1);
1033
+ }
1034
+ setOptions(options) {
1035
+ var _a, _b;
1036
+ this.options = options;
1037
+ switch ((_a = this.options) === null || _a === void 0 ? void 0 : _a.location) {
1038
+ case SkyDockLocation.BeforeElement:
1039
+ this.domAdapter.unbindDock(this.elementRef);
1040
+ break;
1041
+ case SkyDockLocation.ElementBottom:
1042
+ this.domAdapter.setSticky(this.elementRef);
1043
+ break;
1044
+ case SkyDockLocation.BodyBottom:
1045
+ default:
1046
+ this.domAdapter.watchDomChanges(this.elementRef);
1047
+ break;
1048
+ }
1049
+ if ((_b = this.options) === null || _b === void 0 ? void 0 : _b.zIndex) {
1050
+ this.domAdapter.setZIndex(this.options.zIndex, this.elementRef);
1051
+ }
1052
+ }
1053
+ sortItemsByStackOrder() {
1054
+ this.itemRefs.sort(sortByStackOrder);
1055
+ // Reassign the correct index for each view.
1056
+ this.itemRefs.forEach((item, i) => this.target.move(item.componentRef.hostView, i));
1057
+ }
1058
+ getHighestStackOrder() {
1059
+ if (this.itemRefs.length === 0) {
1060
+ return 0;
1061
+ }
1062
+ return this.itemRefs[0].stackOrder + 1;
1063
+ }
1064
+ }
1065
+ SkyDockComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyDockComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ComponentFactoryResolver }, { token: i0.ElementRef }, { token: i0.Injector }, { token: SkyDockDomAdapterService }], target: i0.ɵɵFactoryTarget.Component });
1066
+ SkyDockComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.2", type: SkyDockComponent, selector: "sky-dock", providers: [SkyDockDomAdapterService], viewQueries: [{ propertyName: "target", first: true, predicate: ["target"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: "<ng-container #target></ng-container>\n", styles: [":host{display:flex;flex-direction:column;width:100%}:host:not(.sky-dock-unbound){position:fixed;left:0;bottom:0;right:0}:host.sky-dock-sticky{position:sticky}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1067
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyDockComponent, decorators: [{
1068
+ type: Component,
1069
+ args: [{ selector: 'sky-dock', providers: [SkyDockDomAdapterService], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container #target></ng-container>\n", styles: [":host{display:flex;flex-direction:column;width:100%}:host:not(.sky-dock-unbound){position:fixed;left:0;bottom:0;right:0}:host.sky-dock-sticky{position:sticky}\n"] }]
1070
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ComponentFactoryResolver }, { type: i0.ElementRef }, { type: i0.Injector }, { type: SkyDockDomAdapterService }]; }, propDecorators: { target: [{
1071
+ type: ViewChild,
1072
+ args: ['target', {
1073
+ read: ViewContainerRef,
1074
+ static: true,
1075
+ }]
1076
+ }] } });
1077
+
1078
+ class SkyDockModule {
1079
+ }
1080
+ SkyDockModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyDockModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1081
+ SkyDockModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyDockModule, declarations: [SkyDockComponent], imports: [CommonModule] });
1082
+ SkyDockModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyDockModule, providers: [MutationObserverService], imports: [[CommonModule]] });
1083
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyDockModule, decorators: [{
1084
+ type: NgModule,
1085
+ args: [{
1086
+ imports: [CommonModule],
1087
+ declarations: [SkyDockComponent],
1088
+ providers: [MutationObserverService],
1089
+ }]
1090
+ }] });
1091
+
1092
+ /**
1093
+ * The location on the page where the dynamic component should be rendered.
1094
+ */
1095
+ var SkyDynamicComponentLocation;
1096
+ (function (SkyDynamicComponentLocation) {
1097
+ /**
1098
+ * Renders the dynamic component before a given element.
1099
+ */
1100
+ SkyDynamicComponentLocation[SkyDynamicComponentLocation["BeforeElement"] = 0] = "BeforeElement";
1101
+ /**
1102
+ * Renders the dynamic component as the last element inside the BODY element.
1103
+ */
1104
+ SkyDynamicComponentLocation[SkyDynamicComponentLocation["BodyBottom"] = 1] = "BodyBottom";
1105
+ /**
1106
+ * Renders the dynamic component as the first element inside the BODY element.
1107
+ */
1108
+ SkyDynamicComponentLocation[SkyDynamicComponentLocation["BodyTop"] = 2] = "BodyTop";
1109
+ /**
1110
+ * Renders the dynamic component as the last element inside a given element.
1111
+ */
1112
+ SkyDynamicComponentLocation[SkyDynamicComponentLocation["ElementBottom"] = 3] = "ElementBottom";
1113
+ /**
1114
+ * Renders the dynamic component as the first element inside a given element.
1115
+ */
1116
+ SkyDynamicComponentLocation[SkyDynamicComponentLocation["ElementTop"] = 4] = "ElementTop";
1117
+ })(SkyDynamicComponentLocation || (SkyDynamicComponentLocation = {}));
1118
+
1119
+ /**
1120
+ * @internal
1121
+ */
1122
+ function getWindow() {
1123
+ return window;
1124
+ }
1125
+ /**
1126
+ * The application window reference service references the global window variable.
1127
+ * After users inject SkyAppWindowRef into a component, they can use the service to interact with
1128
+ * window properties and event handlers by referencing its nativeWindow property.
1129
+ */
1130
+ class SkyAppWindowRef {
1131
+ /**
1132
+ * References the global `window` variable.
1133
+ */
1134
+ get nativeWindow() {
1135
+ return getWindow();
1136
+ }
1137
+ }
1138
+ SkyAppWindowRef.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyAppWindowRef, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1139
+ SkyAppWindowRef.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyAppWindowRef, providedIn: 'root' });
1140
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyAppWindowRef, decorators: [{
1141
+ type: Injectable,
1142
+ args: [{
1143
+ providedIn: 'root',
1144
+ }]
1145
+ }] });
1146
+
1147
+ /**
1148
+ * Angular service for creating and rendering a dynamic component.
1149
+ */
1150
+ class SkyDynamicComponentService {
1151
+ constructor(componentFactoryResolver, applicationRef, injector, windowRef, rendererFactory) {
1152
+ this.componentFactoryResolver = componentFactoryResolver;
1153
+ this.applicationRef = applicationRef;
1154
+ this.injector = injector;
1155
+ this.windowRef = windowRef;
1156
+ // Based on suggestions from https://github.com/angular/angular/issues/17824
1157
+ // for accessing an instance of Renderer2 in a service since Renderer2 can't
1158
+ // be injected into a service. Passing undefined for both parameters results
1159
+ // in the default renderer which is what we want here.
1160
+ this.renderer = rendererFactory.createRenderer(undefined, undefined);
1161
+ }
1162
+ /**
1163
+ * Creates an instance of the specified component and adds it to the specified location
1164
+ * on the page.
1165
+ * @param options Options for creating the dynamic component.
1166
+ */
1167
+ createComponent(componentType, options) {
1168
+ options = options || {
1169
+ location: SkyDynamicComponentLocation.BodyBottom,
1170
+ };
1171
+ const componentRef = this.componentFactoryResolver
1172
+ .resolveComponentFactory(componentType)
1173
+ .create(this.injector);
1174
+ this.applicationRef.attachView(componentRef.hostView);
1175
+ const el = this.getRootNode(componentRef);
1176
+ const bodyEl = this.windowRef.nativeWindow.document.body;
1177
+ switch (options.location) {
1178
+ case SkyDynamicComponentLocation.BeforeElement:
1179
+ this.renderer.insertBefore(options.referenceEl.parentElement, el, options.referenceEl);
1180
+ break;
1181
+ case SkyDynamicComponentLocation.ElementTop:
1182
+ this.renderer.insertBefore(options.referenceEl, el, options.referenceEl.firstChild);
1183
+ break;
1184
+ case SkyDynamicComponentLocation.ElementBottom:
1185
+ this.renderer.appendChild(options.referenceEl, el);
1186
+ break;
1187
+ case SkyDynamicComponentLocation.BodyTop:
1188
+ this.renderer.insertBefore(bodyEl, el, bodyEl.firstChild);
1189
+ break;
1190
+ default:
1191
+ this.renderer.appendChild(bodyEl, el);
1192
+ break;
1193
+ }
1194
+ return componentRef;
1195
+ }
1196
+ /**
1197
+ * Removes a component ref from the page
1198
+ * @param componentRef Component ref for the component being removed
1199
+ */
1200
+ removeComponent(componentRef) {
1201
+ if (!componentRef) {
1202
+ return;
1203
+ }
1204
+ this.applicationRef.detachView(componentRef.hostView);
1205
+ componentRef.destroy();
1206
+ }
1207
+ getRootNode(componentRef) {
1208
+ // Technique for retrieving the component's root node taken from here:
1209
+ // https://malcoded.com/posts/angular-dynamic-components
1210
+ return componentRef.hostView.rootNodes[0];
1211
+ }
1212
+ }
1213
+ SkyDynamicComponentService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyDynamicComponentService, deps: [{ token: i0.ComponentFactoryResolver }, { token: i0.ApplicationRef }, { token: i0.Injector }, { token: SkyAppWindowRef }, { token: i0.RendererFactory2 }], target: i0.ɵɵFactoryTarget.Injectable });
1214
+ SkyDynamicComponentService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyDynamicComponentService, providedIn: 'any' });
1215
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyDynamicComponentService, decorators: [{
1216
+ type: Injectable,
1217
+ args: [{
1218
+ // Must be 'any' so that the component is created in the context of its module's injector.
1219
+ // If set to 'root', the component's dependency injections would only be derived from the root
1220
+ // injector and may loose context if the component is created within a lazy-loaded module.
1221
+ providedIn: 'any',
1222
+ }]
1223
+ }], ctorParameters: function () { return [{ type: i0.ComponentFactoryResolver }, { type: i0.ApplicationRef }, { type: i0.Injector }, { type: SkyAppWindowRef }, { type: i0.RendererFactory2 }]; } });
1224
+
1225
+ /**
1226
+ * This service docks components to specific areas on the page.
1227
+ */
1228
+ class SkyDockService {
1229
+ constructor(dynamicComponentService) {
1230
+ this.dynamicComponentService = dynamicComponentService;
1231
+ }
1232
+ /**
1233
+ * Returns all docked items.
1234
+ */
1235
+ get items() {
1236
+ return SkyDockService._items;
1237
+ }
1238
+ /**
1239
+ * Docks a component to the bottom of the page.
1240
+ * @param component The component to dock.
1241
+ * @param config Options that affect the docking action.
1242
+ */
1243
+ insertComponent(component, config) {
1244
+ if (!SkyDockService.dockRef) {
1245
+ this.createDock();
1246
+ }
1247
+ const itemRef = SkyDockService.dockRef.instance.insertComponent(component, config);
1248
+ const item = new SkyDockItem(itemRef.componentRef.instance, itemRef.stackOrder);
1249
+ item.destroyed.subscribe(() => {
1250
+ SkyDockService.dockRef.instance.removeItem(itemRef);
1251
+ SkyDockService._items.splice(SkyDockService._items.indexOf(item), 1);
1252
+ if (SkyDockService._items.length === 0) {
1253
+ this.destroyDock();
1254
+ }
1255
+ });
1256
+ SkyDockService._items.push(item);
1257
+ SkyDockService._items.sort(sortByStackOrder);
1258
+ return item;
1259
+ }
1260
+ /**
1261
+ * Sets options for the positioning and styling of the dock component. Since the dock service is a
1262
+ * singleton instance, these options will be applied to all components inserted into the dock. In
1263
+ * order to create a seperate dock with different options, consumers should provide a different
1264
+ * instance of the dock service.
1265
+ * @param options The options for positioning and styling
1266
+ */
1267
+ setDockOptions(options) {
1268
+ this.options = options;
1269
+ }
1270
+ createDock() {
1271
+ let dockOptions;
1272
+ if (this.options) {
1273
+ let dynamicLocation;
1274
+ switch (this.options.location) {
1275
+ case SkyDockLocation.BeforeElement:
1276
+ dynamicLocation = SkyDynamicComponentLocation.BeforeElement;
1277
+ break;
1278
+ case SkyDockLocation.ElementBottom:
1279
+ dynamicLocation = SkyDynamicComponentLocation.ElementBottom;
1280
+ break;
1281
+ default:
1282
+ dynamicLocation = SkyDynamicComponentLocation.BodyTop;
1283
+ break;
1284
+ }
1285
+ dockOptions = {
1286
+ location: dynamicLocation,
1287
+ referenceEl: this.options.referenceEl,
1288
+ };
1289
+ }
1290
+ SkyDockService.dockRef = this.dynamicComponentService.createComponent(SkyDockComponent, dockOptions);
1291
+ SkyDockService.dockRef.instance.setOptions(this.options);
1292
+ }
1293
+ destroyDock() {
1294
+ this.dynamicComponentService.removeComponent(SkyDockService.dockRef);
1295
+ SkyDockService.dockRef = undefined;
1296
+ }
1297
+ }
1298
+ SkyDockService._items = [];
1299
+ SkyDockService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyDockService, deps: [{ token: SkyDynamicComponentService }], target: i0.ɵɵFactoryTarget.Injectable });
1300
+ SkyDockService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyDockService, providedIn: 'any' });
1301
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyDockService, decorators: [{
1302
+ type: Injectable,
1303
+ args: [{
1304
+ // Must be 'any' so that the dock component is created in the context of its module's injector.
1305
+ // If set to 'root', the component's dependency injections would only be derived from the root
1306
+ // injector and may loose context if the dock was opened from within a lazy-loaded module.
1307
+ providedIn: 'any',
1308
+ }]
1309
+ }], ctorParameters: function () { return [{ type: SkyDynamicComponentService }]; } });
1310
+
1311
+ /**
1312
+ * Provides services required to create dynamic components on the page.
1313
+ * @deprecated The `SkyDynamicComponentService` no longer needs the `SkyDynamicComponentModule`.
1314
+ * The `SkyDynamicComponentModule` can be removed from your project.
1315
+ */
1316
+ class SkyDynamicComponentModule {
1317
+ }
1318
+ SkyDynamicComponentModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyDynamicComponentModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1319
+ SkyDynamicComponentModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyDynamicComponentModule });
1320
+ SkyDynamicComponentModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyDynamicComponentModule });
1321
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyDynamicComponentModule, decorators: [{
1322
+ type: NgModule,
1323
+ args: [{}]
1324
+ }] });
1325
+
1326
+ class SkyAppFormat {
1327
+ formatText(format, ...args) {
1328
+ return String(format).replace(/\{(\d+)\}/g, function (match, capture) {
1329
+ return args[parseInt(capture, 10)];
1330
+ });
1331
+ }
1332
+ }
1333
+ SkyAppFormat.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyAppFormat, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1334
+ SkyAppFormat.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyAppFormat, providedIn: 'root' });
1335
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyAppFormat, decorators: [{
1336
+ type: Injectable,
1337
+ args: [{
1338
+ providedIn: 'root',
1339
+ }]
1340
+ }] });
1341
+
1342
+ let idIndex = 0;
1343
+ function generateId() {
1344
+ idIndex++;
1345
+ return `sky-id-gen__${idIndex}`;
1346
+ }
1347
+ /**
1348
+ * Sets the element's `id` attribute to a unique ID. To reference this unique ID on other elements,
1349
+ * such as in a `label` element's `for` attribute, assign this directive to a template reference
1350
+ * variable, then use its `id` property.
1351
+ */
1352
+ class SkyIdDirective {
1353
+ constructor(elRef, renderer) {
1354
+ // Generate and apply the ID before the template is rendered
1355
+ // to avoid a changed-after-checked error.
1356
+ const id = generateId();
1357
+ renderer.setAttribute(elRef.nativeElement, 'id', id);
1358
+ this._id = id;
1359
+ }
1360
+ get id() {
1361
+ return this._id;
1362
+ }
1363
+ }
1364
+ SkyIdDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyIdDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
1365
+ SkyIdDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.2", type: SkyIdDirective, selector: "[skyId]", exportAs: ["skyId"], ngImport: i0 });
1366
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyIdDirective, decorators: [{
1367
+ type: Directive,
1368
+ args: [{
1369
+ selector: '[skyId]',
1370
+ exportAs: 'skyId',
1371
+ }]
1372
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }]; } });
1373
+
1374
+ class SkyIdModule {
1375
+ }
1376
+ SkyIdModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyIdModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1377
+ SkyIdModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyIdModule, declarations: [SkyIdDirective], exports: [SkyIdDirective] });
1378
+ SkyIdModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyIdModule });
1379
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyIdModule, decorators: [{
1380
+ type: NgModule,
1381
+ args: [{
1382
+ declarations: [SkyIdDirective],
1383
+ exports: [SkyIdDirective],
1384
+ }]
1385
+ }] });
1386
+
1387
+ /**
1388
+ * @deprecated The `SkyLogService` no longer needs the `SkyLogModule`.
1389
+ * The `SkyLogModule` can be removed from your project.
1390
+ */
1391
+ class SkyLogModule {
1392
+ }
1393
+ SkyLogModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyLogModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1394
+ SkyLogModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyLogModule });
1395
+ SkyLogModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyLogModule });
1396
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyLogModule, decorators: [{
1397
+ type: NgModule,
1398
+ args: [{}]
1399
+ }] });
1400
+
1401
+ /**
1402
+ * @internal
1403
+ */
1404
+ const SKY_LOG_LEVEL = new InjectionToken('SkyLogLevel');
1405
+
1406
+ /**
1407
+ * Logs information to the console based on the application's log level as provided by the `SKY_LOG_LEVEL` injection token. If no token is provided, only `error` logs will be shown.
1408
+ * @internal
1409
+ */
1410
+ class SkyLogService {
1411
+ constructor(formatter, applicationLogLevel) {
1412
+ this.formatter = formatter;
1413
+ this.applicationLogLevel = applicationLogLevel;
1414
+ if (!this.applicationLogLevel) {
1415
+ this.applicationLogLevel = 3 /* Error */;
1416
+ }
1417
+ }
1418
+ /**
1419
+ * Logs a deprecation warning for a class, property, function, etc. This will be logged as a console warning unless a different log level is given in the the `args` parameter.
1420
+ * @param name The name of the deprecated class, property, function, etc.
1421
+ * @param args Information about the deprecation and replacement recommendations.
1422
+ * @returns
1423
+ */
1424
+ deprecated(name, args) {
1425
+ var _a;
1426
+ return __awaiter(this, void 0, void 0, function* () {
1427
+ const logLevel = (_a = args === null || args === void 0 ? void 0 : args.logLevel) !== null && _a !== void 0 ? _a : 2 /* Warn */;
1428
+ name = this.convertStringToCode(name);
1429
+ if (this.canLog(logLevel)) {
1430
+ const localizedStrings = [];
1431
+ if (args === null || args === void 0 ? void 0 : args.deprecationMajorVersion) {
1432
+ localizedStrings.push(this.formatter.formatText('{0} is deprecated starting in SKY UX {1}.', name, args.deprecationMajorVersion.toLocaleString()));
1433
+ }
1434
+ else {
1435
+ localizedStrings.push(this.formatter.formatText('{0} is deprecated.', name));
1436
+ }
1437
+ if (args === null || args === void 0 ? void 0 : args.removalMajorVersion) {
1438
+ localizedStrings.push(this.formatter.formatText('We will remove it in version {0}.', args.removalMajorVersion.toLocaleString()));
1439
+ }
1440
+ else {
1441
+ localizedStrings.push('We will remove it in a future major version.');
1442
+ }
1443
+ if (args === null || args === void 0 ? void 0 : args.replacementRecommendation) {
1444
+ localizedStrings.push(args.replacementRecommendation);
1445
+ }
1446
+ if (args === null || args === void 0 ? void 0 : args.moreInfoUrl) {
1447
+ localizedStrings.push(this.formatter.formatText('For more information, see {0}.', args.moreInfoUrl));
1448
+ }
1449
+ this.logBasedOnLevel(logLevel, localizedStrings.join(' '));
1450
+ }
1451
+ return Promise.resolve();
1452
+ });
1453
+ }
1454
+ /**
1455
+ * Logs a console error if the application's log level is `SkyLogLevel.Error`.
1456
+ * @param message The error message
1457
+ * @param params Optional parameters for the error message.
1458
+ */
1459
+ error(message, params) {
1460
+ if (this.canLog(3 /* Error */)) {
1461
+ if (params) {
1462
+ console.error(message, ...params);
1463
+ }
1464
+ else {
1465
+ console.error(message);
1466
+ }
1467
+ }
1468
+ }
1469
+ /**
1470
+ * Logs console information if the application's log level is `SkyLogLevel.Info` or above.
1471
+ * @param message The infomational message
1472
+ * @param params Optional parameters for the informational message.
1473
+ */
1474
+ info(message, params) {
1475
+ if (this.canLog(1 /* Info */)) {
1476
+ if (params) {
1477
+ console.log(message, ...params);
1478
+ }
1479
+ else {
1480
+ console.log(message);
1481
+ }
1482
+ }
1483
+ }
1484
+ /**
1485
+ * Logs a console warning if the application's log level is `SkyLogLevel.Warn` or above.
1486
+ * @param message The warning message
1487
+ * @param params Optional parameters for the warning message.
1488
+ */
1489
+ warn(message, params) {
1490
+ if (this.canLog(2 /* Warn */)) {
1491
+ if (params) {
1492
+ console.warn(message, ...params);
1493
+ }
1494
+ else {
1495
+ console.warn(message);
1496
+ }
1497
+ }
1498
+ }
1499
+ convertStringToCode(typeString) {
1500
+ if (typeString.charAt(0) !== '`' && typeString.charAt(-1) !== '`') {
1501
+ typeString = '`' + typeString + '`';
1502
+ }
1503
+ return typeString;
1504
+ }
1505
+ canLog(intendedLogLevel) {
1506
+ return intendedLogLevel >= this.applicationLogLevel;
1507
+ }
1508
+ logBasedOnLevel(logLevel, message, params) {
1509
+ switch (logLevel) {
1510
+ case 1 /* Info */:
1511
+ this.info(message, params);
1512
+ break;
1513
+ case 2 /* Warn */:
1514
+ this.warn(message, params);
1515
+ break;
1516
+ case 3 /* Error */:
1517
+ this.error(message, params);
1518
+ break;
1519
+ }
1520
+ }
1521
+ }
1522
+ SkyLogService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyLogService, deps: [{ token: SkyAppFormat }, { token: SKY_LOG_LEVEL, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
1523
+ SkyLogService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyLogService, providedIn: 'root' });
1524
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyLogService, decorators: [{
1525
+ type: Injectable,
1526
+ args: [{
1527
+ providedIn: 'root',
1528
+ }]
1529
+ }], ctorParameters: function () {
1530
+ return [{ type: SkyAppFormat }, { type: undefined, decorators: [{
1531
+ type: Optional
1532
+ }, {
1533
+ type: Inject,
1534
+ args: [SKY_LOG_LEVEL]
1535
+ }] }];
1536
+ } });
1537
+
1538
+ /**
1539
+ * @deprecated The `SkyMediaQueryService` no longer needs the `SkyMediaQueryModule`.
1540
+ * The `SkyMediaQueryModule` can be removed from your project.
1541
+ */
1542
+ class SkyMediaQueryModule {
1543
+ }
1544
+ SkyMediaQueryModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyMediaQueryModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1545
+ SkyMediaQueryModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyMediaQueryModule });
1546
+ SkyMediaQueryModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyMediaQueryModule });
1547
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyMediaQueryModule, decorators: [{
1548
+ type: NgModule,
1549
+ args: [{}]
1550
+ }] });
1551
+
1552
+ class SkyMediaQueryService {
1553
+ constructor(zone) {
1554
+ this.zone = zone;
1555
+ this.currentSubject = new BehaviorSubject(this.current);
1556
+ this._current = SkyMediaBreakpoints.md;
1557
+ this.breakpoints = [
1558
+ {
1559
+ mediaQueryString: SkyMediaQueryService.xs,
1560
+ name: SkyMediaBreakpoints.xs,
1561
+ },
1562
+ {
1563
+ mediaQueryString: SkyMediaQueryService.sm,
1564
+ name: SkyMediaBreakpoints.sm,
1565
+ },
1566
+ {
1567
+ mediaQueryString: SkyMediaQueryService.md,
1568
+ name: SkyMediaBreakpoints.md,
1569
+ },
1570
+ {
1571
+ mediaQueryString: SkyMediaQueryService.lg,
1572
+ name: SkyMediaBreakpoints.lg,
1573
+ },
1574
+ ];
1575
+ this.mediaQueries = [];
1576
+ this.addListeners();
1577
+ }
1578
+ /**
1579
+ * Returns the current breakpoint.
1580
+ */
1581
+ get current() {
1582
+ return this._current;
1583
+ }
1584
+ ngOnDestroy() {
1585
+ this.removeListeners();
1586
+ this.currentSubject.complete();
1587
+ }
1588
+ /**
1589
+ * Subscribes to screen size changes.
1590
+ * @param listener Specifies a function that is called when breakpoints change.
1591
+ */
1592
+ subscribe(listener) {
1593
+ return this.currentSubject.subscribe({
1594
+ next: (breakpoints) => {
1595
+ listener(breakpoints);
1596
+ },
1597
+ });
1598
+ }
1599
+ /**
1600
+ * @internal
1601
+ */
1602
+ destroy() {
1603
+ this.removeListeners();
1604
+ this.currentSubject.complete();
1605
+ }
1606
+ addListeners() {
1607
+ this.mediaQueries = this.breakpoints.map((breakpoint) => {
1608
+ const mq = matchMedia(breakpoint.mediaQueryString);
1609
+ const listener = (event) => {
1610
+ // Run the check outside of Angular's change detection since Angular
1611
+ // does not wrap matchMedia listeners in NgZone.
1612
+ // See: https://blog.assaf.co/angular-2-change-detection-zones-and-an-example/
1613
+ this.zone.run(() => {
1614
+ if (event.matches) {
1615
+ this.notifyBreakpointChange(breakpoint.name);
1616
+ }
1617
+ });
1618
+ };
1619
+ mq.addListener(listener);
1620
+ if (mq.matches) {
1621
+ this.notifyBreakpointChange(breakpoint.name);
1622
+ }
1623
+ return {
1624
+ mediaQueryList: mq,
1625
+ listener,
1626
+ };
1627
+ });
1628
+ }
1629
+ removeListeners() {
1630
+ this.mediaQueries.forEach((mediaQuery) => {
1631
+ mediaQuery.mediaQueryList.removeListener(mediaQuery.listener);
1632
+ });
1633
+ this.mediaQueries = [];
1634
+ }
1635
+ notifyBreakpointChange(breakpoint) {
1636
+ this._current = breakpoint;
1637
+ this.currentSubject.next(breakpoint);
1638
+ }
1639
+ }
1640
+ /**
1641
+ * The size for the `xs` breakpoint.
1642
+ * @default "(max-width: 767px)"
1643
+ */
1644
+ SkyMediaQueryService.xs = '(max-width: 767px)';
1645
+ /**
1646
+ * The size for the `sm` breakpoint.
1647
+ * @default "(min-width: 768px) and (max-width: 991px)"
1648
+ */
1649
+ SkyMediaQueryService.sm = '(min-width: 768px) and (max-width: 991px)';
1650
+ /**
1651
+ * The size for the `md` breakpoint.
1652
+ * @default "(min-width: 992px) and (max-width: 1199px)"
1653
+ */
1654
+ SkyMediaQueryService.md = '(min-width: 992px) and (max-width: 1199px)';
1655
+ /**
1656
+ * The size for the `lg` breakpoint.
1657
+ * @default "(min-width: 1200px)"
1658
+ */
1659
+ SkyMediaQueryService.lg = '(min-width: 1200px)';
1660
+ SkyMediaQueryService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyMediaQueryService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
1661
+ SkyMediaQueryService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyMediaQueryService, providedIn: 'root' });
1662
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyMediaQueryService, decorators: [{
1663
+ type: Injectable,
1664
+ args: [{
1665
+ providedIn: 'root',
1666
+ }]
1667
+ }], ctorParameters: function () { return [{ type: i0.NgZone }]; } });
1668
+
1669
+ /**
1670
+ * NOTICE: DO NOT MODIFY THIS FILE!
1671
+ * The contents of this file were automatically generated by
1672
+ * the 'ng generate @skyux/i18n:lib-resources-module lib/modules/shared/sky-core' schematic.
1673
+ * To update this file, simply rerun the command.
1674
+ */
1675
+ const RESOURCES = {
1676
+ 'EN-US': {
1677
+ skyux_numeric_billions_symbol: { message: 'B' },
1678
+ skyux_numeric_millions_symbol: { message: 'M' },
1679
+ skyux_numeric_thousands_symbol: { message: 'K' },
1680
+ skyux_numeric_trillions_symbol: { message: 'T' },
1681
+ },
1682
+ };
1683
+ class SkyCoreResourcesProvider {
1684
+ getString(localeInfo, name) {
1685
+ return getLibStringForLocale(RESOURCES, localeInfo.locale, name);
1686
+ }
1687
+ }
1688
+ /**
1689
+ * Import into any component library module that needs to use resource strings.
1690
+ */
1691
+ class SkyCoreResourcesModule {
1692
+ }
1693
+ SkyCoreResourcesModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyCoreResourcesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1694
+ SkyCoreResourcesModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyCoreResourcesModule, exports: [SkyI18nModule] });
1695
+ SkyCoreResourcesModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyCoreResourcesModule, providers: [
1696
+ {
1697
+ provide: SKY_LIB_RESOURCES_PROVIDERS,
1698
+ useClass: SkyCoreResourcesProvider,
1699
+ multi: true,
1700
+ },
1701
+ ], imports: [SkyI18nModule] });
1702
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyCoreResourcesModule, decorators: [{
1703
+ type: NgModule,
1704
+ args: [{
1705
+ exports: [SkyI18nModule],
1706
+ providers: [
1707
+ {
1708
+ provide: SKY_LIB_RESOURCES_PROVIDERS,
1709
+ useClass: SkyCoreResourcesProvider,
1710
+ multi: true,
1711
+ },
1712
+ ],
1713
+ }]
1714
+ }] });
1715
+
1716
+ /**
1717
+ * Provides arguments for the number to format.
1718
+ */
1719
+ class SkyNumericOptions {
1720
+ constructor() {
1721
+ /**
1722
+ * Specifies the maximum number of digits after the decimal separator.
1723
+ * @default 1
1724
+ */
1725
+ this.digits = 1;
1726
+ /**
1727
+ * Specifies how to format the number. Options are `currency` or `number`.
1728
+ * @default "number"
1729
+ */
1730
+ this.format = 'number';
1731
+ /**
1732
+ * Specifies the format of the currency.
1733
+ * @default "standard"
1734
+ */
1735
+ this.currencySign = 'standard';
1736
+ /**
1737
+ * Specifies the ISO4217 currency code to use for currency formatting. If you do not specify a
1738
+ * currency code, the component uses the browser's culture to determine the currency unless your
1739
+ * SPA provides a different culture with `SkyAppLocaleProvider`.
1740
+ * @default "USD"
1741
+ */
1742
+ this.iso = 'USD';
1743
+ /**
1744
+ * Indicates whether to shorten numbers to rounded numbers and abbreviation characters
1745
+ * such as K for thousands, M for millions, B for billions, and T for trillions.
1746
+ */
1747
+ this.truncate = true;
1748
+ /**
1749
+ * Specifies the starting point after which numbers are shortened to rounded numbers
1750
+ * and abbreviation characters.
1751
+ * @default 0
1752
+ */
1753
+ this.truncateAfter = 0;
1754
+ }
1755
+ }
1756
+ /**
1757
+ * @deprecated Use `SkyNumericOptions` instead.
1758
+ */
1759
+ class NumericOptions extends SkyNumericOptions {
1760
+ }
1761
+
1762
+ // This file is mostly ported from the Angular 4.x NumberPipe in order to maintain the old
1763
+ function isNumeric(value) {
1764
+ return !isNaN(value - parseFloat(value));
1765
+ }
1766
+ function parseIntAutoRadix(text) {
1767
+ const result = parseInt(text, 10);
1768
+ /* istanbul ignore next */
1769
+ if (isNaN(result)) {
1770
+ throw new Error('Invalid integer literal when parsing ' + text);
1771
+ }
1772
+ return result;
1773
+ }
1774
+ // Need to add the following to classes which contain static methods.
1775
+ // See: https://github.com/ng-packagr/ng-packagr/issues/641
1776
+ // @dynamic
1777
+ class SkyNumberFormatUtility {
1778
+ static formatNumber(locale, value, style, digits, currency = null, currencyAsSymbol = false, currencySign) {
1779
+ if (value == null) {
1780
+ return null;
1781
+ }
1782
+ // Convert strings to numbers
1783
+ value = typeof value === 'string' && isNumeric(value) ? +value : value;
1784
+ if (typeof value !== 'number') {
1785
+ throw Error(`SkyInvalidPipeArgument: '${value}'`);
1786
+ }
1787
+ let minInt = undefined;
1788
+ let minFraction = undefined;
1789
+ let maxFraction = undefined;
1790
+ if (style !== SkyIntlNumberFormatStyle.Currency) {
1791
+ // rely on Intl default for currency
1792
+ minInt = 1;
1793
+ minFraction = 0;
1794
+ maxFraction = 3;
1795
+ }
1796
+ if (digits) {
1797
+ const parts = digits.match(this._NUMBER_FORMAT_REGEXP);
1798
+ if (parts === null) {
1799
+ throw new Error(`${digits} is not a valid digit info for number pipes`);
1800
+ }
1801
+ /* istanbul ignore else */
1802
+ if (parts[1] != null) {
1803
+ // min integer digits
1804
+ minInt = parseIntAutoRadix(parts[1]);
1805
+ }
1806
+ /* istanbul ignore else */
1807
+ if (parts[3] != null) {
1808
+ // min fraction digits
1809
+ minFraction = parseIntAutoRadix(parts[3]);
1810
+ }
1811
+ /* istanbul ignore else */
1812
+ if (parts[5] != null) {
1813
+ // max fraction digits
1814
+ maxFraction = parseIntAutoRadix(parts[5]);
1815
+ }
1816
+ }
1817
+ return SkyIntlNumberFormatter.format(value, locale, style, {
1818
+ minimumIntegerDigits: minInt,
1819
+ minimumFractionDigits: minFraction,
1820
+ maximumFractionDigits: maxFraction,
1821
+ currency: currency,
1822
+ currencyAsSymbol: currencyAsSymbol,
1823
+ currencySign: currencySign,
1824
+ });
1825
+ }
1826
+ }
1827
+ SkyNumberFormatUtility._NUMBER_FORMAT_REGEXP = /^(\d+)?\.((\d+)(-(\d+))?)?$/;
1828
+
1829
+ class SkyNumericService {
1830
+ constructor(resourcesService) {
1831
+ this.resourcesService = resourcesService;
1832
+ this.symbolIndex = [
1833
+ { value: 1e12, label: this.getSymbol('skyux_numeric_trillions_symbol') },
1834
+ { value: 1e9, label: this.getSymbol('skyux_numeric_billions_symbol') },
1835
+ { value: 1e6, label: this.getSymbol('skyux_numeric_millions_symbol') },
1836
+ { value: 1e3, label: this.getSymbol('skyux_numeric_thousands_symbol') },
1837
+ ];
1838
+ }
1839
+ /**
1840
+ * The browser's current locale.
1841
+ * @internal
1842
+ */
1843
+ set currentLocale(value) {
1844
+ this._locale = value;
1845
+ }
1846
+ get currentLocale() {
1847
+ return this._locale || 'en-US';
1848
+ }
1849
+ /**
1850
+ * Shortens with or without symbol (K/M/B/T) depending on value of number.
1851
+ * @param value The number to format.
1852
+ * @param options Format options.
1853
+ */
1854
+ formatNumber(value, options) {
1855
+ var _a;
1856
+ if (isNaN(value) || value === null) {
1857
+ return '';
1858
+ }
1859
+ const decimalPlaceRegExp = /\.0+$|(\.[0-9]*[1-9])0+$/;
1860
+ // Get the symbol for the number after rounding, since rounding could push the number
1861
+ // into a different symbol range.
1862
+ let roundedNumber = this.roundNumber(value, options.digits);
1863
+ const roundedNumberAbs = Math.abs(roundedNumber);
1864
+ let suffix = '';
1865
+ for (let i = 0; i < this.symbolIndex.length; i++) {
1866
+ let symbol = this.symbolIndex[i];
1867
+ if (options.truncate &&
1868
+ roundedNumberAbs >= options.truncateAfter &&
1869
+ roundedNumberAbs >= symbol.value) {
1870
+ roundedNumber = this.roundNumber(value / symbol.value, options.digits);
1871
+ if (Math.abs(roundedNumber) === 1000 && i > 0) {
1872
+ // Rounding caused the number to cross into the range of the next symbol.
1873
+ symbol = this.symbolIndex[i - 1];
1874
+ roundedNumber /= 1000;
1875
+ }
1876
+ suffix = symbol.label;
1877
+ break;
1878
+ }
1879
+ }
1880
+ let output = roundedNumber.toString().replace(decimalPlaceRegExp, '$1') + suffix;
1881
+ this.storeShortenSymbol(output);
1882
+ const locale = options.locale || this.currentLocale;
1883
+ let digits;
1884
+ let isDecimal;
1885
+ // Checks the string entered for format. Using toLowerCase to ignore case.
1886
+ switch ((_a = options.format) === null || _a === void 0 ? void 0 : _a.toLowerCase()) {
1887
+ // In a case where a decimal value was not shortened and
1888
+ // the digit input is 2 or higher, it forces 2 digits.
1889
+ // For example, this prevents a value like $15.50 from displaying as $15.5.
1890
+ // Note: This will need to be reviewed if we support currencies with
1891
+ // three decimal digits.
1892
+ case 'currency':
1893
+ isDecimal = value % 1 !== 0;
1894
+ if (options.minDigits) {
1895
+ digits = `1.${options.minDigits}-${options.digits}`;
1896
+ }
1897
+ else if (isDecimal && options.digits >= 2) {
1898
+ digits = `1.2-${options.digits}`;
1899
+ }
1900
+ else {
1901
+ digits = `1.0-${options.digits}`;
1902
+ }
1903
+ output = SkyNumberFormatUtility.formatNumber(locale, parseFloat(output), SkyIntlNumberFormatStyle.Currency, digits, options.iso,
1904
+ // Angular 5+ needs a string for this parameter, but Angular 4 needs a boolean.
1905
+ // To support both versions we can supply 'symbol' which will evaluate truthy for Angular 4
1906
+ // and the appropriate string value for Angular 5+.
1907
+ // See: https://angular.io/api/common/CurrencyPipe#parameters
1908
+ 'symbol', options.currencySign);
1909
+ break;
1910
+ // The following is a catch-all to ensure that if
1911
+ // anything but currency (or a future option) are entered,
1912
+ // it will be treated like a number.
1913
+ default:
1914
+ // Ensures localization of the number to ensure comma and
1915
+ // decimal separator
1916
+ if (options.minDigits) {
1917
+ digits = `1.${options.minDigits}-${options.digits}`;
1918
+ }
1919
+ else if (options.truncate) {
1920
+ digits = `1.0-${options.digits}`;
1921
+ }
1922
+ else {
1923
+ digits = `1.${options.digits}-${options.digits}`;
1924
+ }
1925
+ output = SkyNumberFormatUtility.formatNumber(locale, parseFloat(output), SkyIntlNumberFormatStyle.Decimal, digits);
1926
+ break;
1927
+ }
1928
+ if (options.truncate) {
1929
+ output = this.replaceShortenSymbol(output);
1930
+ }
1931
+ return output;
1932
+ }
1933
+ /**
1934
+ * Rounds a given number
1935
+ *
1936
+ * JS's limitation - numbers bigger than Number.MIN_SAFE_INTEGER or Number.MAX_SAFE_INTEGER
1937
+ * are not guaranteed to be represented or rounded correctly
1938
+ * @param value - value to round
1939
+ * @param precision - what precision to round with, defaults to 0 decimal places
1940
+ */
1941
+ roundNumber(value, precision = 0) {
1942
+ if (precision < 0) {
1943
+ throw new Error('SkyInvalidArgument: precision must be >= 0');
1944
+ }
1945
+ /* Sanity check - ignoring coverage but should not ignore if we make this method public */
1946
+ /* istanbul ignore next */
1947
+ if (isNaN(value) || value === null) {
1948
+ return 0;
1949
+ }
1950
+ const scaledValue = this.scaleNumberByPowerOfTen(value, precision, true);
1951
+ const scaledRoundedValue = Math.round(scaledValue);
1952
+ const unscaledRoundedValue = this.scaleNumberByPowerOfTen(scaledRoundedValue, precision, false);
1953
+ return unscaledRoundedValue;
1954
+ }
1955
+ /**
1956
+ * Scales a given number by a power of 10
1957
+ * @param value - value to scale
1958
+ * @param scalar - 10^scalar
1959
+ * @param scaleUp - whether to increase or decrease the value
1960
+ */
1961
+ scaleNumberByPowerOfTen(value, scalar, scaleUp) {
1962
+ const valueStr = value.toString().toLowerCase();
1963
+ const isExponentFormat = valueStr.includes('e');
1964
+ if (isExponentFormat) {
1965
+ const [base, exp] = valueStr.split('e');
1966
+ const newExp = scaleUp ? Number(exp) + scalar : Number(exp) - scalar;
1967
+ return Number(`${base}e${newExp}`);
1968
+ }
1969
+ else {
1970
+ const e = scaleUp ? 'e' : 'e-';
1971
+ return Number(`${value}${e}${scalar}`);
1972
+ }
1973
+ }
1974
+ /**
1975
+ * Stores the symbol added from shortening to reapply later.
1976
+ * @param value The string to derive the shorten symbol from.
1977
+ */
1978
+ storeShortenSymbol(value) {
1979
+ const symbols = this.symbolIndex.map((s) => s.label);
1980
+ const regexp = new RegExp(symbols.join('|'), 'ig');
1981
+ const match = value.match(regexp);
1982
+ this.shortSymbol = match ? match.toString() : '';
1983
+ }
1984
+ /**
1985
+ * Must have previously called storeShortenSymbol to have something to replace.
1986
+ * Finds the last number in the formatted number, gets the index of the position
1987
+ * after that character and re-inserts the symbol.
1988
+ * Works regardless of currency symbol position.
1989
+ * @param value The string to modify.
1990
+ */
1991
+ replaceShortenSymbol(value) {
1992
+ const result = /(\d)(?!.*\d)/g.exec(value);
1993
+ const pos = result.index + result.length;
1994
+ const output = value.substring(0, pos) + this.shortSymbol + value.substring(pos);
1995
+ return output;
1996
+ }
1997
+ getSymbol(key) {
1998
+ // TODO: Need to implement the async `getString` method in a breaking change.
1999
+ return this.resourcesService.getStringForLocale({ locale: 'en_US' }, key);
2000
+ }
2001
+ }
2002
+ SkyNumericService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyNumericService, deps: [{ token: i1.SkyLibResourcesService }], target: i0.ɵɵFactoryTarget.Injectable });
2003
+ SkyNumericService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyNumericService, providedIn: 'any' });
2004
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyNumericService, decorators: [{
2005
+ type: Injectable,
2006
+ args: [{
2007
+ providedIn: 'any',
2008
+ }]
2009
+ }], ctorParameters: function () { return [{ type: i1.SkyLibResourcesService }]; } });
2010
+
2011
+ /**
2012
+ * Shortens numbers to rounded numbers and abbreviation characters such as K for thousands,
2013
+ * M for millions, B for billions, and T for trillions. The pipe also formats for currency.
2014
+ * Be sure you have a space after the two curly brackets opening the pipe and
2015
+ * a space before the two curly brackets closing the pipe or it will not work.
2016
+ * Usage:
2017
+ * ```
2018
+ * {{ value | skyNumeric(config) }}
2019
+ * ```
2020
+ */
2021
+ class SkyNumericPipe {
2022
+ constructor(localeProvider, numericService, changeDetector) {
2023
+ this.localeProvider = localeProvider;
2024
+ this.numericService = numericService;
2025
+ this.changeDetector = changeDetector;
2026
+ this.ngUnsubscribe = new Subject();
2027
+ this.localeProvider
2028
+ .getLocaleInfo()
2029
+ .pipe(takeUntil(this.ngUnsubscribe))
2030
+ .subscribe((localeInfo) => {
2031
+ this.providerLocale = localeInfo.locale;
2032
+ numericService.currentLocale = this.providerLocale;
2033
+ this.changeDetector.markForCheck();
2034
+ });
2035
+ }
2036
+ ngOnDestroy() {
2037
+ this.ngUnsubscribe.next();
2038
+ this.ngUnsubscribe.complete();
2039
+ }
2040
+ transform(value, config) {
2041
+ const newCacheKey = (config ? JSON.stringify(config, Object.keys(config).sort()) : '') +
2042
+ `${value}_${(config === null || config === void 0 ? void 0 : config.locale) || this.providerLocale}`;
2043
+ /* If the value and locale are the same as the last transform then return the previous value
2044
+ instead of reformatting. */
2045
+ if (this.formattedValue && this.cacheKey === newCacheKey) {
2046
+ return this.formattedValue;
2047
+ }
2048
+ const options = new SkyNumericOptions();
2049
+ // The default number of digits is `1`. When truncate is disabled, set digits
2050
+ // to `0` to avoid the unnecessary addition of `.0` at the end of the formatted number.
2051
+ if (config && config.truncate === false && config.digits === undefined) {
2052
+ options.digits = 0;
2053
+ }
2054
+ // If the minimum digits is less than the set maximum digits then throw an error
2055
+ if (config &&
2056
+ config.minDigits &&
2057
+ config.digits &&
2058
+ config.minDigits > config.digits) {
2059
+ throw new Error('The `digits` property must be greater than or equal to the `minDigits` property');
2060
+ // If there is a minimum digits given but not a maximum then default the maximum to the minimum
2061
+ }
2062
+ else if (config && config.minDigits && !config.digits) {
2063
+ options.digits = config.minDigits;
2064
+ }
2065
+ Object.assign(options, config);
2066
+ // Assign properties for proper result caching.
2067
+ this.cacheKey = newCacheKey;
2068
+ this.formattedValue = this.numericService.formatNumber(value, options);
2069
+ return this.formattedValue;
2070
+ }
2071
+ }
2072
+ SkyNumericPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyNumericPipe, deps: [{ token: i1.SkyAppLocaleProvider }, { token: SkyNumericService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Pipe });
2073
+ SkyNumericPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyNumericPipe, name: "skyNumeric", pure: false });
2074
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyNumericPipe, decorators: [{
2075
+ type: Pipe,
2076
+ args: [{
2077
+ name: 'skyNumeric',
2078
+ pure: false,
2079
+ }]
2080
+ }], ctorParameters: function () { return [{ type: i1.SkyAppLocaleProvider }, { type: SkyNumericService }, { type: i0.ChangeDetectorRef }]; } });
2081
+
2082
+ class SkyNumericModule {
2083
+ }
2084
+ SkyNumericModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyNumericModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2085
+ SkyNumericModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyNumericModule, declarations: [SkyNumericPipe], imports: [SkyI18nModule, SkyCoreResourcesModule], exports: [SkyNumericPipe] });
2086
+ SkyNumericModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyNumericModule, providers: [SkyNumericPipe], imports: [[SkyI18nModule, SkyCoreResourcesModule]] });
2087
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyNumericModule, decorators: [{
2088
+ type: NgModule,
2089
+ args: [{
2090
+ declarations: [SkyNumericPipe],
2091
+ providers: [SkyNumericPipe],
2092
+ imports: [SkyI18nModule, SkyCoreResourcesModule],
2093
+ exports: [SkyNumericPipe],
2094
+ }]
2095
+ }] });
2096
+
2097
+ /**
2098
+ * Represents a new overlay instance. It is used to manage the "closed" state of the overlay,
2099
+ * and access any public members on the appended content component instance.
2100
+ */
2101
+ class SkyOverlayInstance {
2102
+ constructor(
2103
+ /**
2104
+ * The configuration for the overlay.
2105
+ */
2106
+ config, componentRef) {
2107
+ this.config = config;
2108
+ this.componentRef = componentRef;
2109
+ this._backdropClick = new Subject();
2110
+ this._closed = new Subject();
2111
+ this.componentRef.instance.closed.subscribe(() => {
2112
+ this._closed.next();
2113
+ this._closed.complete();
2114
+ this._backdropClick.complete();
2115
+ });
2116
+ this.componentRef.instance.backdropClick.subscribe(() => {
2117
+ this._backdropClick.next();
2118
+ });
2119
+ }
2120
+ /**
2121
+ * Emits when the overlay is clicked (but not its content).
2122
+ */
2123
+ get backdropClick() {
2124
+ return this._backdropClick.asObservable();
2125
+ }
2126
+ /**
2127
+ * Emits after the overlay is closed.
2128
+ */
2129
+ get closed() {
2130
+ return this._closed.asObservable();
2131
+ }
2132
+ /**
2133
+ * Creates and attaches a component to the overlay.
2134
+ * @param component The component to attach.
2135
+ * @param providers Custom providers to apply to the component.
2136
+ */
2137
+ attachComponent(component, providers) {
2138
+ const componentRef = this.componentRef.instance.attachComponent(component, providers);
2139
+ return componentRef.instance;
2140
+ }
2141
+ /**
2142
+ * Attaches a `TemplateRef` to the overlay.
2143
+ * @param templateRef The `TemplateRef` to attach.
2144
+ * @param context The context to provide to the template.
2145
+ */
2146
+ attachTemplate(templateRef, context) {
2147
+ this.componentRef.instance.attachTemplate(templateRef, context);
2148
+ }
2149
+ }
2150
+
2151
+ /**
2152
+ * Provides contextual information to each overlay created.
2153
+ * @internal
2154
+ */
2155
+ class SkyOverlayContext {
2156
+ constructor(config) {
2157
+ this.config = config;
2158
+ }
2159
+ }
2160
+
2161
+ /**
2162
+ * Omnibar is 1000.
2163
+ * See: https://github.com/blackbaud/auth-client/blob/master/src/omnibar/omnibar.ts#L139
2164
+ * ---
2165
+ * Modals start their z-indexes at 1040. However, each modal's z-index is a multiple of 10, so it
2166
+ * will be difficult to reliably predict a z-index that will always appear above all other
2167
+ * layers. Starting the z-index for overlays at a number much greater than modals will accommodate
2168
+ * the most reasonable of scenarios.
2169
+ * See: https://github.com/blackbaud/skyux-modals/blob/master/src/app/public/modules/modal/modal-host.service.ts#L22
2170
+ * (NOTE: It should be noted that modals do not use the overlay service, which is something we
2171
+ * should do in the near future to make sure z-indexes are predictable across all component
2172
+ * libraries.)
2173
+ */
2174
+ let uniqueZIndex = 5000;
2175
+ /**
2176
+ * @internal
2177
+ */
2178
+ class SkyOverlayComponent {
2179
+ constructor(changeDetector, resolver, injector, coreAdapter, context, router) {
2180
+ this.changeDetector = changeDetector;
2181
+ this.resolver = resolver;
2182
+ this.injector = injector;
2183
+ this.coreAdapter = coreAdapter;
2184
+ this.context = context;
2185
+ this.router = router;
2186
+ this.wrapperClass = '';
2187
+ this.enablePointerEvents = false;
2188
+ this.showBackdrop = false;
2189
+ this.zIndex = `${++uniqueZIndex}`;
2190
+ this.ngUnsubscribe = new Subject();
2191
+ this._backdropClick = new Subject();
2192
+ this._closed = new Subject();
2193
+ }
2194
+ get backdropClick() {
2195
+ return this._backdropClick.asObservable();
2196
+ }
2197
+ get closed() {
2198
+ return this._closed.asObservable();
2199
+ }
2200
+ ngOnInit() {
2201
+ this.applyConfig(this.context.config);
2202
+ setTimeout(() => {
2203
+ this.addBackdropClickListener();
2204
+ });
2205
+ if (this.context.config.closeOnNavigation) {
2206
+ this.addRouteListener();
2207
+ }
2208
+ }
2209
+ ngOnDestroy() {
2210
+ this.removeRouteListener();
2211
+ this.ngUnsubscribe.next();
2212
+ this.ngUnsubscribe.complete();
2213
+ this._backdropClick.complete();
2214
+ this._closed.next();
2215
+ this._closed.complete();
2216
+ }
2217
+ attachComponent(component, providers = []) {
2218
+ this.targetRef.clear();
2219
+ const factory = this.resolver.resolveComponentFactory(component);
2220
+ const injector = Injector.create({
2221
+ providers,
2222
+ parent: this.injector,
2223
+ });
2224
+ const componentRef = this.targetRef.createComponent(factory, undefined, injector);
2225
+ // Run an initial change detection cycle after the component has been created.
2226
+ componentRef.changeDetectorRef.detectChanges();
2227
+ return componentRef;
2228
+ }
2229
+ attachTemplate(templateRef, context) {
2230
+ this.targetRef.clear();
2231
+ return this.targetRef.createEmbeddedView(templateRef, context);
2232
+ }
2233
+ applyConfig(config) {
2234
+ this.wrapperClass = config.wrapperClass || '';
2235
+ this.showBackdrop = config.showBackdrop;
2236
+ this.enablePointerEvents = config.enablePointerEvents;
2237
+ this.changeDetector.markForCheck();
2238
+ }
2239
+ addBackdropClickListener() {
2240
+ fromEvent(window.document, 'click')
2241
+ .pipe(takeUntil(this.ngUnsubscribe))
2242
+ .subscribe((event) => {
2243
+ const isChild = this.overlayContentRef.nativeElement.contains(event.target);
2244
+ const isAbove = this.coreAdapter.isTargetAboveElement(event.target, this.overlayRef.nativeElement);
2245
+ /* istanbul ignore else */
2246
+ if (!isChild && !isAbove) {
2247
+ this._backdropClick.next();
2248
+ if (this.context.config.enableClose) {
2249
+ this._closed.next();
2250
+ }
2251
+ }
2252
+ });
2253
+ }
2254
+ addRouteListener() {
2255
+ /*istanbul ignore else*/
2256
+ if (this.router) {
2257
+ this.routerSubscription = this.router.events.subscribe((event) => {
2258
+ /* istanbul ignore else */
2259
+ if (event instanceof NavigationStart) {
2260
+ this._closed.next();
2261
+ }
2262
+ });
2263
+ }
2264
+ }
2265
+ removeRouteListener() {
2266
+ if (this.routerSubscription) {
2267
+ this.routerSubscription.unsubscribe();
2268
+ this.routerSubscription = undefined;
2269
+ }
2270
+ }
2271
+ }
2272
+ SkyOverlayComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyOverlayComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ComponentFactoryResolver }, { token: i0.Injector }, { token: SkyCoreAdapterService }, { token: SkyOverlayContext }, { token: i3.Router, optional: true }], target: i0.ɵɵFactoryTarget.Component });
2273
+ SkyOverlayComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.2", type: SkyOverlayComponent, selector: "sky-overlay", viewQueries: [{ propertyName: "overlayContentRef", first: true, predicate: ["overlayContentRef"], descendants: true, read: ElementRef, static: true }, { propertyName: "overlayRef", first: true, predicate: ["overlayRef"], descendants: true, read: ElementRef, static: true }, { propertyName: "targetRef", first: true, predicate: ["target"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: "<div\n [class]=\"wrapperClass\"\n [style.zIndex]=\"zIndex\"\n [ngClass]=\"{\n 'enable-pointer-events-pass-through': enablePointerEvents,\n 'sky-overlay': true\n }\"\n #overlayRef\n>\n <div class=\"sky-overlay-content\" #overlayContentRef>\n <ng-template #target> </ng-template>\n </div>\n <div *ngIf=\"showBackdrop\" class=\"sky-overlay-backdrop\"></div>\n</div>\n", styles: [".sky-overlay{position:fixed;top:0;right:0;left:0;bottom:0;width:100%;height:100%;display:flex;pointer-events:auto}.sky-overlay-content{position:relative;z-index:1;display:inline-flex;align-self:start;pointer-events:auto}.sky-overlay-backdrop{background:rgba(0,0,0,.5);top:0;right:0;left:0;bottom:0;width:100%;height:100%;position:absolute}.enable-pointer-events-pass-through,.enable-pointer-events-pass-through .sky-overlay-backdrop{pointer-events:none}.enable-pointer-events-pass-through .sky-overlay-content{pointer-events:auto}\n"], directives: [{ type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2274
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyOverlayComponent, decorators: [{
2275
+ type: Component,
2276
+ args: [{ selector: 'sky-overlay', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n [class]=\"wrapperClass\"\n [style.zIndex]=\"zIndex\"\n [ngClass]=\"{\n 'enable-pointer-events-pass-through': enablePointerEvents,\n 'sky-overlay': true\n }\"\n #overlayRef\n>\n <div class=\"sky-overlay-content\" #overlayContentRef>\n <ng-template #target> </ng-template>\n </div>\n <div *ngIf=\"showBackdrop\" class=\"sky-overlay-backdrop\"></div>\n</div>\n", styles: [".sky-overlay{position:fixed;top:0;right:0;left:0;bottom:0;width:100%;height:100%;display:flex;pointer-events:auto}.sky-overlay-content{position:relative;z-index:1;display:inline-flex;align-self:start;pointer-events:auto}.sky-overlay-backdrop{background:rgba(0,0,0,.5);top:0;right:0;left:0;bottom:0;width:100%;height:100%;position:absolute}.enable-pointer-events-pass-through,.enable-pointer-events-pass-through .sky-overlay-backdrop{pointer-events:none}.enable-pointer-events-pass-through .sky-overlay-content{pointer-events:auto}\n"] }]
2277
+ }], ctorParameters: function () {
2278
+ return [{ type: i0.ChangeDetectorRef }, { type: i0.ComponentFactoryResolver }, { type: i0.Injector }, { type: SkyCoreAdapterService }, { type: SkyOverlayContext }, { type: i3.Router, decorators: [{
2279
+ type: Optional
2280
+ }] }];
2281
+ }, propDecorators: { overlayContentRef: [{
2282
+ type: ViewChild,
2283
+ args: ['overlayContentRef', {
2284
+ read: ElementRef,
2285
+ static: true,
2286
+ }]
2287
+ }], overlayRef: [{
2288
+ type: ViewChild,
2289
+ args: ['overlayRef', {
2290
+ read: ElementRef,
2291
+ static: true,
2292
+ }]
2293
+ }], targetRef: [{
2294
+ type: ViewChild,
2295
+ args: ['target', {
2296
+ read: ViewContainerRef,
2297
+ static: true,
2298
+ }]
2299
+ }] } });
2300
+
2301
+ class SkyOverlayModule {
2302
+ }
2303
+ SkyOverlayModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyOverlayModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2304
+ SkyOverlayModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyOverlayModule, declarations: [SkyOverlayComponent], imports: [CommonModule] });
2305
+ SkyOverlayModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyOverlayModule, imports: [[CommonModule]] });
2306
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyOverlayModule, decorators: [{
2307
+ type: NgModule,
2308
+ args: [{
2309
+ imports: [CommonModule],
2310
+ declarations: [SkyOverlayComponent],
2311
+ }]
2312
+ }] });
2313
+
2314
+ /**
2315
+ * @internal
2316
+ */
2317
+ class SkyOverlayAdapterService {
2318
+ constructor(rendererFactory) {
2319
+ this.renderer = rendererFactory.createRenderer(undefined, undefined);
2320
+ }
2321
+ restrictBodyScroll() {
2322
+ // Create a style element to avoid overwriting any existing inline body styles.
2323
+ const styleElement = this.renderer.createElement('style');
2324
+ const textNode = this.renderer.createText('body { overflow: hidden }');
2325
+ // Apply a `data-` attribute to make unit testing easier.
2326
+ this.renderer.setAttribute(styleElement, 'data-test-selector', 'sky-overlay-restrict-scroll-styles');
2327
+ this.renderer.appendChild(styleElement, textNode);
2328
+ this.renderer.appendChild(document.head, styleElement);
2329
+ if (this.styleElement) {
2330
+ this.destroyStyleElement();
2331
+ }
2332
+ this.styleElement = styleElement;
2333
+ }
2334
+ releaseBodyScroll() {
2335
+ this.destroyStyleElement();
2336
+ }
2337
+ destroyStyleElement() {
2338
+ /* istanbul ignore else */
2339
+ if (this.styleElement.parentElement === document.head) {
2340
+ this.renderer.removeChild(document.head, this.styleElement);
2341
+ }
2342
+ }
2343
+ }
2344
+ SkyOverlayAdapterService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyOverlayAdapterService, deps: [{ token: i0.RendererFactory2 }], target: i0.ɵɵFactoryTarget.Injectable });
2345
+ SkyOverlayAdapterService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyOverlayAdapterService, providedIn: 'root' });
2346
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyOverlayAdapterService, decorators: [{
2347
+ type: Injectable,
2348
+ args: [{
2349
+ providedIn: 'root',
2350
+ }]
2351
+ }], ctorParameters: function () { return [{ type: i0.RendererFactory2 }]; } });
2352
+
2353
+ /**
2354
+ * This service is used to create new overlays.
2355
+ * @dynamic
2356
+ */
2357
+ class SkyOverlayService {
2358
+ constructor(applicationRef, componentFactoryResolver, injector, adapter) {
2359
+ this.applicationRef = applicationRef;
2360
+ this.componentFactoryResolver = componentFactoryResolver;
2361
+ this.injector = injector;
2362
+ this.adapter = adapter;
2363
+ }
2364
+ /**
2365
+ * Creates an empty overlay. Use the returned `SkyOverlayInstance` to append content.
2366
+ * @param config Configuration for the overlay.
2367
+ */
2368
+ create(config) {
2369
+ const settings = this.prepareConfig(config);
2370
+ if (settings.enableScroll === false) {
2371
+ this.adapter.restrictBodyScroll();
2372
+ }
2373
+ const componentRef = this.createOverlay(settings);
2374
+ const instance = new SkyOverlayInstance(settings, componentRef);
2375
+ instance.closed.subscribe(() => {
2376
+ // Only execute the service's close method if the instance still exists.
2377
+ // This is needed to address a race condition if the deprecated instance.close method is used instead.
2378
+ if (SkyOverlayService.overlays.indexOf(instance) > -1) {
2379
+ this.close(instance);
2380
+ }
2381
+ });
2382
+ SkyOverlayService.overlays.push(instance);
2383
+ return instance;
2384
+ }
2385
+ /**
2386
+ * Closes (and destroys) an overlay instance.
2387
+ * @param instance The instance to close.
2388
+ */
2389
+ close(instance) {
2390
+ this.destroyOverlay(instance);
2391
+ this.applicationRef.detachView(instance.componentRef.hostView);
2392
+ instance.componentRef.destroy();
2393
+ // In some cases, Angular keeps dynamically-generated component's nodes in the DOM during
2394
+ // unit tests. This can make querying difficult because the older DOM nodes still exist and
2395
+ // produce inconsistent results.
2396
+ // Angular Material's overlay appears to do the same thing:
2397
+ // https://github.com/angular/components/blob/master/src/cdk/portal/dom-portal-outlet.ts#L143-L145
2398
+ // (Ignoring coverage since this branch will only be hit by consumer unit tests.)
2399
+ const componentElement = instance.componentRef.location.nativeElement;
2400
+ /* istanbul ignore if */
2401
+ if (componentElement.parentNode !== null) {
2402
+ componentElement.parentNode.removeChild(componentElement);
2403
+ }
2404
+ }
2405
+ /**
2406
+ * Closes all overlay instances.
2407
+ */
2408
+ closeAll() {
2409
+ // The `close` event handler for each instance alters the array's length asynchronously,
2410
+ // so the only "safe" index to call is zero.
2411
+ while (SkyOverlayService.overlays.length > 0) {
2412
+ this.close(SkyOverlayService.overlays[0]);
2413
+ }
2414
+ }
2415
+ createOverlay(config) {
2416
+ const injector = Injector.create({
2417
+ parent: this.injector,
2418
+ providers: [
2419
+ {
2420
+ provide: SkyOverlayContext,
2421
+ useValue: new SkyOverlayContext(config),
2422
+ },
2423
+ ],
2424
+ });
2425
+ const componentRef = this.componentFactoryResolver
2426
+ .resolveComponentFactory(SkyOverlayComponent)
2427
+ .create(injector);
2428
+ this.applicationRef.attachView(componentRef.hostView);
2429
+ const domElem = componentRef.hostView
2430
+ .rootNodes[0];
2431
+ document.body.appendChild(domElem);
2432
+ return componentRef;
2433
+ }
2434
+ prepareConfig(config) {
2435
+ const defaults = {
2436
+ closeOnNavigation: true,
2437
+ enableClose: false,
2438
+ enablePointerEvents: false,
2439
+ enableScroll: true,
2440
+ showBackdrop: false,
2441
+ wrapperClass: '',
2442
+ };
2443
+ return Object.assign(Object.assign({}, defaults), config);
2444
+ }
2445
+ destroyOverlay(instance) {
2446
+ SkyOverlayService.overlays.splice(SkyOverlayService.overlays.indexOf(instance), 1);
2447
+ if (instance.config.enableScroll === false) {
2448
+ // Only release the body scroll if no other overlay wishes it to be disabled.
2449
+ const anotherOverlayDisablesScroll = SkyOverlayService.overlays.some((o) => !o.config.enableScroll);
2450
+ if (!anotherOverlayDisablesScroll) {
2451
+ this.adapter.releaseBodyScroll();
2452
+ }
2453
+ }
2454
+ }
2455
+ }
2456
+ SkyOverlayService.overlays = [];
2457
+ SkyOverlayService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyOverlayService, deps: [{ token: i0.ApplicationRef }, { token: i0.ComponentFactoryResolver }, { token: i0.Injector }, { token: SkyOverlayAdapterService }], target: i0.ɵɵFactoryTarget.Injectable });
2458
+ SkyOverlayService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyOverlayService, providedIn: 'root' });
2459
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyOverlayService, decorators: [{
2460
+ type: Injectable,
2461
+ args: [{
2462
+ providedIn: 'root',
2463
+ }]
2464
+ }], ctorParameters: function () { return [{ type: i0.ApplicationRef }, { type: i0.ComponentFactoryResolver }, { type: i0.Injector }, { type: SkyOverlayAdapterService }]; } });
2465
+
2466
+ class SkyPercentPipe {
2467
+ constructor(localeProvider) {
2468
+ this.localeProvider = localeProvider;
2469
+ this.defaultFormat = '1.0-2';
2470
+ this.defaultLocale = 'en-US';
2471
+ this.ngUnsubscribe = new Subject();
2472
+ this.localeProvider
2473
+ .getLocaleInfo()
2474
+ .pipe(takeUntil(this.ngUnsubscribe))
2475
+ .subscribe((localeInfo) => {
2476
+ this.defaultLocale = localeInfo.locale;
2477
+ this.updateFormattedValue();
2478
+ });
2479
+ }
2480
+ ngOnDestroy() {
2481
+ this.ngUnsubscribe.next();
2482
+ this.ngUnsubscribe.complete();
2483
+ }
2484
+ transform(value, format, locale) {
2485
+ this.value = value;
2486
+ this.format = format;
2487
+ this.locale = locale;
2488
+ this.updateFormattedValue();
2489
+ return this.formattedValue;
2490
+ }
2491
+ updateFormattedValue() {
2492
+ const locale = this.locale || this.defaultLocale;
2493
+ const format = this.format || this.defaultFormat;
2494
+ this.formattedValue = SkyNumberFormatUtility.formatNumber(locale, this.value, SkyIntlNumberFormatStyle.Percent, format);
2495
+ }
2496
+ }
2497
+ SkyPercentPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyPercentPipe, deps: [{ token: i1.SkyAppLocaleProvider }], target: i0.ɵɵFactoryTarget.Pipe });
2498
+ SkyPercentPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyPercentPipe, name: "skyPercent", pure: false });
2499
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyPercentPipe, decorators: [{
2500
+ type: Pipe,
2501
+ args: [{
2502
+ name: 'skyPercent',
2503
+ pure: false,
2504
+ }]
2505
+ }], ctorParameters: function () { return [{ type: i1.SkyAppLocaleProvider }]; } });
2506
+
2507
+ class SkyPercentPipeModule {
2508
+ }
2509
+ SkyPercentPipeModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyPercentPipeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2510
+ SkyPercentPipeModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyPercentPipeModule, declarations: [SkyPercentPipe], imports: [CommonModule, SkyCoreResourcesModule], exports: [SkyPercentPipe] });
2511
+ SkyPercentPipeModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyPercentPipeModule, providers: [SkyPercentPipe], imports: [[CommonModule, SkyCoreResourcesModule]] });
2512
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyPercentPipeModule, decorators: [{
2513
+ type: NgModule,
2514
+ args: [{
2515
+ declarations: [SkyPercentPipe],
2516
+ providers: [SkyPercentPipe],
2517
+ imports: [CommonModule, SkyCoreResourcesModule],
2518
+ exports: [SkyPercentPipe],
2519
+ }]
2520
+ }] });
2521
+
2522
+ /**
2523
+ * Service to create rxjs observables for changes to the content box dimensions of elements.
2524
+ */
2525
+ class SkyResizeObserverService {
2526
+ constructor(zone) {
2527
+ this.zone = zone;
2528
+ this._tracking = [];
2529
+ this._resizeObserver = new ResizeObserver((entries) => {
2530
+ entries.forEach((entry) => this.callback(entry));
2531
+ });
2532
+ }
2533
+ ngOnDestroy() {
2534
+ this._resizeObserver.disconnect();
2535
+ }
2536
+ /**
2537
+ * Create rxjs observable to get size changes for an element ref.
2538
+ */
2539
+ observe(element) {
2540
+ return this.observeAndTrack(element).subjectObservable;
2541
+ }
2542
+ observeAndTrack(element) {
2543
+ const checkTracking = this._tracking.findIndex((value) => {
2544
+ return !value.subject.closed && value.element === element.nativeElement;
2545
+ });
2546
+ if (checkTracking === -1) {
2547
+ this._resizeObserver.observe(element.nativeElement);
2548
+ }
2549
+ const subject = new Subject();
2550
+ const subjectObservable = subject.pipe(finalize(() => {
2551
+ // Are there any other tracking entries still watching this element?
2552
+ const checkTracking = this._tracking.findIndex((value) => {
2553
+ return (value.subject !== subject &&
2554
+ !value.subject.closed &&
2555
+ value.element === element.nativeElement);
2556
+ });
2557
+ if (checkTracking === -1) {
2558
+ this._resizeObserver.unobserve(element.nativeElement);
2559
+ }
2560
+ }));
2561
+ const tracking = {
2562
+ element: element.nativeElement,
2563
+ subject,
2564
+ subjectObservable,
2565
+ };
2566
+ this._tracking.push(tracking);
2567
+ return tracking;
2568
+ }
2569
+ callback(entry) {
2570
+ this._tracking
2571
+ .filter((value) => !(value.subject.closed || value.subject.isStopped))
2572
+ .forEach((value) => {
2573
+ /* istanbul ignore else */
2574
+ if (value.element === entry.target) {
2575
+ this.zone.run(() => {
2576
+ value.subject.next(entry);
2577
+ });
2578
+ }
2579
+ });
2580
+ }
2581
+ }
2582
+ SkyResizeObserverService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyResizeObserverService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
2583
+ SkyResizeObserverService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyResizeObserverService, providedIn: 'any' });
2584
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyResizeObserverService, decorators: [{
2585
+ type: Injectable,
2586
+ args: [{
2587
+ providedIn: 'any',
2588
+ }]
2589
+ }], ctorParameters: function () { return [{ type: i0.NgZone }]; } });
2590
+
2591
+ /**
2592
+ * Acts like `SkyMediaQueryService` for a container element, emitting the same responsive breakpoints.
2593
+ */
2594
+ class SkyResizeObserverMediaQueryService {
2595
+ constructor(resizeObserverService) {
2596
+ this.resizeObserverService = resizeObserverService;
2597
+ this._breakpoints = [
2598
+ {
2599
+ check: (width) => width <= 767,
2600
+ name: SkyMediaBreakpoints.xs,
2601
+ },
2602
+ {
2603
+ check: (width) => width > 767 && width <= 991,
2604
+ name: SkyMediaBreakpoints.sm,
2605
+ },
2606
+ {
2607
+ check: (width) => width > 991 && width <= 1199,
2608
+ name: SkyMediaBreakpoints.md,
2609
+ },
2610
+ {
2611
+ check: (width) => width > 1199,
2612
+ name: SkyMediaBreakpoints.lg,
2613
+ },
2614
+ ];
2615
+ this._currentBreakpointObservable = new ReplaySubject(1);
2616
+ this._stopListening = new Subject();
2617
+ this._stopListening.subscribe(() => {
2618
+ this._target = undefined;
2619
+ this.updateBreakpoint(undefined);
2620
+ });
2621
+ }
2622
+ /**
2623
+ * Returns the current breakpoint.
2624
+ */
2625
+ get current() {
2626
+ return this._currentBreakpoint;
2627
+ }
2628
+ ngOnDestroy() {
2629
+ this._stopListening.next();
2630
+ this._currentBreakpoint = undefined;
2631
+ this._stopListening.complete();
2632
+ this._currentBreakpointObservable.complete();
2633
+ }
2634
+ /**
2635
+ * @internal
2636
+ */
2637
+ destroy() {
2638
+ this.ngOnDestroy();
2639
+ }
2640
+ /**
2641
+ * Sets the container element to watch. The `SkyResizeObserverMediaQueryService` will only observe one element at a
2642
+ * time. Any previous subscriptions will be unsubscribed when a new element is observed.
2643
+ */
2644
+ observe(element) {
2645
+ if (this._target) {
2646
+ if (this._target === element) {
2647
+ return this;
2648
+ }
2649
+ this._stopListening.next();
2650
+ }
2651
+ this._target = element;
2652
+ const width = element.nativeElement.offsetWidth;
2653
+ if (width) {
2654
+ const breakpoint = this.checkBreakpoint(width);
2655
+ this.updateBreakpoint(breakpoint);
2656
+ }
2657
+ this.resizeObserverService
2658
+ .observe(element)
2659
+ .pipe(takeUntil(this._stopListening))
2660
+ .subscribe((value) => {
2661
+ const breakpoint = this.checkBreakpoint(value.contentRect.width);
2662
+ /* istanbul ignore else */
2663
+ if (breakpoint !== this._currentBreakpoint) {
2664
+ this.updateBreakpoint(breakpoint);
2665
+ }
2666
+ });
2667
+ return this;
2668
+ }
2669
+ /**
2670
+ * Stop watching the container element.
2671
+ */
2672
+ unobserve() {
2673
+ this._stopListening.next();
2674
+ }
2675
+ /**
2676
+ * Subscribes to element size changes that cross breakpoints.
2677
+ */
2678
+ subscribe(listener) {
2679
+ return this._currentBreakpointObservable
2680
+ .pipe(takeUntil(this._stopListening))
2681
+ .subscribe(listener);
2682
+ }
2683
+ updateBreakpoint(breakpoint) {
2684
+ this._currentBreakpoint = breakpoint;
2685
+ this._currentBreakpointObservable.next(breakpoint);
2686
+ }
2687
+ checkBreakpoint(width) {
2688
+ var _a;
2689
+ return (_a = this._breakpoints.find((breakpoint) => breakpoint.check(width))) === null || _a === void 0 ? void 0 : _a.name;
2690
+ }
2691
+ }
2692
+ SkyResizeObserverMediaQueryService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyResizeObserverMediaQueryService, deps: [{ token: SkyResizeObserverService }], target: i0.ɵɵFactoryTarget.Injectable });
2693
+ SkyResizeObserverMediaQueryService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyResizeObserverMediaQueryService, providedIn: 'any' });
2694
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyResizeObserverMediaQueryService, decorators: [{
2695
+ type: Injectable,
2696
+ args: [{
2697
+ providedIn: 'any',
2698
+ }]
2699
+ }], ctorParameters: function () { return [{ type: SkyResizeObserverService }]; } });
2700
+
2701
+ function notifySubscribers(subscribers, item) {
2702
+ for (const subscriber of subscribers) {
2703
+ subscriber.next(item);
2704
+ }
2705
+ }
2706
+ class SkyScrollableHostService {
2707
+ constructor(mutationObserverSvc, windowRef) {
2708
+ this.mutationObserverSvc = mutationObserverSvc;
2709
+ this.windowRef = windowRef;
2710
+ }
2711
+ /**
2712
+ * Returns the given element's current scrollable host
2713
+ * @param elementRef The element whose scrollable host is being requested
2714
+ * @returns The current scrollable host
2715
+ */
2716
+ getScrollableHost(elementRef) {
2717
+ return this.findScrollableHost(elementRef.nativeElement);
2718
+ }
2719
+ /**
2720
+ * Returns an observable which emits the given element's current scrollable host
2721
+ * @param elementRef The element whose scrollable host is being requested
2722
+ * @param completionObservable An observable which alerts the internal observers that they should complete
2723
+ * @returns An observable which emits the current scrollable host
2724
+ * @internal
2725
+ */
2726
+ watchScrollableHost(elementRef) {
2727
+ const subscribers = [];
2728
+ let parentMutationObserver;
2729
+ let documentHiddenElementMutationObserver;
2730
+ return new Observable((subscriber) => {
2731
+ subscribers.push(subscriber);
2732
+ let scrollableHost = this.findScrollableHost(elementRef.nativeElement);
2733
+ if (subscribers.length === 1) {
2734
+ parentMutationObserver = this.mutationObserverSvc.create(() => {
2735
+ const newScrollableHost = this.findScrollableHost(elementRef.nativeElement);
2736
+ if (newScrollableHost !== scrollableHost &&
2737
+ elementRef.nativeElement.offsetParent) {
2738
+ scrollableHost = newScrollableHost;
2739
+ this.observeForScrollableHostChanges(scrollableHost, parentMutationObserver);
2740
+ notifySubscribers(subscribers, scrollableHost);
2741
+ }
2742
+ });
2743
+ this.observeForScrollableHostChanges(scrollableHost, parentMutationObserver);
2744
+ documentHiddenElementMutationObserver = this.mutationObserverSvc.create(() => {
2745
+ if (scrollableHost && !elementRef.nativeElement.offsetParent) {
2746
+ scrollableHost = undefined;
2747
+ this.observeForScrollableHostChanges(scrollableHost, parentMutationObserver);
2748
+ notifySubscribers(subscribers, scrollableHost);
2749
+ }
2750
+ });
2751
+ this.observeDocumentHiddenElementChanges(documentHiddenElementMutationObserver);
2752
+ }
2753
+ subscriber.next(scrollableHost);
2754
+ subscriber.add(() => {
2755
+ const subIndex = subscribers.indexOf(subscriber);
2756
+ /* sanity check */
2757
+ /* istanbul ignore else */
2758
+ if (subIndex >= 0) {
2759
+ subscribers.splice(subIndex, 1);
2760
+ }
2761
+ if (subscribers.length === 0) {
2762
+ documentHiddenElementMutationObserver.disconnect();
2763
+ parentMutationObserver.disconnect();
2764
+ }
2765
+ });
2766
+ });
2767
+ }
2768
+ /**
2769
+ * Returns an observable which emits whenever the element's scrollable host emits a scroll event. The observable will always emit the scroll events from the elements current scrollable host and will update based on any scrollable host changes. The observable will also emit once whenever the scrollable host changes.
2770
+ * @param elementRef The element whose scrollable host scroll events are being requested
2771
+ * @param completionObservable An observable which alerts the internal observers that they should complete
2772
+ * @returns An observable which emits when the elements scrollable host is scrolled or is changed
2773
+ */
2774
+ watchScrollableHostScrollEvents(elementRef) {
2775
+ const subscribers = [];
2776
+ let scrollableHost;
2777
+ let newScrollableHostObservable = new Subject();
2778
+ let scrollableHostSubscription;
2779
+ let scrollEventSubscription;
2780
+ return new Observable((subscriber) => {
2781
+ subscribers.push(subscriber);
2782
+ if (subscribers.length === 1) {
2783
+ scrollableHostSubscription = this.watchScrollableHost(elementRef).subscribe((newScrollableHost) => {
2784
+ newScrollableHostObservable.next();
2785
+ newScrollableHostObservable.complete();
2786
+ if (scrollableHost && scrollableHost !== newScrollableHost) {
2787
+ notifySubscribers(subscribers);
2788
+ }
2789
+ scrollableHost = newScrollableHost;
2790
+ newScrollableHostObservable = new Subject();
2791
+ if (newScrollableHost) {
2792
+ scrollEventSubscription = fromEvent(newScrollableHost, 'scroll')
2793
+ .pipe(takeUntil(newScrollableHostObservable))
2794
+ .subscribe(() => {
2795
+ notifySubscribers(subscribers);
2796
+ });
2797
+ }
2798
+ });
2799
+ }
2800
+ subscriber.add(() => {
2801
+ const subIndex = subscribers.indexOf(subscriber);
2802
+ /* sanity check */
2803
+ /* istanbul ignore else */
2804
+ if (subIndex >= 0) {
2805
+ subscribers.splice(subIndex, 1);
2806
+ }
2807
+ if (subscribers.length === 0) {
2808
+ scrollableHostSubscription.unsubscribe();
2809
+ scrollEventSubscription.unsubscribe();
2810
+ newScrollableHostObservable.complete();
2811
+ }
2812
+ });
2813
+ });
2814
+ }
2815
+ findScrollableHost(element) {
2816
+ const regex = /(auto|scroll)/;
2817
+ const windowObj = this.windowRef.nativeWindow;
2818
+ const bodyObj = windowObj.document.body;
2819
+ /* Sanity check */
2820
+ if (!element) {
2821
+ return windowObj;
2822
+ }
2823
+ let style = windowObj.getComputedStyle(element);
2824
+ let parent = element;
2825
+ do {
2826
+ parent = parent.parentNode;
2827
+ /* Sanity check for if this function is called for an element which has been removed from the DOM */
2828
+ if (!(parent instanceof HTMLElement)) {
2829
+ return windowObj;
2830
+ }
2831
+ style = windowObj.getComputedStyle(parent);
2832
+ } while (!regex.test(style.overflow) &&
2833
+ !regex.test(style.overflowY) &&
2834
+ parent !== bodyObj);
2835
+ if (parent === bodyObj) {
2836
+ return windowObj;
2837
+ }
2838
+ return parent;
2839
+ }
2840
+ observeDocumentHiddenElementChanges(mutationObserver) {
2841
+ mutationObserver.observe(document.documentElement, {
2842
+ attributes: true,
2843
+ attributeFilter: ['class', 'style', 'hidden'],
2844
+ childList: true,
2845
+ subtree: true,
2846
+ });
2847
+ }
2848
+ observeForScrollableHostChanges(element, mutationObserver) {
2849
+ mutationObserver.disconnect();
2850
+ if (element instanceof HTMLElement) {
2851
+ mutationObserver.observe(element, {
2852
+ attributes: true,
2853
+ attributeFilter: ['class', 'style'],
2854
+ childList: true,
2855
+ subtree: true,
2856
+ });
2857
+ }
2858
+ else {
2859
+ mutationObserver.observe(document.documentElement, {
2860
+ attributes: true,
2861
+ attributeFilter: ['class', 'style'],
2862
+ childList: true,
2863
+ subtree: true,
2864
+ });
2865
+ }
2866
+ }
2867
+ }
2868
+ SkyScrollableHostService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyScrollableHostService, deps: [{ token: MutationObserverService }, { token: SkyAppWindowRef }], target: i0.ɵɵFactoryTarget.Injectable });
2869
+ SkyScrollableHostService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyScrollableHostService, providedIn: 'root' });
2870
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyScrollableHostService, decorators: [{
2871
+ type: Injectable,
2872
+ args: [{
2873
+ providedIn: 'root',
2874
+ }]
2875
+ }], ctorParameters: function () { return [{ type: MutationObserverService }, { type: SkyAppWindowRef }]; } });
2876
+
2877
+ /**
2878
+ * Provides a method for setting a formatted title on the current window.
2879
+ */
2880
+ class SkyAppTitleService {
2881
+ constructor(title) {
2882
+ this.title = title;
2883
+ }
2884
+ /**
2885
+ * Sets the title on the current window.
2886
+ * @param args An array of title parts. The parts will be concatenated with a hyphen between
2887
+ * each part.
2888
+ */
2889
+ setTitle(args) {
2890
+ if (args && args.titleParts) {
2891
+ this.title.setTitle(args.titleParts.join(' - '));
2892
+ }
2893
+ }
2894
+ }
2895
+ SkyAppTitleService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyAppTitleService, deps: [{ token: i1$1.Title }], target: i0.ɵɵFactoryTarget.Injectable });
2896
+ SkyAppTitleService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyAppTitleService, providedIn: 'root' });
2897
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyAppTitleService, decorators: [{
2898
+ type: Injectable,
2899
+ args: [{
2900
+ providedIn: 'root',
2901
+ }]
2902
+ }], ctorParameters: function () { return [{ type: i1$1.Title }]; } });
2903
+
2904
+ class SkyUIConfigService {
2905
+ getConfig(key, defaultConfig) {
2906
+ return of(defaultConfig);
2907
+ }
2908
+ /* istanbul ignore next */
2909
+ setConfig(key, value) {
2910
+ return of({});
2911
+ }
2912
+ }
2913
+ SkyUIConfigService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyUIConfigService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2914
+ SkyUIConfigService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyUIConfigService, providedIn: 'root' });
2915
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyUIConfigService, decorators: [{
2916
+ type: Injectable,
2917
+ args: [{
2918
+ providedIn: 'root',
2919
+ }]
2920
+ }] });
2921
+
2922
+ class SkyViewkeeperHostOptions {
2923
+ }
2924
+ SkyViewkeeperHostOptions.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyViewkeeperHostOptions, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2925
+ SkyViewkeeperHostOptions.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyViewkeeperHostOptions });
2926
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyViewkeeperHostOptions, decorators: [{
2927
+ type: Injectable
2928
+ }] });
2929
+
2930
+ const CLS_VIEWKEEPER_FIXED = 'sky-viewkeeper-fixed';
2931
+ const EVT_AFTER_VIEWKEEPER_SYNC = 'afterViewkeeperSync';
2932
+ let styleEl;
2933
+ let nextIdIndex;
2934
+ function ensureStyleEl() {
2935
+ if (!styleEl) {
2936
+ styleEl = document.createElement('style');
2937
+ const css = document.createTextNode(`
2938
+ .${CLS_VIEWKEEPER_FIXED} {
2939
+ position: fixed !important;
2940
+ z-index: 999;
2941
+ opacity: 0.95;
2942
+ overflow: hidden;
2943
+ }
2944
+
2945
+ .sky-theme-modern .${CLS_VIEWKEEPER_FIXED} {
2946
+ box-shadow: 0px 1px 8px -1px rgba(0, 0, 0, 0.3);
2947
+ opacity: initial;
2948
+ }
2949
+ `);
2950
+ styleEl.appendChild(css);
2951
+ document.head.appendChild(styleEl);
2952
+ }
2953
+ }
2954
+ function nextId() {
2955
+ nextIdIndex = (nextIdIndex || 0) + 1;
2956
+ return 'viewkeeper-' + nextIdIndex;
2957
+ }
2958
+ function getOffset(el, scrollableHost) {
2959
+ const rect = el.getBoundingClientRect();
2960
+ const parent = scrollableHost ? scrollableHost : document.documentElement;
2961
+ return {
2962
+ top: rect.top + parent.scrollTop,
2963
+ left: rect.left + parent.scrollLeft,
2964
+ };
2965
+ }
2966
+ function px(value) {
2967
+ let pxValue = value ? value.toString() : '';
2968
+ if (typeof value === 'number') {
2969
+ pxValue = value + 'px';
2970
+ }
2971
+ return pxValue;
2972
+ }
2973
+ function setElPosition(el, left, top, width, marginTop) {
2974
+ el.style.top = px(top);
2975
+ el.style.left = px(left);
2976
+ el.style.marginTop = px(marginTop);
2977
+ /*istanbul ignore else*/
2978
+ /* sanity check */
2979
+ if (width !== null) {
2980
+ el.style.width = px(width);
2981
+ }
2982
+ }
2983
+ function getHeightWithMargin(el) {
2984
+ const computedStyle = getComputedStyle(el);
2985
+ return (el.offsetHeight +
2986
+ parseInt(computedStyle.marginTop, 10) +
2987
+ parseInt(computedStyle.marginBottom, 10));
2988
+ }
2989
+ function createCustomEvent(name) {
2990
+ const evt = document.createEvent('CustomEvent');
2991
+ evt.initCustomEvent(name, false, false, undefined);
2992
+ return evt;
2993
+ }
2994
+ class SkyViewkeeper {
2995
+ constructor(options) {
2996
+ options = options || /* istanbul ignore next */ {};
2997
+ this.setWidth = options.setWidth;
2998
+ this.id = nextId();
2999
+ this.el = options.el;
3000
+ this.boundaryEl = options.boundaryEl;
3001
+ this.scrollableHost = options.scrollableHost;
3002
+ this.verticalOffset = options.verticalOffset || 0;
3003
+ this.verticalOffsetEl = options.verticalOffsetEl;
3004
+ this.viewportMarginTop = options.viewportMarginTop || 0;
3005
+ this.syncElPositionHandler = () => this.syncElPosition();
3006
+ if (this.verticalOffsetEl) {
3007
+ this.verticalOffsetEl.addEventListener(EVT_AFTER_VIEWKEEPER_SYNC, this.syncElPositionHandler);
3008
+ }
3009
+ window.addEventListener('scroll', this.syncElPositionHandler, true);
3010
+ window.addEventListener('resize', this.syncElPositionHandler);
3011
+ window.addEventListener('orientationchange', this.syncElPositionHandler);
3012
+ ensureStyleEl();
3013
+ this.syncElPosition();
3014
+ }
3015
+ set viewportMarginTop(margin) {
3016
+ this._viewportMarginTop = margin;
3017
+ }
3018
+ get viewportMarginTop() {
3019
+ if (this.scrollableHost) {
3020
+ return 0;
3021
+ }
3022
+ else {
3023
+ return this._viewportMarginTop;
3024
+ }
3025
+ }
3026
+ syncElPosition() {
3027
+ const verticalOffset = this.calculateVerticalOffset();
3028
+ // When the element isn't visible, its size can't be calculated, so don't attempt syncing position in this case.
3029
+ if (this.el.offsetWidth === 0 && this.el.offsetHeight === 0) {
3030
+ return;
3031
+ }
3032
+ const boundaryInfo = this.getBoundaryInfo();
3033
+ const fixedStyles = this.getFixedStyles(boundaryInfo, verticalOffset);
3034
+ const doFixEl = this.shouldFixEl(boundaryInfo, verticalOffset);
3035
+ if (this.needsUpdating(doFixEl, fixedStyles)) {
3036
+ if (doFixEl) {
3037
+ this.fixEl(boundaryInfo, fixedStyles);
3038
+ }
3039
+ else {
3040
+ this.unfixEl();
3041
+ }
3042
+ }
3043
+ const evt = createCustomEvent(EVT_AFTER_VIEWKEEPER_SYNC);
3044
+ this.el.dispatchEvent(evt);
3045
+ }
3046
+ destroy() {
3047
+ if (!this.isDestroyed) {
3048
+ window.removeEventListener('scroll', this.syncElPositionHandler, true);
3049
+ window.removeEventListener('resize', this.syncElPositionHandler);
3050
+ window.removeEventListener('orientationchange', this.syncElPositionHandler);
3051
+ this.unfixEl();
3052
+ if (this.verticalOffsetEl) {
3053
+ this.verticalOffsetEl.removeEventListener(EVT_AFTER_VIEWKEEPER_SYNC, this.syncElPositionHandler);
3054
+ }
3055
+ this.el = this.boundaryEl = this.verticalOffsetEl = undefined;
3056
+ this.isDestroyed = true;
3057
+ }
3058
+ }
3059
+ getSpacerId() {
3060
+ return this.id + '-spacer';
3061
+ }
3062
+ unfixEl() {
3063
+ const spacerEl = document.getElementById(this.getSpacerId());
3064
+ if (spacerEl) {
3065
+ spacerEl.parentElement.removeChild(spacerEl);
3066
+ }
3067
+ this.el.classList.remove(CLS_VIEWKEEPER_FIXED);
3068
+ this.currentElFixedLeft =
3069
+ this.currentElFixedTop =
3070
+ this.currentElFixedWidth =
3071
+ undefined;
3072
+ let width;
3073
+ if (this.setWidth) {
3074
+ width = 'auto';
3075
+ }
3076
+ setElPosition(this.el, '', '', width, '');
3077
+ }
3078
+ calculateVerticalOffset() {
3079
+ let offset = this.verticalOffset;
3080
+ if (this.verticalOffsetEl) {
3081
+ const verticalOffsetElTopStyle = this.verticalOffsetEl.style.top;
3082
+ const verticalOffsetElTop = parseInt(verticalOffsetElTopStyle, 10) || 0;
3083
+ offset += this.verticalOffsetEl.offsetHeight + verticalOffsetElTop;
3084
+ }
3085
+ else if (this.scrollableHost) {
3086
+ offset += this.scrollableHost.getBoundingClientRect().top;
3087
+ }
3088
+ return offset;
3089
+ }
3090
+ shouldFixEl(boundaryInfo, verticalOffset) {
3091
+ let anchorTop;
3092
+ if (boundaryInfo.spacerEl) {
3093
+ anchorTop = getOffset(boundaryInfo.spacerEl, this.scrollableHost).top;
3094
+ }
3095
+ else {
3096
+ anchorTop = getOffset(this.el, this.scrollableHost).top;
3097
+ }
3098
+ const doFixEl = boundaryInfo.scrollTop + verticalOffset + this.viewportMarginTop >
3099
+ anchorTop;
3100
+ return doFixEl;
3101
+ }
3102
+ getFixedStyles(boundaryInfo, verticalOffset) {
3103
+ // If the element needs to be fixed, this will calculate its position. The position
3104
+ // will be 0 (fully visible) unless the user is scrolling the boundary out of view.
3105
+ // In that case, the element should begin to scroll out of view with the
3106
+ // rest of the boundary by setting its top position to a negative value.
3107
+ const elFixedTop = Math.min(boundaryInfo.boundaryBottom -
3108
+ boundaryInfo.elHeight -
3109
+ boundaryInfo.scrollTop, verticalOffset);
3110
+ const elFixedWidth = boundaryInfo.boundaryEl.getBoundingClientRect().width;
3111
+ const elFixedLeft = boundaryInfo.boundaryOffset.left - boundaryInfo.scrollLeft;
3112
+ return {
3113
+ elFixedLeft,
3114
+ elFixedTop,
3115
+ elFixedWidth,
3116
+ };
3117
+ }
3118
+ needsUpdating(doFixEl, fixedStyles) {
3119
+ if ((doFixEl &&
3120
+ this.currentElFixedLeft === fixedStyles.elFixedLeft &&
3121
+ this.currentElFixedTop === fixedStyles.elFixedTop &&
3122
+ this.currentElFixedWidth === fixedStyles.elFixedWidth) ||
3123
+ (!doFixEl &&
3124
+ !(this.currentElFixedLeft !== undefined &&
3125
+ this.currentElFixedLeft !== null))) {
3126
+ // The element is either currently fixed and its position and width do not need
3127
+ // to change, or the element is not currently fixed and does not need to be fixed.
3128
+ // No changes are needed.
3129
+ return false;
3130
+ }
3131
+ return true;
3132
+ }
3133
+ fixEl(boundaryInfo, fixedStyles) {
3134
+ const el = this.el;
3135
+ /* istanbul ignore else */
3136
+ /* sanity check */
3137
+ if (!boundaryInfo.spacerEl) {
3138
+ const spacerHeight = boundaryInfo.elHeight;
3139
+ const spacerEl = document.createElement('div');
3140
+ spacerEl.id = boundaryInfo.spacerId;
3141
+ spacerEl.style.height = px(spacerHeight);
3142
+ el.parentNode.insertBefore(spacerEl, el.nextSibling);
3143
+ }
3144
+ el.classList.add(CLS_VIEWKEEPER_FIXED);
3145
+ this.currentElFixedTop = fixedStyles.elFixedTop;
3146
+ this.currentElFixedLeft = fixedStyles.elFixedLeft;
3147
+ this.currentElFixedWidth = fixedStyles.elFixedWidth;
3148
+ let width;
3149
+ if (this.setWidth) {
3150
+ width = fixedStyles.elFixedWidth;
3151
+ }
3152
+ setElPosition(el, fixedStyles.elFixedLeft, fixedStyles.elFixedTop, width, this.viewportMarginTop);
3153
+ }
3154
+ getBoundaryInfo() {
3155
+ const spacerId = this.getSpacerId();
3156
+ const spacerEl = document.getElementById(spacerId);
3157
+ const boundaryEl = this.boundaryEl;
3158
+ const boundaryOffset = getOffset(boundaryEl, this.scrollableHost);
3159
+ const boundaryTop = boundaryOffset.top;
3160
+ const boundaryBottom = boundaryTop + boundaryEl.getBoundingClientRect().height;
3161
+ const scrollLeft = this.scrollableHost
3162
+ ? this.scrollableHost.scrollLeft
3163
+ : document.documentElement.scrollLeft;
3164
+ const scrollTop = this.scrollableHost
3165
+ ? this.scrollableHost.scrollTop
3166
+ : document.documentElement.scrollTop;
3167
+ const elHeight = getHeightWithMargin(this.el);
3168
+ return {
3169
+ boundaryBottom,
3170
+ boundaryOffset,
3171
+ boundaryEl,
3172
+ elHeight,
3173
+ scrollLeft,
3174
+ scrollTop,
3175
+ spacerId,
3176
+ spacerEl,
3177
+ };
3178
+ }
3179
+ }
3180
+
3181
+ /**
3182
+ * Provides methods for creating and destroying viewkeeper instances.
3183
+ */
3184
+ class SkyViewkeeperService {
3185
+ constructor(hostOptions) {
3186
+ this.hostOptions = hostOptions;
3187
+ }
3188
+ /**
3189
+ *
3190
+ * @param options Creates a viewkeeper instance, applying host options where applicable.
3191
+ */
3192
+ create(options) {
3193
+ options = Object.assign({}, this.hostOptions || {}, options);
3194
+ return new SkyViewkeeper(options);
3195
+ }
3196
+ /**
3197
+ * Destroys a viewkeeper instance.
3198
+ * @param vk Viewkeeper instance to destroy.
3199
+ */
3200
+ destroy(vk) {
3201
+ vk.destroy();
3202
+ }
3203
+ }
3204
+ SkyViewkeeperService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyViewkeeperService, deps: [{ token: SkyViewkeeperHostOptions, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
3205
+ SkyViewkeeperService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyViewkeeperService, providedIn: 'root' });
3206
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyViewkeeperService, decorators: [{
3207
+ type: Injectable,
3208
+ args: [{
3209
+ providedIn: 'root',
3210
+ }]
3211
+ }], ctorParameters: function () {
3212
+ return [{ type: SkyViewkeeperHostOptions, decorators: [{
3213
+ type: Optional
3214
+ }] }];
3215
+ } });
3216
+
3217
+ class SkyViewkeeperDirective {
3218
+ constructor(el, mutationObserverSvc, viewkeeperSvc, scrollableHostService) {
3219
+ this.el = el;
3220
+ this.mutationObserverSvc = mutationObserverSvc;
3221
+ this.viewkeeperSvc = viewkeeperSvc;
3222
+ this.scrollableHostService = scrollableHostService;
3223
+ this.viewkeepers = [];
3224
+ this.scrollableHostWatchUnsubscribe = undefined;
3225
+ }
3226
+ set skyViewkeeper(value) {
3227
+ this._skyViewkeeper = value;
3228
+ this.detectElements();
3229
+ }
3230
+ get skyViewkeeper() {
3231
+ return this._skyViewkeeper;
3232
+ }
3233
+ ngOnInit() {
3234
+ this.observer = this.mutationObserverSvc.create(() => this.detectElements());
3235
+ this.observer.observe(this.el.nativeElement, {
3236
+ childList: true,
3237
+ subtree: true,
3238
+ });
3239
+ }
3240
+ ngOnDestroy() {
3241
+ this.observer.disconnect();
3242
+ this.destroyViewkeepers();
3243
+ }
3244
+ destroyViewkeepers() {
3245
+ for (const viewkeeper of this.viewkeepers) {
3246
+ this.viewkeeperSvc.destroy(viewkeeper);
3247
+ }
3248
+ this.viewkeepers = [];
3249
+ }
3250
+ getViewkeeperEls() {
3251
+ let viewkeeperEls;
3252
+ if (this.skyViewkeeper) {
3253
+ viewkeeperEls = [];
3254
+ for (const item of this.skyViewkeeper) {
3255
+ const matchingEls = Array.from(this.el.nativeElement.querySelectorAll(item));
3256
+ viewkeeperEls = [...viewkeeperEls, ...matchingEls];
3257
+ }
3258
+ }
3259
+ return viewkeeperEls;
3260
+ }
3261
+ viewkeeperElsChanged(viewkeeperEls) {
3262
+ if (!viewkeeperEls !== !this.currentViewkeeperEls) {
3263
+ return true;
3264
+ }
3265
+ if (viewkeeperEls && this.currentViewkeeperEls) {
3266
+ if (viewkeeperEls.length !== this.currentViewkeeperEls.length) {
3267
+ return true;
3268
+ }
3269
+ for (let i = 0, n = viewkeeperEls.length; i < n; i++) {
3270
+ if (viewkeeperEls[i] !== this.currentViewkeeperEls[i]) {
3271
+ return true;
3272
+ }
3273
+ }
3274
+ }
3275
+ return false;
3276
+ }
3277
+ detectElements() {
3278
+ const viewkeeperEls = this.getViewkeeperEls();
3279
+ if (this.viewkeeperElsChanged(viewkeeperEls)) {
3280
+ if (this.scrollableHostWatchUnsubscribe) {
3281
+ this.scrollableHostWatchUnsubscribe.next();
3282
+ this.scrollableHostWatchUnsubscribe = new Subject();
3283
+ }
3284
+ else {
3285
+ this.scrollableHostWatchUnsubscribe = new Subject();
3286
+ }
3287
+ this.scrollableHostService
3288
+ .watchScrollableHost(this.el)
3289
+ .pipe(takeUntil(this.scrollableHostWatchUnsubscribe))
3290
+ .subscribe((scrollableHost) => {
3291
+ this.destroyViewkeepers();
3292
+ let previousViewkeeperEl;
3293
+ for (const viewkeeperEl of viewkeeperEls) {
3294
+ this.viewkeepers.push(this.viewkeeperSvc.create({
3295
+ boundaryEl: this.el.nativeElement,
3296
+ scrollableHost: scrollableHost instanceof HTMLElement
3297
+ ? scrollableHost
3298
+ : undefined,
3299
+ el: viewkeeperEl,
3300
+ setWidth: true,
3301
+ verticalOffsetEl: previousViewkeeperEl,
3302
+ }));
3303
+ previousViewkeeperEl = viewkeeperEl;
3304
+ }
3305
+ });
3306
+ this.currentViewkeeperEls = viewkeeperEls;
3307
+ }
3308
+ }
3309
+ }
3310
+ SkyViewkeeperDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyViewkeeperDirective, deps: [{ token: i0.ElementRef }, { token: MutationObserverService }, { token: SkyViewkeeperService }, { token: SkyScrollableHostService, optional: true }], target: i0.ɵɵFactoryTarget.Directive });
3311
+ SkyViewkeeperDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.2", type: SkyViewkeeperDirective, selector: "[skyViewkeeper]", inputs: { skyViewkeeper: "skyViewkeeper" }, ngImport: i0 });
3312
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyViewkeeperDirective, decorators: [{
3313
+ type: Directive,
3314
+ args: [{
3315
+ selector: '[skyViewkeeper]',
3316
+ }]
3317
+ }], ctorParameters: function () {
3318
+ return [{ type: i0.ElementRef }, { type: MutationObserverService }, { type: SkyViewkeeperService }, { type: SkyScrollableHostService, decorators: [{
3319
+ type: Optional
3320
+ }] }];
3321
+ }, propDecorators: { skyViewkeeper: [{
3322
+ type: Input
3323
+ }] } });
3324
+
3325
+ class SkyViewkeeperModule {
3326
+ }
3327
+ SkyViewkeeperModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyViewkeeperModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
3328
+ SkyViewkeeperModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyViewkeeperModule, declarations: [SkyViewkeeperDirective], exports: [SkyViewkeeperDirective] });
3329
+ SkyViewkeeperModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyViewkeeperModule });
3330
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.2", ngImport: i0, type: SkyViewkeeperModule, decorators: [{
3331
+ type: NgModule,
3332
+ args: [{
3333
+ declarations: [SkyViewkeeperDirective],
3334
+ exports: [SkyViewkeeperDirective],
3335
+ }]
3336
+ }] });
3337
+
3338
+ /**
3339
+ * Generated bundle index. Do not edit.
3340
+ */
3341
+
3342
+ export { MutationObserverService, NumericOptions, SKY_LOG_LEVEL, SkyAffixAutoFitContext, SkyAffixModule, SkyAffixService, SkyAffixer, SkyAppFormat, SkyAppTitleService, SkyAppWindowRef, SkyCoreAdapterModule, SkyCoreAdapterService, SkyDockItem, SkyDockLocation, SkyDockModule, SkyDockService, SkyDynamicComponentLocation, SkyDynamicComponentModule, SkyDynamicComponentService, SkyIdModule, SkyLogModule, SkyLogService, SkyMediaBreakpoints, SkyMediaQueryModule, SkyMediaQueryService, SkyNumericModule, SkyNumericOptions, SkyNumericPipe, SkyNumericService, SkyOverlayInstance, SkyOverlayModule, SkyOverlayService, SkyPercentPipe, SkyPercentPipeModule, SkyResizeObserverMediaQueryService, SkyResizeObserverService, SkyScrollableHostService, SkyUIConfigService, SkyViewkeeperHostOptions, SkyViewkeeperModule, SkyViewkeeperService, getWindow, SkyAffixDirective as λ1, SkyIdDirective as λ2, SkyViewkeeperDirective as λ3 };
3343
+ //# sourceMappingURL=skyux-core.mjs.map