@ifsworld/granite-components 4.3.0 → 5.0.0

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 (291) hide show
  1. package/README.md +117 -4
  2. package/esm2020/ifsworld-granite-components.mjs +5 -0
  3. package/esm2020/index.mjs +48 -0
  4. package/esm2020/lib/arrange-grid/arrange-grid-item.component.mjs +44 -0
  5. package/esm2020/lib/arrange-grid/arrange-grid.component.mjs +125 -0
  6. package/esm2020/lib/arrange-grid/arrange-grid.module.mjs +19 -0
  7. package/esm2020/lib/badge/badge.component.mjs +39 -0
  8. package/esm2020/lib/badge/badge.module.mjs +18 -0
  9. package/esm2020/lib/badge/testing/badge.harness.mjs +25 -0
  10. package/esm2020/lib/button/button.component.mjs +89 -0
  11. package/esm2020/lib/button/button.module.mjs +16 -0
  12. package/esm2020/lib/checkbox/checkbox-group.component.mjs +17 -0
  13. package/esm2020/lib/checkbox/checkbox.component.mjs +96 -0
  14. package/esm2020/lib/checkbox/checkbox.module.mjs +17 -0
  15. package/esm2020/lib/core/animation.mjs +34 -0
  16. package/esm2020/lib/core/client-environment.mjs +20 -0
  17. package/esm2020/lib/core/common-behaviors/disabled.mjs +27 -0
  18. package/esm2020/lib/core/core.module.mjs +36 -0
  19. package/esm2020/lib/core/devices/client-input-desktop.directive.mjs +29 -0
  20. package/esm2020/lib/core/devices/client-input-touch.directive.mjs +29 -0
  21. package/esm2020/lib/core/devices/client-output-desktop.directive.mjs +29 -0
  22. package/esm2020/lib/core/devices/client-output-touch.directive.mjs +29 -0
  23. package/esm2020/lib/core/pipes/pure-pipes.module.mjs +16 -0
  24. package/esm2020/lib/core/pipes/title.pipe.mjs +21 -0
  25. package/esm2020/lib/core/radio-checkbox-base.mjs +19 -0
  26. package/esm2020/lib/core/theme.library.mjs +59 -0
  27. package/esm2020/lib/core/types.mjs +2 -0
  28. package/esm2020/lib/grid/grid.component.mjs +128 -0
  29. package/esm2020/lib/grid/grid.module.mjs +18 -0
  30. package/esm2020/lib/icon/icon.component.mjs +43 -0
  31. package/esm2020/lib/icon/icon.module.mjs +16 -0
  32. package/esm2020/lib/input-field/input-field.component.mjs +160 -0
  33. package/esm2020/lib/input-field/input-field.module.mjs +20 -0
  34. package/esm2020/lib/menu/divider.directive.mjs +23 -0
  35. package/esm2020/lib/menu/menu-base.mjs +347 -0
  36. package/esm2020/lib/menu/menu-desktop-animations.mjs +23 -0
  37. package/esm2020/lib/menu/menu-errors.mjs +37 -0
  38. package/esm2020/lib/menu/menu-item.component.mjs +91 -0
  39. package/esm2020/lib/menu/menu-panel.mjs +7 -0
  40. package/esm2020/lib/menu/menu-positions.mjs +9 -0
  41. package/esm2020/lib/menu/menu-touch-animations.mjs +137 -0
  42. package/esm2020/lib/menu/menu-touch-close.component.mjs +13 -0
  43. package/esm2020/lib/menu/menu-touch-title.component.mjs +59 -0
  44. package/esm2020/lib/menu/menu-trigger-for.directive.mjs +702 -0
  45. package/esm2020/lib/menu/menu.component.mjs +30 -0
  46. package/esm2020/lib/menu/menu.module.mjs +55 -0
  47. package/esm2020/lib/menu/testing/menu.harness.mjs +109 -0
  48. package/esm2020/lib/menu/title.directive.mjs +17 -0
  49. package/esm2020/lib/radio-button/radio-button.component.mjs +118 -0
  50. package/esm2020/lib/radio-button/radio-button.module.mjs +17 -0
  51. package/esm2020/lib/radio-button/radio-group.component.mjs +17 -0
  52. package/esm2020/lib/table/cell/cell.mjs +15 -0
  53. package/esm2020/lib/table/cell/table-data-cell.component.mjs +26 -0
  54. package/esm2020/lib/table/cell/table-header-cell.component.mjs +12 -0
  55. package/esm2020/lib/table/column/table-column.directive.mjs +23 -0
  56. package/esm2020/lib/table/table-constants.library.mjs +4 -0
  57. package/esm2020/lib/table/table.component.mjs +36 -0
  58. package/esm2020/lib/table/table.module.mjs +32 -0
  59. package/esm2020/lib/toggle-switch/toggle-switch.component.mjs +96 -0
  60. package/esm2020/lib/toggle-switch/toggle-switch.module.mjs +16 -0
  61. package/fesm2015/ifsworld-granite-components.mjs +3145 -0
  62. package/fesm2015/ifsworld-granite-components.mjs.map +1 -0
  63. package/fesm2020/ifsworld-granite-components.mjs +3103 -0
  64. package/fesm2020/ifsworld-granite-components.mjs.map +1 -0
  65. package/ifsworld-granite-components.d.ts +1 -8
  66. package/lib/arrange-grid/arrange-grid-item.component.d.ts +3 -0
  67. package/lib/arrange-grid/arrange-grid.component.d.ts +3 -0
  68. package/lib/arrange-grid/arrange-grid.module.d.ts +7 -0
  69. package/lib/badge/badge.component.d.ts +3 -0
  70. package/lib/badge/badge.module.d.ts +6 -0
  71. package/lib/button/button.component.d.ts +5 -0
  72. package/lib/button/button.module.d.ts +5 -0
  73. package/lib/checkbox/checkbox-group.component.d.ts +3 -0
  74. package/lib/checkbox/checkbox.component.d.ts +3 -0
  75. package/lib/checkbox/checkbox.module.d.ts +6 -0
  76. package/lib/core/core.module.d.ts +8 -0
  77. package/lib/core/devices/client-input-desktop.directive.d.ts +3 -0
  78. package/lib/core/devices/client-input-touch.directive.d.ts +3 -0
  79. package/lib/core/devices/client-output-desktop.directive.d.ts +3 -0
  80. package/lib/core/devices/client-output-touch.directive.d.ts +3 -0
  81. package/lib/core/pipes/pure-pipes.module.d.ts +5 -0
  82. package/lib/core/pipes/title.pipe.d.ts +3 -0
  83. package/lib/core/radio-checkbox-base.d.ts +3 -0
  84. package/lib/grid/grid.component.d.ts +5 -0
  85. package/lib/grid/grid.module.d.ts +6 -0
  86. package/lib/icon/icon.component.d.ts +3 -0
  87. package/lib/icon/icon.module.d.ts +5 -0
  88. package/lib/input-field/input-field.component.d.ts +3 -0
  89. package/lib/input-field/input-field.module.d.ts +8 -0
  90. package/lib/menu/divider.directive.d.ts +3 -0
  91. package/lib/menu/menu-base.d.ts +190 -0
  92. package/lib/menu/menu-item.component.d.ts +3 -0
  93. package/lib/menu/menu-touch-close.component.d.ts +3 -0
  94. package/lib/menu/menu-touch-title.component.d.ts +4 -1
  95. package/lib/menu/menu-trigger-for.directive.d.ts +4 -1
  96. package/lib/menu/menu.component.d.ts +4 -187
  97. package/lib/menu/menu.module.d.ts +15 -0
  98. package/lib/menu/title.directive.d.ts +3 -0
  99. package/lib/radio-button/radio-button.component.d.ts +4 -1
  100. package/lib/radio-button/radio-button.module.d.ts +6 -0
  101. package/lib/radio-button/radio-group.component.d.ts +3 -0
  102. package/lib/table/cell/cell.d.ts +3 -0
  103. package/lib/table/cell/table-data-cell.component.d.ts +3 -0
  104. package/lib/table/cell/table-header-cell.component.d.ts +3 -0
  105. package/lib/table/column/table-column.directive.d.ts +3 -0
  106. package/lib/table/table.component.d.ts +3 -0
  107. package/lib/table/table.module.d.ts +12 -0
  108. package/lib/toggle-switch/toggle-switch.component.d.ts +3 -0
  109. package/lib/toggle-switch/toggle-switch.module.d.ts +5 -0
  110. package/package.json +25 -12
  111. package/bundles/ifsworld-granite-components.umd.js +0 -3649
  112. package/bundles/ifsworld-granite-components.umd.js.map +0 -1
  113. package/bundles/ifsworld-granite-components.umd.min.js +0 -10
  114. package/bundles/ifsworld-granite-components.umd.min.js.map +0 -1
  115. package/esm2015/ifsworld-granite-components.js +0 -13
  116. package/esm2015/ifsworld-granite-components.js.map +0 -1
  117. package/esm2015/ifsworld-granite-components.metadata.json +0 -1
  118. package/esm2015/index.js +0 -48
  119. package/esm2015/index.js.map +0 -1
  120. package/esm2015/index.metadata.json +0 -1
  121. package/esm2015/lib/arrange-grid/arrange-grid-item.component.js +0 -48
  122. package/esm2015/lib/arrange-grid/arrange-grid-item.component.js.map +0 -1
  123. package/esm2015/lib/arrange-grid/arrange-grid-item.component.metadata.json +0 -1
  124. package/esm2015/lib/arrange-grid/arrange-grid.component.js +0 -123
  125. package/esm2015/lib/arrange-grid/arrange-grid.component.js.map +0 -1
  126. package/esm2015/lib/arrange-grid/arrange-grid.component.metadata.json +0 -1
  127. package/esm2015/lib/arrange-grid/arrange-grid.module.js +0 -14
  128. package/esm2015/lib/arrange-grid/arrange-grid.module.js.map +0 -1
  129. package/esm2015/lib/arrange-grid/arrange-grid.module.metadata.json +0 -1
  130. package/esm2015/lib/badge/badge.component.js +0 -44
  131. package/esm2015/lib/badge/badge.component.js.map +0 -1
  132. package/esm2015/lib/badge/badge.component.metadata.json +0 -1
  133. package/esm2015/lib/badge/badge.module.js +0 -13
  134. package/esm2015/lib/badge/badge.module.js.map +0 -1
  135. package/esm2015/lib/badge/badge.module.metadata.json +0 -1
  136. package/esm2015/lib/badge/testing/badge.harness.js +0 -30
  137. package/esm2015/lib/badge/testing/badge.harness.js.map +0 -1
  138. package/esm2015/lib/badge/testing/badge.harness.metadata.json +0 -1
  139. package/esm2015/lib/button/button.component.js +0 -108
  140. package/esm2015/lib/button/button.component.js.map +0 -1
  141. package/esm2015/lib/button/button.component.metadata.json +0 -1
  142. package/esm2015/lib/button/button.module.js +0 -11
  143. package/esm2015/lib/button/button.module.js.map +0 -1
  144. package/esm2015/lib/button/button.module.metadata.json +0 -1
  145. package/esm2015/lib/checkbox/checkbox-group.component.js +0 -19
  146. package/esm2015/lib/checkbox/checkbox-group.component.js.map +0 -1
  147. package/esm2015/lib/checkbox/checkbox-group.component.metadata.json +0 -1
  148. package/esm2015/lib/checkbox/checkbox.component.js +0 -89
  149. package/esm2015/lib/checkbox/checkbox.component.js.map +0 -1
  150. package/esm2015/lib/checkbox/checkbox.component.metadata.json +0 -1
  151. package/esm2015/lib/checkbox/checkbox.module.js +0 -12
  152. package/esm2015/lib/checkbox/checkbox.module.js.map +0 -1
  153. package/esm2015/lib/checkbox/checkbox.module.metadata.json +0 -1
  154. package/esm2015/lib/core/animation.js +0 -34
  155. package/esm2015/lib/core/animation.js.map +0 -1
  156. package/esm2015/lib/core/animation.metadata.json +0 -1
  157. package/esm2015/lib/core/client-environment.js +0 -20
  158. package/esm2015/lib/core/client-environment.js.map +0 -1
  159. package/esm2015/lib/core/client-environment.metadata.json +0 -1
  160. package/esm2015/lib/core/common-behaviors/disabled.js +0 -25
  161. package/esm2015/lib/core/common-behaviors/disabled.js.map +0 -1
  162. package/esm2015/lib/core/common-behaviors/disabled.metadata.json +0 -1
  163. package/esm2015/lib/core/core.module.js +0 -25
  164. package/esm2015/lib/core/core.module.js.map +0 -1
  165. package/esm2015/lib/core/core.module.metadata.json +0 -1
  166. package/esm2015/lib/core/devices/client-input-desktop.directive.js +0 -22
  167. package/esm2015/lib/core/devices/client-input-desktop.directive.js.map +0 -1
  168. package/esm2015/lib/core/devices/client-input-desktop.directive.metadata.json +0 -1
  169. package/esm2015/lib/core/devices/client-input-touch.directive.js +0 -22
  170. package/esm2015/lib/core/devices/client-input-touch.directive.js.map +0 -1
  171. package/esm2015/lib/core/devices/client-input-touch.directive.metadata.json +0 -1
  172. package/esm2015/lib/core/devices/client-output-desktop.directive.js +0 -22
  173. package/esm2015/lib/core/devices/client-output-desktop.directive.js.map +0 -1
  174. package/esm2015/lib/core/devices/client-output-desktop.directive.metadata.json +0 -1
  175. package/esm2015/lib/core/devices/client-output-touch.directive.js +0 -22
  176. package/esm2015/lib/core/devices/client-output-touch.directive.js.map +0 -1
  177. package/esm2015/lib/core/devices/client-output-touch.directive.metadata.json +0 -1
  178. package/esm2015/lib/core/pipes/pure-pipes.module.js +0 -11
  179. package/esm2015/lib/core/pipes/pure-pipes.module.js.map +0 -1
  180. package/esm2015/lib/core/pipes/pure-pipes.module.metadata.json +0 -1
  181. package/esm2015/lib/core/pipes/title.pipe.js +0 -17
  182. package/esm2015/lib/core/pipes/title.pipe.js.map +0 -1
  183. package/esm2015/lib/core/pipes/title.pipe.metadata.json +0 -1
  184. package/esm2015/lib/core/radio-checkbox-base.js +0 -15
  185. package/esm2015/lib/core/radio-checkbox-base.js.map +0 -1
  186. package/esm2015/lib/core/radio-checkbox-base.metadata.json +0 -1
  187. package/esm2015/lib/core/theme.library.js +0 -59
  188. package/esm2015/lib/core/theme.library.js.map +0 -1
  189. package/esm2015/lib/core/theme.library.metadata.json +0 -1
  190. package/esm2015/lib/core/types.js +0 -2
  191. package/esm2015/lib/core/types.js.map +0 -1
  192. package/esm2015/lib/core/types.metadata.json +0 -1
  193. package/esm2015/lib/grid/grid.component.js +0 -131
  194. package/esm2015/lib/grid/grid.component.js.map +0 -1
  195. package/esm2015/lib/grid/grid.component.metadata.json +0 -1
  196. package/esm2015/lib/grid/grid.module.js +0 -13
  197. package/esm2015/lib/grid/grid.module.js.map +0 -1
  198. package/esm2015/lib/grid/grid.module.metadata.json +0 -1
  199. package/esm2015/lib/icon/icon.component.js +0 -48
  200. package/esm2015/lib/icon/icon.component.js.map +0 -1
  201. package/esm2015/lib/icon/icon.component.metadata.json +0 -1
  202. package/esm2015/lib/icon/icon.module.js +0 -11
  203. package/esm2015/lib/icon/icon.module.js.map +0 -1
  204. package/esm2015/lib/icon/icon.module.metadata.json +0 -1
  205. package/esm2015/lib/input-field/input-field.component.js +0 -144
  206. package/esm2015/lib/input-field/input-field.component.js.map +0 -1
  207. package/esm2015/lib/input-field/input-field.component.metadata.json +0 -1
  208. package/esm2015/lib/input-field/input-field.module.js +0 -15
  209. package/esm2015/lib/input-field/input-field.module.js.map +0 -1
  210. package/esm2015/lib/input-field/input-field.module.metadata.json +0 -1
  211. package/esm2015/lib/menu/divider.directive.js +0 -20
  212. package/esm2015/lib/menu/divider.directive.js.map +0 -1
  213. package/esm2015/lib/menu/divider.directive.metadata.json +0 -1
  214. package/esm2015/lib/menu/menu-desktop-animations.js +0 -23
  215. package/esm2015/lib/menu/menu-desktop-animations.js.map +0 -1
  216. package/esm2015/lib/menu/menu-desktop-animations.metadata.json +0 -1
  217. package/esm2015/lib/menu/menu-errors.js +0 -37
  218. package/esm2015/lib/menu/menu-errors.js.map +0 -1
  219. package/esm2015/lib/menu/menu-errors.metadata.json +0 -1
  220. package/esm2015/lib/menu/menu-item.component.js +0 -82
  221. package/esm2015/lib/menu/menu-item.component.js.map +0 -1
  222. package/esm2015/lib/menu/menu-item.component.metadata.json +0 -1
  223. package/esm2015/lib/menu/menu-panel.js +0 -7
  224. package/esm2015/lib/menu/menu-panel.js.map +0 -1
  225. package/esm2015/lib/menu/menu-panel.metadata.json +0 -1
  226. package/esm2015/lib/menu/menu-positions.js +0 -9
  227. package/esm2015/lib/menu/menu-positions.js.map +0 -1
  228. package/esm2015/lib/menu/menu-positions.metadata.json +0 -1
  229. package/esm2015/lib/menu/menu-touch-animations.js +0 -137
  230. package/esm2015/lib/menu/menu-touch-animations.js.map +0 -1
  231. package/esm2015/lib/menu/menu-touch-animations.metadata.json +0 -1
  232. package/esm2015/lib/menu/menu-touch-close.component.js +0 -16
  233. package/esm2015/lib/menu/menu-touch-close.component.js.map +0 -1
  234. package/esm2015/lib/menu/menu-touch-close.component.metadata.json +0 -1
  235. package/esm2015/lib/menu/menu-touch-title.component.js +0 -45
  236. package/esm2015/lib/menu/menu-touch-title.component.js.map +0 -1
  237. package/esm2015/lib/menu/menu-touch-title.component.metadata.json +0 -1
  238. package/esm2015/lib/menu/menu-trigger-for.directive.js +0 -684
  239. package/esm2015/lib/menu/menu-trigger-for.directive.js.map +0 -1
  240. package/esm2015/lib/menu/menu-trigger-for.directive.metadata.json +0 -1
  241. package/esm2015/lib/menu/menu.component.js +0 -362
  242. package/esm2015/lib/menu/menu.component.js.map +0 -1
  243. package/esm2015/lib/menu/menu.component.metadata.json +0 -1
  244. package/esm2015/lib/menu/menu.module.js +0 -38
  245. package/esm2015/lib/menu/menu.module.js.map +0 -1
  246. package/esm2015/lib/menu/menu.module.metadata.json +0 -1
  247. package/esm2015/lib/menu/testing/menu.harness.js +0 -133
  248. package/esm2015/lib/menu/testing/menu.harness.js.map +0 -1
  249. package/esm2015/lib/menu/testing/menu.harness.metadata.json +0 -1
  250. package/esm2015/lib/menu/title.directive.js +0 -13
  251. package/esm2015/lib/menu/title.directive.js.map +0 -1
  252. package/esm2015/lib/menu/title.directive.metadata.json +0 -1
  253. package/esm2015/lib/radio-button/radio-button.component.js +0 -110
  254. package/esm2015/lib/radio-button/radio-button.component.js.map +0 -1
  255. package/esm2015/lib/radio-button/radio-button.component.metadata.json +0 -1
  256. package/esm2015/lib/radio-button/radio-button.module.js +0 -12
  257. package/esm2015/lib/radio-button/radio-button.module.js.map +0 -1
  258. package/esm2015/lib/radio-button/radio-button.module.metadata.json +0 -1
  259. package/esm2015/lib/radio-button/radio-group.component.js +0 -19
  260. package/esm2015/lib/radio-button/radio-group.component.js.map +0 -1
  261. package/esm2015/lib/radio-button/radio-group.component.metadata.json +0 -1
  262. package/esm2015/lib/table/cell/cell.js +0 -12
  263. package/esm2015/lib/table/cell/cell.js.map +0 -1
  264. package/esm2015/lib/table/cell/cell.metadata.json +0 -1
  265. package/esm2015/lib/table/cell/table-data-cell.component.js +0 -21
  266. package/esm2015/lib/table/cell/table-data-cell.component.js.map +0 -1
  267. package/esm2015/lib/table/cell/table-data-cell.component.metadata.json +0 -1
  268. package/esm2015/lib/table/cell/table-header-cell.component.js +0 -13
  269. package/esm2015/lib/table/cell/table-header-cell.component.js.map +0 -1
  270. package/esm2015/lib/table/cell/table-header-cell.component.metadata.json +0 -1
  271. package/esm2015/lib/table/column/table-column.directive.js +0 -16
  272. package/esm2015/lib/table/column/table-column.directive.js.map +0 -1
  273. package/esm2015/lib/table/column/table-column.directive.metadata.json +0 -1
  274. package/esm2015/lib/table/table-constants.library.js +0 -4
  275. package/esm2015/lib/table/table-constants.library.js.map +0 -1
  276. package/esm2015/lib/table/table-constants.library.metadata.json +0 -1
  277. package/esm2015/lib/table/table.component.js +0 -28
  278. package/esm2015/lib/table/table.component.js.map +0 -1
  279. package/esm2015/lib/table/table.component.metadata.json +0 -1
  280. package/esm2015/lib/table/table.module.js +0 -24
  281. package/esm2015/lib/table/table.module.js.map +0 -1
  282. package/esm2015/lib/table/table.module.metadata.json +0 -1
  283. package/esm2015/lib/toggle-switch/toggle-switch.component.js +0 -89
  284. package/esm2015/lib/toggle-switch/toggle-switch.component.js.map +0 -1
  285. package/esm2015/lib/toggle-switch/toggle-switch.component.metadata.json +0 -1
  286. package/esm2015/lib/toggle-switch/toggle-switch.module.js +0 -11
  287. package/esm2015/lib/toggle-switch/toggle-switch.module.js.map +0 -1
  288. package/esm2015/lib/toggle-switch/toggle-switch.module.metadata.json +0 -1
  289. package/fesm2015/ifsworld-granite-components.js +0 -2992
  290. package/fesm2015/ifsworld-granite-components.js.map +0 -1
  291. package/ifsworld-granite-components.metadata.json +0 -1
@@ -0,0 +1,3145 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Component, ChangeDetectionStrategy, Input, HostBinding, ContentChildren, NgModule, InjectionToken, Attribute, Inject, Optional, EventEmitter, QueryList, TemplateRef, Directive, ViewChild, Output, Self, HostListener, ContentChild, Pipe } from '@angular/core';
3
+ import * as i2 from '@angular/common';
4
+ import { CommonModule, DOCUMENT } from '@angular/common';
5
+ import { coerceNumberProperty, coerceBooleanProperty } from '@angular/cdk/coercion';
6
+ import { Subject, BehaviorSubject, combineLatest, Subscription, merge, of, asapScheduler, fromEvent } from 'rxjs';
7
+ import { takeUntil, filter, map, startWith, switchMap, take, delay } from 'rxjs/operators';
8
+ import { __awaiter } from 'tslib';
9
+ import { ComponentHarness, HarnessPredicate, TestKey } from '@angular/cdk/testing';
10
+ import * as i1$1 from '@angular/cdk/overlay';
11
+ import { OverlayConfig, OverlayModule } from '@angular/cdk/overlay';
12
+ import { TemplatePortal, PortalModule } from '@angular/cdk/portal';
13
+ import { trigger, state, style, transition, group, query, animate, sequence } from '@angular/animations';
14
+ import * as i1 from '@angular/cdk/a11y';
15
+ import { FocusKeyManager, isFakeMousedownFromScreenReader } from '@angular/cdk/a11y';
16
+ import { hasModifierKey } from '@angular/cdk/keycodes';
17
+ import { normalizePassiveListenerOptions } from '@angular/cdk/platform';
18
+ import * as i3 from '@angular/cdk/bidi';
19
+ import * as i2$1 from '@angular/cdk/collections';
20
+ import * as i1$2 from '@angular/cdk/table';
21
+ import { CdkTableModule } from '@angular/cdk/table';
22
+
23
+ class GraniteArrangeGridItemComponent {
24
+ constructor(element) {
25
+ this.element = element;
26
+ /**
27
+ * Column span to render.
28
+ * For use in template only. Do not use outside of this component.
29
+ * @ignore
30
+ */
31
+ this._columnSpan = null;
32
+ /* no-op */
33
+ }
34
+ /**
35
+ * Number of cells the item would span. Used by arrange grid in column
36
+ * orientation to fill any unused space caused by wrapped items.
37
+ */
38
+ set columnSpan(value) {
39
+ this._columnSpan = value;
40
+ this.updateStyles();
41
+ }
42
+ /**
43
+ * Update element styles
44
+ */
45
+ updateStyles() {
46
+ this.setCssProperty('--columnSpan', this._columnSpan ? this._columnSpan.toString() : null);
47
+ }
48
+ /**
49
+ * Set CSS variable value or remove it if a null value is given.
50
+ * Would of course rather have used property binding but that is not
51
+ * supported until (perhaps) Angular 9.
52
+ * See: https://github.com/angular/angular/issues/9343
53
+ */
54
+ setCssProperty(variable, value) {
55
+ this.element.nativeElement.style.setProperty(variable, value);
56
+ }
57
+ }
58
+ GraniteArrangeGridItemComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteArrangeGridItemComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
59
+ GraniteArrangeGridItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: GraniteArrangeGridItemComponent, selector: "granite-arrange-grid-item", ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host{--columnSpan: $default-column-span;display:grid;grid-column:span var(--columnSpan, 1)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
60
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteArrangeGridItemComponent, decorators: [{
61
+ type: Component,
62
+ args: [{ selector: 'granite-arrange-grid-item', template: '<ng-content></ng-content>', changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--columnSpan: $default-column-span;display:grid;grid-column:span var(--columnSpan, 1)}\n"] }]
63
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }]; } });
64
+
65
+ var GraniteArrangeGridOrientation;
66
+ (function (GraniteArrangeGridOrientation) {
67
+ GraniteArrangeGridOrientation["columns"] = "columns";
68
+ GraniteArrangeGridOrientation["rows"] = "rows";
69
+ })(GraniteArrangeGridOrientation || (GraniteArrangeGridOrientation = {}));
70
+ class GraniteArrangeGridComponent {
71
+ constructor(element) {
72
+ this.element = element;
73
+ /** How to present grid items; `columns` (default) or `rows` */
74
+ this.orientation = GraniteArrangeGridOrientation.columns;
75
+ /** Exposes column orientation to template */
76
+ this.classColumnOrientation = false;
77
+ /** Exposes row orientation to template */
78
+ this.classRowOrientation = false;
79
+ /** Number of columns to render */
80
+ this._cols = GraniteArrangeGridComponent.defaultCols;
81
+ /** Nexted on component destruction to complete other observables. */
82
+ this.destroy$ = new Subject();
83
+ /* no-op */
84
+ }
85
+ /**
86
+ * Number of grid columns to use when orientation is set to `column`. The
87
+ * default is two columns.
88
+ */
89
+ set cols(value) {
90
+ this._cols = Math.max(1, Math.round(coerceNumberProperty(value)));
91
+ }
92
+ get cols() {
93
+ return this._cols;
94
+ }
95
+ set rows(value) {
96
+ // Prevent pointless usage
97
+ throw Error('Explicitly setting rows value for arrange grid is unsupported');
98
+ }
99
+ get rows() {
100
+ return this._rows;
101
+ }
102
+ ngAfterContentInit() {
103
+ // Update style whenever grid item components change in content
104
+ this.arrangeGridItemComponents.changes
105
+ .pipe(takeUntil(this.destroy$))
106
+ .subscribe(() => this.updateStyles());
107
+ this.updateStyles();
108
+ }
109
+ ngOnChanges(changes) {
110
+ if ((changes.orientation && !changes.orientation.isFirstChange()) ||
111
+ (changes.cols && !changes.cols.isFirstChange())) {
112
+ this.updateStyles();
113
+ }
114
+ }
115
+ ngOnDestroy() {
116
+ this.destroy$.next();
117
+ }
118
+ /**
119
+ * Update grid row template style.
120
+ *
121
+ * Use content height of all but last row and let the last grow
122
+ * to take up any remaining space.
123
+ */
124
+ updateStyles() {
125
+ const children = (this.arrangeGridItemComponents || []).length;
126
+ if (this.orientation === GraniteArrangeGridOrientation.columns) {
127
+ // If too many items was placed into too few colums, there would
128
+ // be some wrapping. Take that into account when calculating the
129
+ // number of rows.
130
+ this._rows = Math.trunc((children - 1) / (this._cols || 1)) + 1;
131
+ this.classColumnOrientation = true;
132
+ this.classRowOrientation = false;
133
+ if (children > 0) {
134
+ // Fill any unused space caused by wrapped items by making the
135
+ // last item also span over remaining cells.
136
+ this.arrangeGridItemComponents.forEach((c) => (c.columnSpan = null));
137
+ this.arrangeGridItemComponents.last.columnSpan =
138
+ this._rows * this._cols - children + 1;
139
+ }
140
+ }
141
+ else {
142
+ this._cols = 1; // In row orientation, there is just a single column
143
+ this._rows = children;
144
+ this.classColumnOrientation = false;
145
+ this.classRowOrientation = true;
146
+ }
147
+ this.setCssProperty('--cols', this._cols.toString());
148
+ this.setCssProperty('--rows', this._rows.toString());
149
+ }
150
+ /**
151
+ * Set CSS variable value or remove it if a null value is given.
152
+ * Would of course rather have used property binding but that is not
153
+ * supported until (perhaps) Angular 9.
154
+ * See: https://github.com/angular/angular/issues/9343
155
+ *
156
+ * TODO: Replace with property binding with Angular 9 upgrade
157
+ */
158
+ setCssProperty(variable, value) {
159
+ this.element.nativeElement.style.setProperty(variable, value);
160
+ }
161
+ }
162
+ /** Default number of columns to use in column orientation */
163
+ GraniteArrangeGridComponent.defaultCols = 2;
164
+ GraniteArrangeGridComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteArrangeGridComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
165
+ GraniteArrangeGridComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: GraniteArrangeGridComponent, selector: "granite-arrange-grid", inputs: { orientation: "orientation", cols: "cols" }, host: { properties: { "class.column-orientation": "this.classColumnOrientation", "class.row-orientation": "this.classRowOrientation" } }, queries: [{ propertyName: "arrangeGridItemComponents", predicate: GraniteArrangeGridItemComponent }], usesOnChanges: true, ngImport: i0, template: "<ng-content select=\"granite-arrange-grid-item\"></ng-content>\n", styles: ["@media only screen and (min-width: 960px){:host{--cols: 1;--rows: 1;display:grid;grid-template-columns:repeat(var(--cols, 1),1fr);grid-column-gap:.5rem;column-gap:.5rem;grid-row-gap:.5rem;row-gap:.5rem}:host.row-orientation{grid-template-columns:auto;grid-template-rows:repeat(calc(var(--rows, 1) - 1),max-content)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
166
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteArrangeGridComponent, decorators: [{
167
+ type: Component,
168
+ args: [{ selector: 'granite-arrange-grid', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-content select=\"granite-arrange-grid-item\"></ng-content>\n", styles: ["@media only screen and (min-width: 960px){:host{--cols: 1;--rows: 1;display:grid;grid-template-columns:repeat(var(--cols, 1),1fr);grid-column-gap:.5rem;column-gap:.5rem;grid-row-gap:.5rem;row-gap:.5rem}:host.row-orientation{grid-template-columns:auto;grid-template-rows:repeat(calc(var(--rows, 1) - 1),max-content)}}\n"] }]
169
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { orientation: [{
170
+ type: Input
171
+ }], classColumnOrientation: [{
172
+ type: HostBinding,
173
+ args: ['class.column-orientation']
174
+ }], classRowOrientation: [{
175
+ type: HostBinding,
176
+ args: ['class.row-orientation']
177
+ }], arrangeGridItemComponents: [{
178
+ type: ContentChildren,
179
+ args: [GraniteArrangeGridItemComponent]
180
+ }], cols: [{
181
+ type: Input
182
+ }] } });
183
+
184
+ class GraniteArrangeGridModule {
185
+ }
186
+ GraniteArrangeGridModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteArrangeGridModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
187
+ GraniteArrangeGridModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteArrangeGridModule, declarations: [GraniteArrangeGridComponent, GraniteArrangeGridItemComponent], imports: [CommonModule], exports: [GraniteArrangeGridComponent, GraniteArrangeGridItemComponent] });
188
+ GraniteArrangeGridModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteArrangeGridModule, imports: [[CommonModule]] });
189
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteArrangeGridModule, decorators: [{
190
+ type: NgModule,
191
+ args: [{
192
+ declarations: [GraniteArrangeGridComponent, GraniteArrangeGridItemComponent],
193
+ imports: [CommonModule],
194
+ exports: [GraniteArrangeGridComponent, GraniteArrangeGridItemComponent],
195
+ }]
196
+ }] });
197
+
198
+ /**
199
+ * Grid item component
200
+ *
201
+ * Merely a wrapper for CSS Grid items, accepting item style as input parameters.
202
+ */
203
+ class GraniteGridItemComponent {
204
+ constructor(element, renderer) {
205
+ this.element = element;
206
+ this.renderer = renderer;
207
+ }
208
+ ngOnChanges() {
209
+ this.updateStyles();
210
+ }
211
+ /**
212
+ * Update element styles
213
+ */
214
+ updateStyles() {
215
+ this.setStyle('gridColumnStart', this.columnStart);
216
+ this.setStyle('gridColumnEnd', this.columnEnd);
217
+ this.setStyle('gridRowStart', this.rowStart);
218
+ this.setStyle('gridRowEnd', this.rowEnd);
219
+ }
220
+ /**
221
+ * Sets the element style. Needs to be set manually to avoid "Changed after
222
+ * checked" errors that would occur with HostBinding.
223
+ */
224
+ setStyle(property, value) {
225
+ this.renderer.setStyle(this.element.nativeElement, property, value || '');
226
+ }
227
+ }
228
+ GraniteGridItemComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteGridItemComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
229
+ GraniteGridItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: GraniteGridItemComponent, selector: "granite-grid-item", inputs: { columnStart: "columnStart", columnEnd: "columnEnd", rowStart: "rowStart", rowEnd: "rowEnd" }, usesOnChanges: true, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
230
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteGridItemComponent, decorators: [{
231
+ type: Component,
232
+ args: [{
233
+ selector: 'granite-grid-item',
234
+ template: '<ng-content></ng-content>',
235
+ changeDetection: ChangeDetectionStrategy.OnPush,
236
+ }]
237
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { columnStart: [{
238
+ type: Input
239
+ }], columnEnd: [{
240
+ type: Input
241
+ }], rowStart: [{
242
+ type: Input
243
+ }], rowEnd: [{
244
+ type: Input
245
+ }] } });
246
+ /**
247
+ * Grid
248
+ *
249
+ * A wrapper around a native CSS Grid. Anything can be used for grid items, but
250
+ * `GridItemComponent` is recommended for common cases.
251
+ */
252
+ class GraniteGridComponent {
253
+ constructor(element) {
254
+ this.element = element;
255
+ }
256
+ /**
257
+ * Number of grid columns, unless set via styling (grid-template-columns)
258
+ *
259
+ * Setting this value will produce equally sized columns
260
+ */
261
+ set cols(value) {
262
+ this._cols = Math.max(1, Math.round(coerceNumberProperty(value)));
263
+ }
264
+ get cols() {
265
+ return this._cols;
266
+ }
267
+ /**
268
+ * Number of grid rows, unless set via styling (grid-template-rows)
269
+ *
270
+ * Setting this value will produce equally sized rows
271
+ */
272
+ set rows(value) {
273
+ this._rows = Math.max(1, Math.round(coerceNumberProperty(value)));
274
+ }
275
+ get rows() {
276
+ return this._rows;
277
+ }
278
+ ngAfterContentInit() {
279
+ this.updateStyles();
280
+ }
281
+ ngOnChanges(changes) {
282
+ if ((changes.cols && !changes.cols.isFirstChange()) ||
283
+ (changes.rows && !changes.rows.isFirstChange())) {
284
+ this.updateStyles();
285
+ }
286
+ }
287
+ /** Update element styles */
288
+ updateStyles() {
289
+ this.updateColumnStyles();
290
+ this.updateRowStyles();
291
+ }
292
+ /**
293
+ * Set CSS variable value or remove it if a null value is given.
294
+ * Would of course rather have used property binding but that is not
295
+ * supported until (perhaps) Angular 9.
296
+ * See: https://github.com/angular/angular/issues/9343
297
+ *
298
+ * TODO: Replace with property binding with Angular 9 upgrade
299
+ */
300
+ setCssProperty(variable, value) {
301
+ this.element.nativeElement.style.setProperty(variable, value);
302
+ }
303
+ /** Update grid column template style */
304
+ updateColumnStyles() {
305
+ this.setCssProperty('--cols', (this._cols && this._cols.toString()) || null);
306
+ }
307
+ /** Update grid row template style */
308
+ updateRowStyles() {
309
+ this.setCssProperty('--rows', (this._rows && this._rows.toString()) || null);
310
+ }
311
+ }
312
+ GraniteGridComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteGridComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
313
+ GraniteGridComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: GraniteGridComponent, selector: "granite-grid", inputs: { cols: "cols", rows: "rows" }, usesOnChanges: true, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host{--cols: 1;--rows: 1;display:grid;grid-template-columns:repeat(var(--cols, 1),1fr);grid-template-rows:repeat(var(--rows, 1),1fr)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
314
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteGridComponent, decorators: [{
315
+ type: Component,
316
+ args: [{ selector: 'granite-grid', template: '<ng-content></ng-content>', changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{--cols: 1;--rows: 1;display:grid;grid-template-columns:repeat(var(--cols, 1),1fr);grid-template-rows:repeat(var(--rows, 1),1fr)}\n"] }]
317
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { cols: [{
318
+ type: Input
319
+ }], rows: [{
320
+ type: Input
321
+ }] } });
322
+
323
+ class GraniteGridModule {
324
+ }
325
+ GraniteGridModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteGridModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
326
+ GraniteGridModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteGridModule, declarations: [GraniteGridComponent, GraniteGridItemComponent], imports: [CommonModule], exports: [GraniteGridComponent, GraniteGridItemComponent] });
327
+ GraniteGridModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteGridModule, imports: [[CommonModule]] });
328
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteGridModule, decorators: [{
329
+ type: NgModule,
330
+ args: [{
331
+ declarations: [GraniteGridComponent, GraniteGridItemComponent],
332
+ imports: [CommonModule],
333
+ exports: [GraniteGridComponent, GraniteGridItemComponent],
334
+ }]
335
+ }] });
336
+
337
+ const TOKEN_PREFIX = 'granite-';
338
+ const TOKEN_PREFIX_OLD = 'fnd-'; // TODO: Remove this when all tokens have 'granite-' as the prefix
339
+ /**
340
+ * Get the theme that corresponds to a given ID
341
+ */
342
+ function getThemeById(themes, id) {
343
+ const theme = id !== undefined ? themes.find((t) => t.id === id) : undefined;
344
+ return theme;
345
+ }
346
+ /**
347
+ * Apply a theme to a DOM element by iterating though all tokens,
348
+ * setting a CSS variable for each one.
349
+ *
350
+ * @param theme Theme to set
351
+ * @param element Target element
352
+ */
353
+ function applyTheme(theme, element) {
354
+ applyTokens(theme.tokens, element);
355
+ }
356
+ /**
357
+ * Set a CSS variable for each token on the specified element.
358
+ *
359
+ * @param theme Theme to set
360
+ * @param element Target element
361
+ */
362
+ function applyTokens(tokens, element) {
363
+ for (const token of Object.keys(tokens)) {
364
+ element.style.setProperty(token, tokens[token]);
365
+ }
366
+ }
367
+ /**
368
+ * Remove theme token CSS variables from an element using the specified keys
369
+ *
370
+ * @param theme Theme with tokens to clear
371
+ * @param element Target element
372
+ */
373
+ function clearTheme(theme, element) {
374
+ clearTokens(Object.keys(theme.tokens), element);
375
+ }
376
+ /**
377
+ * Remove token CSS variables from an element using the specified keys.
378
+ *
379
+ * @param keys Token keys
380
+ * @param element Target element
381
+ */
382
+ function clearTokens(keys, element) {
383
+ for (const token of keys) {
384
+ element.style.removeProperty(token);
385
+ }
386
+ }
387
+ function isValidToken(key) {
388
+ return (key && (key.startsWith(TOKEN_PREFIX) || key.startsWith(TOKEN_PREFIX_OLD)));
389
+ }
390
+ function setPropertyValue(name, value, element) {
391
+ if (element && element.style && value != null) {
392
+ element.style.setProperty(name, isValidToken(value) ? `var(--${value})` : value);
393
+ }
394
+ }
395
+
396
+ class GraniteBadgeComponent {
397
+ constructor(elementRef) {
398
+ this.elementRef = elementRef;
399
+ /** Pill style badge */
400
+ this.pill = false;
401
+ }
402
+ ngOnChanges(changes) {
403
+ if (changes.backgroundColor) {
404
+ if (changes.backgroundColor.previousValue !==
405
+ changes.backgroundColor.currentValue) {
406
+ setPropertyValue('background-color', changes.backgroundColor.currentValue, this.elementRef.nativeElement);
407
+ }
408
+ }
409
+ if (changes.color) {
410
+ if (changes.color.previousValue !== changes.color.currentValue) {
411
+ setPropertyValue('color', changes.color.currentValue, this.elementRef.nativeElement);
412
+ }
413
+ }
414
+ }
415
+ }
416
+ GraniteBadgeComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteBadgeComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
417
+ GraniteBadgeComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: GraniteBadgeComponent, selector: "granite-badge", inputs: { backgroundColor: "backgroundColor", color: "color", pill: "pill" }, host: { properties: { "class.granite-badge-pill": "pill" }, classAttribute: "granite-badge" }, exportAs: ["graniteBadge"], usesOnChanges: true, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host{display:-moz-inline-flex;display:inline-flex;flex-direction:row;flex-wrap:nowrap;overflow:hidden;-ms-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap;align-items:center;background-color:var(--granite-color-signal-neutral);color:var(--granite-color-text-static-light);padding:calc(var(--granite-spacing-m) * .3125);border-radius:.3125rem;padding-inline-start:calc(var(--granite-spacing-m) * .625);padding-inline-end:calc(var(--granite-spacing-m) * .625)}:host(.granite-badge-pill){border-radius:1.5625rem}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
418
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteBadgeComponent, decorators: [{
419
+ type: Component,
420
+ args: [{ selector: 'granite-badge', exportAs: 'graniteBadge', host: {
421
+ class: 'granite-badge',
422
+ '[class.granite-badge-pill]': 'pill',
423
+ }, template: '<ng-content></ng-content>', changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:-moz-inline-flex;display:inline-flex;flex-direction:row;flex-wrap:nowrap;overflow:hidden;-ms-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap;align-items:center;background-color:var(--granite-color-signal-neutral);color:var(--granite-color-text-static-light);padding:calc(var(--granite-spacing-m) * .3125);border-radius:.3125rem;padding-inline-start:calc(var(--granite-spacing-m) * .625);padding-inline-end:calc(var(--granite-spacing-m) * .625)}:host(.granite-badge-pill){border-radius:1.5625rem}\n"] }]
424
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { backgroundColor: [{
425
+ type: Input
426
+ }], color: [{
427
+ type: Input
428
+ }], pill: [{
429
+ type: Input
430
+ }] } });
431
+
432
+ class GraniteBadgeModule {
433
+ }
434
+ GraniteBadgeModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteBadgeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
435
+ GraniteBadgeModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteBadgeModule, declarations: [GraniteBadgeComponent], imports: [CommonModule], exports: [GraniteBadgeComponent] });
436
+ GraniteBadgeModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteBadgeModule, imports: [[CommonModule]] });
437
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteBadgeModule, decorators: [{
438
+ type: NgModule,
439
+ args: [{
440
+ declarations: [GraniteBadgeComponent],
441
+ imports: [CommonModule],
442
+ exports: [GraniteBadgeComponent],
443
+ }]
444
+ }] });
445
+
446
+ class GraniteBadgeHarness extends ComponentHarness {
447
+ /**
448
+ * Gets a `HarnessPredicate` that can be used to search for a `GraniteBadgeHarness` that meets
449
+ * certain criteria.
450
+ * @param options Options for filtering which badge instances are considered a match.
451
+ * @return a `HarnessPredicate` configured with the given options.
452
+ */
453
+ static with(options = {}) {
454
+ const predicate = new HarnessPredicate(GraniteBadgeHarness, options);
455
+ predicate.addOption('text', options.text, (harness, label) => HarnessPredicate.stringMatches(harness.getText(), label));
456
+ predicate.addOption('pill', options.pill, (harness, pill) => __awaiter(this, void 0, void 0, function* () { return (yield harness.isPill()) === pill; }));
457
+ return predicate;
458
+ }
459
+ /** Gets the Badge text. */
460
+ getText() {
461
+ return __awaiter(this, void 0, void 0, function* () {
462
+ return (yield this.host()).text();
463
+ });
464
+ }
465
+ /** Whether it's a Pill type badge. */
466
+ isPill() {
467
+ return __awaiter(this, void 0, void 0, function* () {
468
+ return (yield this.host()).hasClass('granite-badge-pill');
469
+ });
470
+ }
471
+ }
472
+ GraniteBadgeHarness.hostSelector = 'granite-badge';
473
+
474
+ /**
475
+ * Returns an ease-out CSS animation string with a slightly steeper curve
476
+ * than usual.
477
+ *
478
+ * @param duration Duration in milliseconds
479
+ * @param delay Delay in milliseconds
480
+ */
481
+ function getEaseOutSteep(duration, delay) {
482
+ return (`${duration}ms ` +
483
+ (delay !== undefined ? ` ${delay}ms ` : '') +
484
+ 'cubic-bezier(0, 0, 0.2, 1)');
485
+ }
486
+ /**
487
+ * Returns an ease-out-back CSS animation string with a slightly steeper
488
+ * curve than usual.
489
+ *
490
+ * @param duration Duration in milliseconds
491
+ * @param delay Delay in milliseconds
492
+ */
493
+ function getEaseOutSteepBack(duration, delay) {
494
+ return (`${duration}ms ` +
495
+ (delay !== undefined ? ` ${delay}ms ` : '') +
496
+ 'cubic-bezier(.37,1.3,.77,1)');
497
+ }
498
+ /**
499
+ * Returns a linear CSS animation string
500
+ *
501
+ * @param duration Duration in milliseconds
502
+ * @param delay Delay in milliseconds
503
+ */
504
+ function getEaseLinear(duration, delay) {
505
+ return (`${duration}ms ` + (delay !== undefined ? ` ${delay}ms ` : '') + 'linear');
506
+ }
507
+
508
+ const easeOut120 = getEaseOutSteep(120);
509
+ /**
510
+ * Animations used by the `granite-menu` component, showing the desktop interface.
511
+ * @docs-private
512
+ */
513
+ const graniteMenuDesktopAnimations = {
514
+ transformMenuDesktop: trigger('transformMenuDesktop', [
515
+ state('void', style({
516
+ opacity: 0,
517
+ transform: 'scale(0.9)',
518
+ })),
519
+ transition('void => enter', group([
520
+ query('.granite-menu-content', animate(getEaseLinear(100), style({
521
+ opacity: 1,
522
+ }))),
523
+ animate(easeOut120, style({ transform: 'scale(1)' })),
524
+ ])),
525
+ transition('* => void', animate(getEaseLinear(100, 25), style({ opacity: 0 }))),
526
+ ]),
527
+ };
528
+
529
+ const defaultDuration = 300;
530
+ const defaultDelay = 200;
531
+ const easeOut = getEaseOutSteep(defaultDuration);
532
+ const linear = getEaseLinear(defaultDuration);
533
+ const linearDelayed = getEaseLinear(defaultDuration, defaultDelay);
534
+ /**
535
+ * Insanely fast travel somewhere on or off the stage,
536
+ * to set a great starting position.
537
+ *
538
+ * For some reason this has to be animated with > 0ms time.
539
+ * Setting style directly gets ignored.
540
+ */
541
+ const teleport = '1ms linear';
542
+ /**
543
+ * Style used by our menu stars to make grand entrée et sortie from/to below
544
+ * the viewport stage.
545
+ */
546
+ const inTheOrchestraPit = style({
547
+ transform: 'translateX(0) translateY(100%)',
548
+ opacity: 0,
549
+ });
550
+ /** Style for a menu at the center of attention, on the viewport stage */
551
+ const onStage = style({
552
+ opacity: 1,
553
+ transform: 'translateX(0) translateY(0)',
554
+ });
555
+ /**
556
+ * Style for a (sub) menu starting position at the side of the stage, waiting
557
+ * to make an entrance by sliding into view, pushing the previous (parent)
558
+ * menu off.
559
+ */
560
+ const awaitingCue = style({
561
+ opacity: 0,
562
+ transform: 'translateX(100vw) translateY(0)',
563
+ });
564
+ /**
565
+ * Style for a (parent) menu that has been pushed aside by a debutant
566
+ * (sub) menu and therefore, although maybe temporarily, left the spotlight.
567
+ *
568
+ * @param translateY Where to place on Y axis
569
+ */
570
+ const retired = style({
571
+ opacity: 1,
572
+ transform: `translateX(-100vw) translateY(0)`,
573
+ });
574
+ /**
575
+ * Style for an active (sub) menu that dances across the stage, along with its
576
+ * parent menu, as a result of the user panning. Requires an `xOffset`
577
+ * parameter for the distance.
578
+ */
579
+ const futsalShuffle = style({
580
+ transform: 'translateX({{ xOffset }}px)',
581
+ });
582
+ /**
583
+ * Style for a parent menu sweeping across the stage, right beside the
584
+ * starlet sub menu, either off the stage or back onto it (for a great comeback).
585
+ * Requires an `xOffset` parameter for the distance.
586
+ */
587
+ const moonwalk = style({
588
+ transform: 'translateX(calc(-100vw + {{ xOffset }}px))',
589
+ });
590
+ const onStageHidden = style({
591
+ opacity: 0,
592
+ transform: 'translateX(0) translateY(0)',
593
+ });
594
+ /**
595
+ * Animations used by the `granite-menu` component, showing the touch interface.
596
+ * @docs-private
597
+ */
598
+ const graniteMenuTouchAnimations = {
599
+ transformMenuTouch: trigger('transformMenuTouch', [
600
+ // Set up cast positions
601
+ state('void', awaitingCue),
602
+ state('enter, enter-from-below', onStage),
603
+ state('pan-hidden', moonwalk, { params: { xOffset: 0 } }),
604
+ state('pan', futsalShuffle, { params: { xOffset: 0 } }),
605
+ state('below-with-delay', inTheOrchestraPit),
606
+ state('hide', retired),
607
+ // General movement across the stage. Transitions to 'pan' and 'pan-hidden'
608
+ // states are intentionally left out as we want the menu position to update
609
+ // instantly as the user moves their finger.
610
+ transition('pan => enter, ' +
611
+ 'pan => enter-from-below, ' +
612
+ 'pan => void, ' +
613
+ 'enter <=> hide, ' +
614
+ 'enter-from-below <=> hide, ' +
615
+ 'pan-hidden => hide, ' +
616
+ 'pan-hidden => enter', animate(easeOut)),
617
+ transition(
618
+ // Jump straight onto the stage, from the orchestra pit.
619
+ // Excitement fills the air. Spotlight. Showtime.
620
+ 'void => enter-from-below', sequence([
621
+ animate(teleport, inTheOrchestraPit),
622
+ animate(easeOut, onStage),
623
+ ])),
624
+ transition(
625
+ // Go stand in the curtains, then make a grand entrance from the side
626
+ 'void => enter', sequence([animate(teleport, awaitingCue), animate(easeOut, onStage)])),
627
+ transition(
628
+ // Get off the stage, back into the curtains on the side
629
+ 'enter => void', animate(easeOut, awaitingCue)),
630
+ transition(
631
+ // Take the side stairs down from the stage
632
+ 'hide => below', animate(linear, retired)),
633
+ transition(
634
+ // Wait for a bit, then take the side stairs down from the stage
635
+ 'hide => below-with-delay', sequence([animate(teleport, retired), animate(linearDelayed, retired)])),
636
+ transition(
637
+ // Stage dive into the orchestra pit
638
+ 'enter => below, enter-from-below => below', sequence([animate(teleport, onStage), animate(linear, inTheOrchestraPit)])),
639
+ transition(
640
+ // Receive the standing ovations, then stage dive into the orchestra pit
641
+ 'enter => below-with-delay, enter-from-below => below-with-delay', sequence([
642
+ animate(teleport, onStage),
643
+ animate(linearDelayed, inTheOrchestraPit),
644
+ ])),
645
+ ]),
646
+ transformCloseButton: trigger('transformCloseButton', [
647
+ state('void, below, below-with-delay', onStageHidden),
648
+ state('enter, enter-from-below, pan-hidden, pan, hide', onStage),
649
+ transition('void => enter-from-below', sequence([
650
+ animate(teleport, onStageHidden),
651
+ animate(getEaseLinear(50, defaultDuration / 2), onStage),
652
+ ])),
653
+ transition('enter => below, enter-from-below => below', sequence([
654
+ animate(teleport, onStage),
655
+ animate(getEaseLinear(25), onStageHidden),
656
+ ])),
657
+ transition('enter => below-with-delay, enter-from-below => below-with-delay', sequence([
658
+ animate(teleport, onStage),
659
+ animate(getEaseLinear(50, defaultDelay), onStageHidden),
660
+ ])),
661
+ ]),
662
+ };
663
+
664
+ /**
665
+ * Injection token used to provide the parent menu to menu-specific components.
666
+ * @docs-private
667
+ */
668
+ const GRANITE_MENU_PANEL = new InjectionToken('GRANITE_MENU_PANEL');
669
+
670
+ /**
671
+ * @license
672
+ * Copyright Google LLC All Rights Reserved.
673
+ *
674
+ * Use of this source code is governed by an MIT-style license that can be
675
+ * found in the LICENSE file at https://angular.io/license
676
+ */
677
+ /**
678
+ * Throws an exception for the case when menu trigger doesn't have a valid granite-menu instance
679
+ * @docs-private
680
+ */
681
+ function throwGraniteMenuMissingError() {
682
+ throw Error(`graniteMenuTriggerFor: must pass in an granite-menu instance.
683
+
684
+ Example:
685
+ <granite-menu #menu="graniteMenu"></granite-menu>
686
+ <button [graniteMenuTriggerFor]="menu"></button>`);
687
+ }
688
+ /**
689
+ * Throws an exception for the case when menu's x-position value isn't valid.
690
+ * In other words, it doesn't match 'before' or 'after'.
691
+ * @docs-private
692
+ */
693
+ function throwGraniteMenuInvalidPositionX() {
694
+ throw Error(`xPosition value must be either 'before' or after'.
695
+ Example: <granite-menu xPosition="before" #menu="graniteMenu"></granite-menu>`);
696
+ }
697
+ /**
698
+ * Throws an exception for the case when menu's y-position value isn't valid.
699
+ * In other words, it doesn't match 'above' or 'below'.
700
+ * @docs-private
701
+ */
702
+ function throwGraniteMenuInvalidPositionY() {
703
+ throw Error(`yPosition value must be either 'above' or below'.
704
+ Example: <granite-menu yPosition="above" #menu="graniteMenu"></granite-menu>`);
705
+ }
706
+
707
+ class GraniteIconComponent {
708
+ constructor(_elementRef, renderer, ariaHidden) {
709
+ this._elementRef = _elementRef;
710
+ this.renderer = renderer;
711
+ // aria-hidden will be set to true by default, unless it's overridden by the developer
712
+ if (!ariaHidden) {
713
+ this.renderer.setAttribute(_elementRef.nativeElement, 'aria-hidden', 'true');
714
+ }
715
+ }
716
+ ngOnChanges(changes) {
717
+ if (changes.fontIcon) {
718
+ this._updateFontIcon();
719
+ }
720
+ }
721
+ _updateFontIcon() {
722
+ if (this.fontIcon !== this._previousFontIconClass) {
723
+ if (this._previousFontIconClass) {
724
+ this.renderer.removeClass(this._elementRef.nativeElement, this._previousFontIconClass);
725
+ }
726
+ if (this.fontIcon) {
727
+ this.renderer.addClass(this._elementRef.nativeElement, this.fontIcon);
728
+ }
729
+ this._previousFontIconClass = this.fontIcon;
730
+ }
731
+ }
732
+ }
733
+ GraniteIconComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteIconComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: 'aria-hidden', attribute: true }], target: i0.ɵɵFactoryTarget.Component });
734
+ GraniteIconComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: GraniteIconComponent, selector: "granite-icon", inputs: { fontIcon: "fontIcon" }, host: { attributes: { "role": "img" }, classAttribute: "granite-icon" }, usesOnChanges: true, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host.granite-icon{background-repeat:no-repeat;display:inline-block;padding:0 calc(var(--granite-spacing-xs) / 2);font-size:1em;line-height:1em;position:relative;top:.1em}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
735
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteIconComponent, decorators: [{
736
+ type: Component,
737
+ args: [{ selector: 'granite-icon', template: '<ng-content></ng-content>', host: {
738
+ role: 'img',
739
+ class: 'granite-icon',
740
+ }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host.granite-icon{background-repeat:no-repeat;display:inline-block;padding:0 calc(var(--granite-spacing-xs) / 2);font-size:1em;line-height:1em;position:relative;top:.1em}\n"] }]
741
+ }], ctorParameters: function () {
742
+ return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: undefined, decorators: [{
743
+ type: Attribute,
744
+ args: ['aria-hidden']
745
+ }] }];
746
+ }, propDecorators: { fontIcon: [{
747
+ type: Input
748
+ }] } });
749
+
750
+ class GraniteMenuItemComponent {
751
+ constructor(_elementRef, _focusMonitor, _parentMenu) {
752
+ this._elementRef = _elementRef;
753
+ this._focusMonitor = _focusMonitor;
754
+ this._parentMenu = _parentMenu;
755
+ /** ARIA role for the menu item. */
756
+ this.role = 'menuitem';
757
+ /** Stream that emits when the menu item is hovered. */
758
+ // eslint-disable-next-line rxjs/no-exposed-subjects
759
+ this._hovered = new Subject();
760
+ /** Stream that emits when the menu item is focused. */
761
+ // eslint-disable-next-line rxjs/no-exposed-subjects
762
+ this._focused = new Subject();
763
+ /** Whether the menu item acts as a trigger for a sub-menu (used for styling) */
764
+ this._triggersSubmenu = false;
765
+ /**
766
+ * Whether the menu item is highlighted, e.g. in the "breadcrumb" parent chain
767
+ * of sub menu trigger items
768
+ */
769
+ this._highlighted = false;
770
+ // Start monitoring the element so it gets the appropriate focused classes. We want
771
+ // to show the focus style for menu items only when the focus was not caused by a
772
+ // mouse or touch interaction.
773
+ _focusMonitor.monitor(this._elementRef, false);
774
+ }
775
+ ngOnDestroy() {
776
+ this._focusMonitor.stopMonitoring(this._elementRef);
777
+ this._hovered.complete();
778
+ this._focused.complete();
779
+ }
780
+ /** Focuses the menu item. */
781
+ focus(origin = 'program', options) {
782
+ this._focusMonitor.focusVia(this._getHostElement(), origin, options);
783
+ this._focused.next(this);
784
+ }
785
+ /** Returns the host DOM element. */
786
+ _getHostElement() {
787
+ return this._elementRef.nativeElement;
788
+ }
789
+ }
790
+ GraniteMenuItemComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteMenuItemComponent, deps: [{ token: i0.ElementRef }, { token: i1.FocusMonitor }, { token: GRANITE_MENU_PANEL, optional: true }], target: i0.ɵɵFactoryTarget.Component });
791
+ GraniteMenuItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: GraniteMenuItemComponent, selector: "[graniteMenuItem]", inputs: { role: "role" }, host: { listeners: { "mouseenter": "_hovered.next(this)" }, properties: { "attr.role": "role", "class.granite-menu-item": "true", "class.granite-menu-item-highlighted": "_highlighted", "class.granite-menu-item-submenu-trigger": "_triggersSubmenu", "class.granite-device-output-touch": "_clientOutput?.device === \"touch\"" } }, exportAs: ["graniteMenuItem"], ngImport: i0, template: `<ng-content></ng-content>
792
+ <ng-container *ngIf="_triggersSubmenu">
793
+ <granite-icon
794
+ class="caret-left"
795
+ [fontIcon]="'icon-caret-left'"
796
+ ></granite-icon>
797
+ <granite-icon
798
+ class="caret-right"
799
+ [fontIcon]="'icon-caret-right'"
800
+ ></granite-icon>
801
+ </ng-container>`, isInline: true, styles: [":host{display:block;position:relative;line-height:2rem;padding:0 var(--granite-spacing-s);width:100%;max-width:100%;-webkit-user-select:none;user-select:none;cursor:pointer;outline:none;border:none;-webkit-tap-highlight-color:transparent;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:start;text-decoration:none;background-color:var(--granite-color-background-variant);color:var(--granite-color-text);font-size:var(--granite-font-size-body-small);font-family:inherit}@media (hover: hover) and (pointer: fine){:host:hover:not(.granite-title):not([disabled]){background:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active)}}@media (hover: none) and (pointer: coarse){:host:active:not(.granite-title):not([disabled]){background:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active)}}:host.granite-title{-webkit-user-select:none;user-select:none;display:flex;align-items:center;line-height:1.5rem;width:100%;outline:none;border:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-decoration:none;color:var(--granite-color-text);font-size:var(--granite-font-size-micro);font-weight:var(--granite-font-weight-bold);cursor:default}:host.cdk-mouse-focused,:host.cdk-program-focused,:host.cdk-keyboard-focused,:host.granite-menu-item-highlighted{background:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active)}:host granite-icon{position:absolute;font-size:var(--granite-font-size-body-small);color:inherit;top:50%;transform:translateY(-50%)}:host.granite-menu-item-submenu-trigger{padding-inline-end:var(--granite-spacing-l)}html[dir=ltr] :host.granite-menu-item-submenu-trigger granite-icon{right:var(--granite-spacing-xs)}:host-context([dir=ltr]) :host.granite-menu-item-submenu-trigger granite-icon{right:var(--granite-spacing-xs)}html[dir=rtl] :host.granite-menu-item-submenu-trigger granite-icon{left:var(--granite-spacing-xs)}:host-context([dir=rtl]) :host.granite-menu-item-submenu-trigger granite-icon{left:var(--granite-spacing-xs)}[dir=rtl] :host.granite-menu-item-submenu-trigger granite-icon.caret-right{display:none}[dir=ltr] :host.granite-menu-item-submenu-trigger granite-icon.caret-left{display:none}:host.granite-divider-top{border-top:.0625rem solid var(--granite-color-border-soft)}:host.granite-divider-bottom{border-bottom:.0625rem solid var(--granite-color-border-soft)}:host.granite-device-output-touch{line-height:3rem;font-size:var(--granite-font-size-body-small);text-align:center;padding:0 var(--granite-spacing-l)}:host.granite-device-output-touch.granite-title{padding:0;justify-content:center;line-height:1.5rem;font-size:var(--granite-font-size-micro)}:host.granite-device-output-touch.granite-menu-item-back-trigger,:host.granite-device-output-touch.granite-menu-item-submenu-trigger{padding:0 var(--granite-spacing-l)}:host.granite-device-output-touch.granite-menu-item-title{line-height:3rem;height:3rem;font-size:var(--granite-font-size-micro);color:var(--granite-color-text-weak)}@media (hover: none) and (pointer: coarse){:host.granite-device-output-touch.granite-menu-item-title:active{background:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active)}}html[dir=ltr] :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon{left:var(--granite-spacing-xs)}:host-context([dir=ltr]) :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon{left:var(--granite-spacing-xs)}html[dir=rtl] :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon{right:var(--granite-spacing-xs)}:host-context([dir=rtl]) :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon{right:var(--granite-spacing-xs)}[dir=rtl] :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon.caret-left{display:none}[dir=ltr] :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon.caret-right{display:none}:host:disabled:not(.granite-menu-item-title){opacity:.4;cursor:default}\n"], components: [{ type: GraniteIconComponent, selector: "granite-icon", inputs: ["fontIcon"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
802
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteMenuItemComponent, decorators: [{
803
+ type: Component,
804
+ args: [{ selector: '[graniteMenuItem]', template: `<ng-content></ng-content>
805
+ <ng-container *ngIf="_triggersSubmenu">
806
+ <granite-icon
807
+ class="caret-left"
808
+ [fontIcon]="'icon-caret-left'"
809
+ ></granite-icon>
810
+ <granite-icon
811
+ class="caret-right"
812
+ [fontIcon]="'icon-caret-right'"
813
+ ></granite-icon>
814
+ </ng-container>`, exportAs: 'graniteMenuItem', host: {
815
+ '[attr.role]': 'role',
816
+ '[class.granite-menu-item]': 'true',
817
+ '[class.granite-menu-item-highlighted]': '_highlighted',
818
+ '[class.granite-menu-item-submenu-trigger]': '_triggersSubmenu',
819
+ //#region --- Touch device customizations ---
820
+ '[class.granite-device-output-touch]': '_clientOutput?.device === "touch"',
821
+ //#endregion --- Touch device customizations ---
822
+ '(mouseenter)': '_hovered.next(this)',
823
+ }, styles: [":host{display:block;position:relative;line-height:2rem;padding:0 var(--granite-spacing-s);width:100%;max-width:100%;-webkit-user-select:none;user-select:none;cursor:pointer;outline:none;border:none;-webkit-tap-highlight-color:transparent;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:start;text-decoration:none;background-color:var(--granite-color-background-variant);color:var(--granite-color-text);font-size:var(--granite-font-size-body-small);font-family:inherit}@media (hover: hover) and (pointer: fine){:host:hover:not(.granite-title):not([disabled]){background:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active)}}@media (hover: none) and (pointer: coarse){:host:active:not(.granite-title):not([disabled]){background:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active)}}:host.granite-title{-webkit-user-select:none;user-select:none;display:flex;align-items:center;line-height:1.5rem;width:100%;outline:none;border:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-decoration:none;color:var(--granite-color-text);font-size:var(--granite-font-size-micro);font-weight:var(--granite-font-weight-bold);cursor:default}:host.cdk-mouse-focused,:host.cdk-program-focused,:host.cdk-keyboard-focused,:host.granite-menu-item-highlighted{background:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active)}:host granite-icon{position:absolute;font-size:var(--granite-font-size-body-small);color:inherit;top:50%;transform:translateY(-50%)}:host.granite-menu-item-submenu-trigger{padding-inline-end:var(--granite-spacing-l)}html[dir=ltr] :host.granite-menu-item-submenu-trigger granite-icon{right:var(--granite-spacing-xs)}:host-context([dir=ltr]) :host.granite-menu-item-submenu-trigger granite-icon{right:var(--granite-spacing-xs)}html[dir=rtl] :host.granite-menu-item-submenu-trigger granite-icon{left:var(--granite-spacing-xs)}:host-context([dir=rtl]) :host.granite-menu-item-submenu-trigger granite-icon{left:var(--granite-spacing-xs)}[dir=rtl] :host.granite-menu-item-submenu-trigger granite-icon.caret-right{display:none}[dir=ltr] :host.granite-menu-item-submenu-trigger granite-icon.caret-left{display:none}:host.granite-divider-top{border-top:.0625rem solid var(--granite-color-border-soft)}:host.granite-divider-bottom{border-bottom:.0625rem solid var(--granite-color-border-soft)}:host.granite-device-output-touch{line-height:3rem;font-size:var(--granite-font-size-body-small);text-align:center;padding:0 var(--granite-spacing-l)}:host.granite-device-output-touch.granite-title{padding:0;justify-content:center;line-height:1.5rem;font-size:var(--granite-font-size-micro)}:host.granite-device-output-touch.granite-menu-item-back-trigger,:host.granite-device-output-touch.granite-menu-item-submenu-trigger{padding:0 var(--granite-spacing-l)}:host.granite-device-output-touch.granite-menu-item-title{line-height:3rem;height:3rem;font-size:var(--granite-font-size-micro);color:var(--granite-color-text-weak)}@media (hover: none) and (pointer: coarse){:host.granite-device-output-touch.granite-menu-item-title:active{background:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active)}}html[dir=ltr] :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon{left:var(--granite-spacing-xs)}:host-context([dir=ltr]) :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon{left:var(--granite-spacing-xs)}html[dir=rtl] :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon{right:var(--granite-spacing-xs)}:host-context([dir=rtl]) :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon{right:var(--granite-spacing-xs)}[dir=rtl] :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon.caret-left{display:none}[dir=ltr] :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon.caret-right{display:none}:host:disabled:not(.granite-menu-item-title){opacity:.4;cursor:default}\n"] }]
824
+ }], ctorParameters: function () {
825
+ return [{ type: i0.ElementRef }, { type: i1.FocusMonitor }, { type: undefined, decorators: [{
826
+ type: Inject,
827
+ args: [GRANITE_MENU_PANEL]
828
+ }, {
829
+ type: Optional
830
+ }] }];
831
+ }, propDecorators: { role: [{
832
+ type: Input
833
+ }] } });
834
+
835
+ /** Counter for panel ID generation */
836
+ let menuPanelUid = 0;
837
+ /** Menu panel animation default transform values */
838
+ const transformMenuDefault = {
839
+ value: 'void',
840
+ params: {
841
+ xOffset: 0,
842
+ },
843
+ };
844
+ /** Base class with all of the menu functionality. */
845
+ // eslint-disable-next-line @angular-eslint/directive-class-suffix
846
+ class _MenuBaseComponent {
847
+ constructor(_changeDetectorRef) {
848
+ this._changeDetectorRef = _changeDetectorRef;
849
+ this.openOnHover = true;
850
+ /**
851
+ * Event emitted when the menu is closed
852
+ */
853
+ this.closed = new EventEmitter();
854
+ /**
855
+ * Used for locating the panel in tests and setting the aria-control attribute
856
+ * for the menu trigger.
857
+ */
858
+ this.panelId = `granite-menu-panel-${menuPanelUid++}`;
859
+ /** Whether to show back button in touch menu title bar */
860
+ this.showBackButton = false;
861
+ /** Whether to show touch menu title bar */
862
+ this.showTitle = false;
863
+ /** Whether to add a close button below the menu */
864
+ this.showCloseButton = false;
865
+ /** Observable current state of the panel animation. */
866
+ // eslint-disable-next-line rxjs/no-exposed-subjects
867
+ this._transformMenu = new BehaviorSubject(transformMenuDefault);
868
+ /** Emits whenever an animation on the menu completes. */
869
+ // eslint-disable-next-line rxjs/no-exposed-subjects
870
+ this._animationDone = new Subject();
871
+ this._menuEmpty$ = new BehaviorSubject(false);
872
+ // eslint-disable-next-line @typescript-eslint/member-ordering
873
+ this._isMenuEmpty$ = combineLatest([
874
+ this._menuEmpty$,
875
+ this._animationDone,
876
+ ]).pipe(filter(([m, a]) => m && a != null), map(() => true));
877
+ /** Only the direct descendant menu items. */
878
+ this._directDescendantItems = new QueryList();
879
+ /** Subscription to tab events on the menu panel */
880
+ this._tabSubscription = Subscription.EMPTY;
881
+ this._xPosition = 'after';
882
+ this._yPosition = 'below';
883
+ /**
884
+ * Current horizontal offset. Used with `pan` and `pan-hidden`
885
+ * animation states.
886
+ */
887
+ this.xOffset = 0;
888
+ }
889
+ /** Position of the menu in the X axis. */
890
+ get xPosition() {
891
+ return this._xPosition;
892
+ }
893
+ set xPosition(value) {
894
+ if (value !== 'before' && value !== 'after') {
895
+ throwGraniteMenuInvalidPositionX();
896
+ }
897
+ this._xPosition = value;
898
+ }
899
+ /** Position of the menu in the Y axis. */
900
+ get yPosition() {
901
+ return this._yPosition;
902
+ }
903
+ set yPosition(value) {
904
+ if (value !== 'above' && value !== 'below') {
905
+ throwGraniteMenuInvalidPositionY();
906
+ }
907
+ this._yPosition = value;
908
+ }
909
+ /** Current state of the panel animation. */
910
+ set _panelAnimationState(state) {
911
+ this._transformMenu.next({
912
+ value: state,
913
+ params: { xOffset: this.xOffset },
914
+ });
915
+ }
916
+ ngAfterContentChecked() {
917
+ this._menuEmpty$.next(this._allItems.length < 1 ? true : false);
918
+ }
919
+ ngAfterContentInit() {
920
+ this._updateDirectDescendants();
921
+ this._keyManager = new FocusKeyManager(this._directDescendantItems)
922
+ .withWrap()
923
+ .skipPredicate((menuItem) => {
924
+ const hostElement = menuItem._getHostElement();
925
+ return hostElement instanceof HTMLButtonElement
926
+ ? hostElement.disabled
927
+ : hostElement.hasAttribute('graniteTitle');
928
+ });
929
+ this._tabSubscription = this._keyManager.tabOut.subscribe(() => {
930
+ this.closed.emit('tab');
931
+ });
932
+ // If a user manually (programatically) focuses a menu item, we need to reflect that focus
933
+ // change back to the key manager. Note that we don't need to unsubscribe here because _focused
934
+ // is internal and we know that it gets completed on destroy.
935
+ this._directDescendantItems.changes
936
+ .pipe(startWith(this._directDescendantItems), switchMap((items) => merge(...items.map((item) => item._focused))))
937
+ .subscribe((focusedItem) => this._keyManager.updateActiveItem(focusedItem));
938
+ }
939
+ ngOnDestroy() {
940
+ this._directDescendantItems.destroy();
941
+ this._tabSubscription.unsubscribe();
942
+ this.closed.complete();
943
+ }
944
+ /**
945
+ * Stream that combines the `_hovered` observables of all the menu's items
946
+ * into a single observable. Emits whenever the hovered menu item changes.
947
+ */
948
+ _hovered() {
949
+ // Coerce the `changes` property because Angular types it as `Observable<any>`
950
+ const itemChanges = this._directDescendantItems.changes;
951
+ return itemChanges.pipe(startWith(this._directDescendantItems),
952
+ // Hovering is not applicable when producing touch output
953
+ filter(() => {
954
+ var _a;
955
+ return ((_a = this._clientOutput) === null || _a === void 0 ? void 0 : _a.device) !== 'touch';
956
+ }), switchMap((items) => merge(...items.map((item) => item._hovered))));
957
+ }
958
+ /** Handle a keyboard event from the menu, delegating to the appropriate action. */
959
+ _handleKeydown(event) {
960
+ const key = event.key;
961
+ const manager = this._keyManager;
962
+ switch (key) {
963
+ case 'Escape':
964
+ if (!hasModifierKey(event)) {
965
+ event.preventDefault();
966
+ this.closed.emit('keydown');
967
+ }
968
+ break;
969
+ case 'ArrowLeft':
970
+ if (this.parentMenu && this.direction === 'ltr') {
971
+ this.closed.emit('keydown');
972
+ }
973
+ break;
974
+ case 'ArrowRight':
975
+ if (this.parentMenu && this.direction === 'rtl') {
976
+ this.closed.emit('keydown');
977
+ }
978
+ break;
979
+ case 'Home':
980
+ case 'End':
981
+ if (!hasModifierKey(event)) {
982
+ key === 'Home'
983
+ ? manager.setFirstItemActive()
984
+ : manager.setLastItemActive();
985
+ event.preventDefault();
986
+ }
987
+ break;
988
+ default:
989
+ if (key === 'ArrowUp' || key === 'ArrowDown') {
990
+ manager.setFocusOrigin('keyboard');
991
+ }
992
+ manager.onKeydown(event);
993
+ }
994
+ }
995
+ /**
996
+ * Focus the first item in the menu.
997
+ * @param origin Action from which the focus originated. Used to set the correct styling.
998
+ */
999
+ focusFirstItem(origin = 'program') {
1000
+ this._keyManager.setFocusOrigin(origin).setFirstItemActive();
1001
+ }
1002
+ /** Updates the `showTitle` property for touch device UI */
1003
+ _updateShowTitle() {
1004
+ this.showTitle = !!this.title || this.showBackButton;
1005
+ }
1006
+ /** Starts the enter animation */
1007
+ _startAnimation() {
1008
+ this._panelAnimationState = 'enter';
1009
+ }
1010
+ /** Resets the panel animation to its initial state. */
1011
+ _resetAnimation() {
1012
+ this._panelAnimationState = 'void';
1013
+ }
1014
+ /**
1015
+ * Starts the 'below' animation, moving a menu down, out of view below the
1016
+ * viewport. Used to close the whole menu, for example when clicking
1017
+ * the backdrop.
1018
+ */
1019
+ _startTouchCloseDownAnimation() {
1020
+ this._panelAnimationState = 'below';
1021
+ }
1022
+ /**
1023
+ * Starts the 'below-with-delay' animation, moving a menu down, out of view below the
1024
+ * viewport. Used to close the whole menu as a response to the user tapping
1025
+ * a menu item. There is a short delay before the animation starts, to that
1026
+ * the user gets a visual feedback on what item was selected.
1027
+ */
1028
+ _startTouchCloseDownAnimationWithDelay() {
1029
+ this._panelAnimationState = 'below-with-delay';
1030
+ }
1031
+ /**
1032
+ * Starts the 'void' animation, moving a (sub) menu out of view to the side
1033
+ * of the viewport. Used when going "back" from a sub menu.
1034
+ */
1035
+ _startTouchCloseSideAnimation() {
1036
+ this._resetAnimation();
1037
+ }
1038
+ /**
1039
+ * Starts the enter-from-below animation, moving a (root) menu into view,
1040
+ * Animates upwards from a starting position below the viewport.
1041
+ */
1042
+ _startTouchRootEnterAnimation() {
1043
+ this._panelAnimationState = 'enter-from-below';
1044
+ this.xOffset = 0;
1045
+ }
1046
+ /** Starts the enter animation, moving a (sub) menu into view. */
1047
+ _startTouchSubmenuEnterAnimation() {
1048
+ this._panelAnimationState = 'enter';
1049
+ this.xOffset = 0;
1050
+ }
1051
+ /**
1052
+ * Starts the pan animation, to position a submenu in a response
1053
+ * to user dragging sideways (panning).
1054
+ */
1055
+ _startTouchPanAnimation(xOffset) {
1056
+ this._panelAnimationState = 'pan';
1057
+ this.xOffset = xOffset;
1058
+ }
1059
+ /**
1060
+ * Starts the pan-hidden animation, to position a parent menu next to an
1061
+ * active submenu that the user is dragging sideways (panning).
1062
+ */
1063
+ _startTouchHidePanAnimation(xOffset) {
1064
+ this._panelAnimationState = 'pan-hidden';
1065
+ this.xOffset = xOffset;
1066
+ }
1067
+ /**
1068
+ * Starts the hide animation, to make a parent menu slide out to leave
1069
+ * space for a submenu.
1070
+ */
1071
+ _startTouchHideAnimation() {
1072
+ this._panelAnimationState = 'hide';
1073
+ this.xOffset = 0;
1074
+ }
1075
+ /** Callback that is invoked when the panel animation completes. */
1076
+ _onAnimationDone(event) {
1077
+ this._animationDone.next(event);
1078
+ this._isAnimating = false;
1079
+ }
1080
+ _onAnimationStart(event) {
1081
+ this._isAnimating = true;
1082
+ // Scroll the content element to the top as soon as the animation starts. This is necessary,
1083
+ // because we move focus to the first item while it's still being animated, which can throw
1084
+ // the browser off when it determines the scroll position. Alternatively we can move focus
1085
+ // when the animation is done, however moving focus asynchronously will interrupt screen
1086
+ // readers which are in the process of reading out the menu already. We take the `element`
1087
+ // from the `event` since we can't use a `ViewChild` to access the pane.
1088
+ if ((event.toState === 'enter' || event.toState === 'enter-from-below') &&
1089
+ this._keyManager.activeItemIndex === 0) {
1090
+ event.element.scrollTop = 0;
1091
+ }
1092
+ }
1093
+ /**
1094
+ * Handle click on the menu by emitting on the `closed` emitter
1095
+ * with a `click` reason
1096
+ */
1097
+ _handleClick() {
1098
+ this.closed.emit('click');
1099
+ }
1100
+ /**
1101
+ * Handle click on the close button by emitting on the `closed` emitter
1102
+ * without any particular reason
1103
+ */
1104
+ _handleCloseClick() {
1105
+ this.closed.emit();
1106
+ }
1107
+ /**
1108
+ * Handle click on the back icon by emitting on the `clicked` emitter
1109
+ */
1110
+ _handleBackClick(e) {
1111
+ if (this.showBackButton) {
1112
+ // Close submenu keydown-style: close only this menu and leave parents open
1113
+ this.closed.emit('keydown');
1114
+ }
1115
+ e.stopPropagation();
1116
+ }
1117
+ /**
1118
+ * Update client device information for the menu and its menu items.
1119
+ */
1120
+ _setDevice(clientInput, clientOutput) {
1121
+ this._clientInput = clientInput;
1122
+ this._clientOutput = clientOutput;
1123
+ this._directDescendantItems.forEach((item) => {
1124
+ item._clientInput = clientInput;
1125
+ item._clientOutput = clientOutput;
1126
+ });
1127
+ this._changeDetectorRef.markForCheck();
1128
+ }
1129
+ /**
1130
+ * Resets the active item in the menu. This is used when the menu is opened, allowing
1131
+ * the user to start from the first option when pressing the down arrow.
1132
+ */
1133
+ resetActiveItem() {
1134
+ this._keyManager.setActiveItem(-1);
1135
+ }
1136
+ /**
1137
+ * Sets up a stream that will keep track of any newly-added menu items and will update the list
1138
+ * of direct descendants. We collect the descendants this way, because `_allItems` can include
1139
+ * items that are part of child menus, and using a custom way of registering items is unreliable
1140
+ * when it comes to maintaining the item order.
1141
+ */
1142
+ _updateDirectDescendants() {
1143
+ this._allItems.changes
1144
+ .pipe(startWith(this._allItems))
1145
+ .subscribe((items) => {
1146
+ this._directDescendantItems.reset(items.filter((item) => item._parentMenu === this));
1147
+ this._directDescendantItems.notifyOnChanges();
1148
+ });
1149
+ }
1150
+ }
1151
+ _MenuBaseComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: _MenuBaseComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
1152
+ _MenuBaseComponent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.11", type: _MenuBaseComponent, inputs: { xPosition: "xPosition", yPosition: "yPosition", title: "title", closeLabel: "closeLabel", openOnHover: "openOnHover" }, outputs: { closed: "closed" }, queries: [{ propertyName: "_allItems", predicate: GraniteMenuItemComponent, descendants: true }], viewQueries: [{ propertyName: "templateRef", first: true, predicate: TemplateRef, descendants: true }], ngImport: i0 });
1153
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: _MenuBaseComponent, decorators: [{
1154
+ type: Directive
1155
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { xPosition: [{
1156
+ type: Input
1157
+ }], yPosition: [{
1158
+ type: Input
1159
+ }], title: [{
1160
+ type: Input
1161
+ }], closeLabel: [{
1162
+ type: Input
1163
+ }], openOnHover: [{
1164
+ type: Input
1165
+ }], templateRef: [{
1166
+ type: ViewChild,
1167
+ args: [TemplateRef]
1168
+ }], _allItems: [{
1169
+ type: ContentChildren,
1170
+ args: [GraniteMenuItemComponent, { descendants: true }]
1171
+ }], closed: [{
1172
+ type: Output
1173
+ }] } });
1174
+
1175
+ class GraniteMenuTouchTitleItemComponent {
1176
+ constructor(
1177
+ /** If this is an item on a _submenu_, its parent menu will have a parent */
1178
+ _parentMenu) {
1179
+ /**
1180
+ * Whether the menu item acts as a trigger to return to a parent menu
1181
+ * (used for styling)
1182
+ */
1183
+ this._triggersBack = false;
1184
+ this._triggersBack = !!_parentMenu.parentMenu;
1185
+ }
1186
+ }
1187
+ GraniteMenuTouchTitleItemComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteMenuTouchTitleItemComponent, deps: [{ token: GRANITE_MENU_PANEL, optional: true }], target: i0.ɵɵFactoryTarget.Component });
1188
+ GraniteMenuTouchTitleItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: GraniteMenuTouchTitleItemComponent, selector: "[graniteMenuTouchTitleItem]", host: { properties: { "class.granite-menu-item-title": "true", "class.granite-menu-item-back-trigger": "_triggersBack", "class.granite-device-output-touch": "true" } }, exportAs: ["graniteMenuTouchTitleItem"], ngImport: i0, template: `
1189
+ <ng-container *ngIf="_triggersBack">
1190
+ <granite-icon
1191
+ class="caret-left"
1192
+ [fontIcon]="'icon-caret-left'"
1193
+ ></granite-icon>
1194
+ <granite-icon
1195
+ class="caret-right"
1196
+ [fontIcon]="'icon-caret-right'"
1197
+ ></granite-icon>
1198
+ </ng-container>
1199
+ <ng-content></ng-content>
1200
+ `, isInline: true, styles: [":host{display:block;position:relative;line-height:2rem;padding:0 var(--granite-spacing-s);width:100%;max-width:100%;-webkit-user-select:none;user-select:none;cursor:pointer;outline:none;border:none;-webkit-tap-highlight-color:transparent;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:start;text-decoration:none;background-color:var(--granite-color-background-variant);color:var(--granite-color-text);font-size:var(--granite-font-size-body-small);font-family:inherit}@media (hover: hover) and (pointer: fine){:host:hover:not(.granite-title):not([disabled]){background:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active)}}@media (hover: none) and (pointer: coarse){:host:active:not(.granite-title):not([disabled]){background:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active)}}:host.granite-title{-webkit-user-select:none;user-select:none;display:flex;align-items:center;line-height:1.5rem;width:100%;outline:none;border:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-decoration:none;color:var(--granite-color-text);font-size:var(--granite-font-size-micro);font-weight:var(--granite-font-weight-bold);cursor:default}:host.cdk-mouse-focused,:host.cdk-program-focused,:host.cdk-keyboard-focused,:host.granite-menu-item-highlighted{background:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active)}:host granite-icon{position:absolute;font-size:var(--granite-font-size-body-small);color:inherit;top:50%;transform:translateY(-50%)}:host.granite-menu-item-submenu-trigger{padding-inline-end:var(--granite-spacing-l)}html[dir=ltr] :host.granite-menu-item-submenu-trigger granite-icon{right:var(--granite-spacing-xs)}:host-context([dir=ltr]) :host.granite-menu-item-submenu-trigger granite-icon{right:var(--granite-spacing-xs)}html[dir=rtl] :host.granite-menu-item-submenu-trigger granite-icon{left:var(--granite-spacing-xs)}:host-context([dir=rtl]) :host.granite-menu-item-submenu-trigger granite-icon{left:var(--granite-spacing-xs)}[dir=rtl] :host.granite-menu-item-submenu-trigger granite-icon.caret-right{display:none}[dir=ltr] :host.granite-menu-item-submenu-trigger granite-icon.caret-left{display:none}:host.granite-divider-top{border-top:.0625rem solid var(--granite-color-border-soft)}:host.granite-divider-bottom{border-bottom:.0625rem solid var(--granite-color-border-soft)}:host.granite-device-output-touch{line-height:3rem;font-size:var(--granite-font-size-body-small);text-align:center;padding:0 var(--granite-spacing-l)}:host.granite-device-output-touch.granite-title{padding:0;justify-content:center;line-height:1.5rem;font-size:var(--granite-font-size-micro)}:host.granite-device-output-touch.granite-menu-item-back-trigger,:host.granite-device-output-touch.granite-menu-item-submenu-trigger{padding:0 var(--granite-spacing-l)}:host.granite-device-output-touch.granite-menu-item-title{line-height:3rem;height:3rem;font-size:var(--granite-font-size-micro);color:var(--granite-color-text-weak)}@media (hover: none) and (pointer: coarse){:host.granite-device-output-touch.granite-menu-item-title:active{background:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active)}}html[dir=ltr] :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon{left:var(--granite-spacing-xs)}:host-context([dir=ltr]) :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon{left:var(--granite-spacing-xs)}html[dir=rtl] :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon{right:var(--granite-spacing-xs)}:host-context([dir=rtl]) :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon{right:var(--granite-spacing-xs)}[dir=rtl] :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon.caret-left{display:none}[dir=ltr] :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon.caret-right{display:none}:host:disabled:not(.granite-menu-item-title){opacity:.4;cursor:default}\n"], components: [{ type: GraniteIconComponent, selector: "granite-icon", inputs: ["fontIcon"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
1201
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteMenuTouchTitleItemComponent, decorators: [{
1202
+ type: Component,
1203
+ args: [{ selector: '[graniteMenuTouchTitleItem]', template: `
1204
+ <ng-container *ngIf="_triggersBack">
1205
+ <granite-icon
1206
+ class="caret-left"
1207
+ [fontIcon]="'icon-caret-left'"
1208
+ ></granite-icon>
1209
+ <granite-icon
1210
+ class="caret-right"
1211
+ [fontIcon]="'icon-caret-right'"
1212
+ ></granite-icon>
1213
+ </ng-container>
1214
+ <ng-content></ng-content>
1215
+ `, exportAs: 'graniteMenuTouchTitleItem', host: {
1216
+ '[class.granite-menu-item-title]': 'true',
1217
+ '[class.granite-menu-item-back-trigger]': '_triggersBack',
1218
+ '[class.granite-device-output-touch]': 'true',
1219
+ }, styles: [":host{display:block;position:relative;line-height:2rem;padding:0 var(--granite-spacing-s);width:100%;max-width:100%;-webkit-user-select:none;user-select:none;cursor:pointer;outline:none;border:none;-webkit-tap-highlight-color:transparent;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:start;text-decoration:none;background-color:var(--granite-color-background-variant);color:var(--granite-color-text);font-size:var(--granite-font-size-body-small);font-family:inherit}@media (hover: hover) and (pointer: fine){:host:hover:not(.granite-title):not([disabled]){background:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active)}}@media (hover: none) and (pointer: coarse){:host:active:not(.granite-title):not([disabled]){background:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active)}}:host.granite-title{-webkit-user-select:none;user-select:none;display:flex;align-items:center;line-height:1.5rem;width:100%;outline:none;border:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-decoration:none;color:var(--granite-color-text);font-size:var(--granite-font-size-micro);font-weight:var(--granite-font-weight-bold);cursor:default}:host.cdk-mouse-focused,:host.cdk-program-focused,:host.cdk-keyboard-focused,:host.granite-menu-item-highlighted{background:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active)}:host granite-icon{position:absolute;font-size:var(--granite-font-size-body-small);color:inherit;top:50%;transform:translateY(-50%)}:host.granite-menu-item-submenu-trigger{padding-inline-end:var(--granite-spacing-l)}html[dir=ltr] :host.granite-menu-item-submenu-trigger granite-icon{right:var(--granite-spacing-xs)}:host-context([dir=ltr]) :host.granite-menu-item-submenu-trigger granite-icon{right:var(--granite-spacing-xs)}html[dir=rtl] :host.granite-menu-item-submenu-trigger granite-icon{left:var(--granite-spacing-xs)}:host-context([dir=rtl]) :host.granite-menu-item-submenu-trigger granite-icon{left:var(--granite-spacing-xs)}[dir=rtl] :host.granite-menu-item-submenu-trigger granite-icon.caret-right{display:none}[dir=ltr] :host.granite-menu-item-submenu-trigger granite-icon.caret-left{display:none}:host.granite-divider-top{border-top:.0625rem solid var(--granite-color-border-soft)}:host.granite-divider-bottom{border-bottom:.0625rem solid var(--granite-color-border-soft)}:host.granite-device-output-touch{line-height:3rem;font-size:var(--granite-font-size-body-small);text-align:center;padding:0 var(--granite-spacing-l)}:host.granite-device-output-touch.granite-title{padding:0;justify-content:center;line-height:1.5rem;font-size:var(--granite-font-size-micro)}:host.granite-device-output-touch.granite-menu-item-back-trigger,:host.granite-device-output-touch.granite-menu-item-submenu-trigger{padding:0 var(--granite-spacing-l)}:host.granite-device-output-touch.granite-menu-item-title{line-height:3rem;height:3rem;font-size:var(--granite-font-size-micro);color:var(--granite-color-text-weak)}@media (hover: none) and (pointer: coarse){:host.granite-device-output-touch.granite-menu-item-title:active{background:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active)}}html[dir=ltr] :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon{left:var(--granite-spacing-xs)}:host-context([dir=ltr]) :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon{left:var(--granite-spacing-xs)}html[dir=rtl] :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon{right:var(--granite-spacing-xs)}:host-context([dir=rtl]) :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon{right:var(--granite-spacing-xs)}[dir=rtl] :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon.caret-left{display:none}[dir=ltr] :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon.caret-right{display:none}:host:disabled:not(.granite-menu-item-title){opacity:.4;cursor:default}\n"] }]
1220
+ }], ctorParameters: function () {
1221
+ return [{ type: _MenuBaseComponent, decorators: [{
1222
+ type: Inject,
1223
+ args: [GRANITE_MENU_PANEL]
1224
+ }, {
1225
+ type: Optional
1226
+ }] }];
1227
+ } });
1228
+
1229
+ class GraniteMenuTouchCloseComponent {
1230
+ }
1231
+ GraniteMenuTouchCloseComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteMenuTouchCloseComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1232
+ GraniteMenuTouchCloseComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: GraniteMenuTouchCloseComponent, selector: "[graniteMenuTouchCloseItem]", host: { properties: { "class.granite-device-output-touch": "true" } }, exportAs: ["graniteMenuTouchCloseItem"], ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host{display:block;position:relative;line-height:2rem;padding:0 var(--granite-spacing-s);width:100%;max-width:100%;-webkit-user-select:none;user-select:none;cursor:pointer;outline:none;border:none;-webkit-tap-highlight-color:transparent;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:start;text-decoration:none;background-color:var(--granite-color-background-variant);color:var(--granite-color-text);font-size:var(--granite-font-size-body-small);font-family:inherit}@media (hover: hover) and (pointer: fine){:host:hover:not(.granite-title):not([disabled]){background:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active)}}@media (hover: none) and (pointer: coarse){:host:active:not(.granite-title):not([disabled]){background:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active)}}:host.granite-title{-webkit-user-select:none;user-select:none;display:flex;align-items:center;line-height:1.5rem;width:100%;outline:none;border:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-decoration:none;color:var(--granite-color-text);font-size:var(--granite-font-size-micro);font-weight:var(--granite-font-weight-bold);cursor:default}:host.cdk-mouse-focused,:host.cdk-program-focused,:host.cdk-keyboard-focused,:host.granite-menu-item-highlighted{background:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active)}:host granite-icon{position:absolute;font-size:var(--granite-font-size-body-small);color:inherit;top:50%;transform:translateY(-50%)}:host.granite-menu-item-submenu-trigger{padding-inline-end:var(--granite-spacing-l)}html[dir=ltr] :host.granite-menu-item-submenu-trigger granite-icon{right:var(--granite-spacing-xs)}:host-context([dir=ltr]) :host.granite-menu-item-submenu-trigger granite-icon{right:var(--granite-spacing-xs)}html[dir=rtl] :host.granite-menu-item-submenu-trigger granite-icon{left:var(--granite-spacing-xs)}:host-context([dir=rtl]) :host.granite-menu-item-submenu-trigger granite-icon{left:var(--granite-spacing-xs)}[dir=rtl] :host.granite-menu-item-submenu-trigger granite-icon.caret-right{display:none}[dir=ltr] :host.granite-menu-item-submenu-trigger granite-icon.caret-left{display:none}:host.granite-divider-top{border-top:.0625rem solid var(--granite-color-border-soft)}:host.granite-divider-bottom{border-bottom:.0625rem solid var(--granite-color-border-soft)}:host.granite-device-output-touch{line-height:3rem;font-size:var(--granite-font-size-body-small);text-align:center;padding:0 var(--granite-spacing-l)}:host.granite-device-output-touch.granite-title{padding:0;justify-content:center;line-height:1.5rem;font-size:var(--granite-font-size-micro)}:host.granite-device-output-touch.granite-menu-item-back-trigger,:host.granite-device-output-touch.granite-menu-item-submenu-trigger{padding:0 var(--granite-spacing-l)}:host.granite-device-output-touch.granite-menu-item-title{line-height:3rem;height:3rem;font-size:var(--granite-font-size-micro);color:var(--granite-color-text-weak)}@media (hover: none) and (pointer: coarse){:host.granite-device-output-touch.granite-menu-item-title:active{background:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active)}}html[dir=ltr] :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon{left:var(--granite-spacing-xs)}:host-context([dir=ltr]) :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon{left:var(--granite-spacing-xs)}html[dir=rtl] :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon{right:var(--granite-spacing-xs)}:host-context([dir=rtl]) :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon{right:var(--granite-spacing-xs)}[dir=rtl] :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon.caret-left{display:none}[dir=ltr] :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon.caret-right{display:none}:host:disabled:not(.granite-menu-item-title){opacity:.4;cursor:default}\n"] });
1233
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteMenuTouchCloseComponent, decorators: [{
1234
+ type: Component,
1235
+ args: [{ selector: '[graniteMenuTouchCloseItem]', template: '<ng-content></ng-content>', exportAs: 'graniteMenuTouchCloseItem', host: {
1236
+ '[class.granite-device-output-touch]': 'true',
1237
+ }, styles: [":host{display:block;position:relative;line-height:2rem;padding:0 var(--granite-spacing-s);width:100%;max-width:100%;-webkit-user-select:none;user-select:none;cursor:pointer;outline:none;border:none;-webkit-tap-highlight-color:transparent;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:start;text-decoration:none;background-color:var(--granite-color-background-variant);color:var(--granite-color-text);font-size:var(--granite-font-size-body-small);font-family:inherit}@media (hover: hover) and (pointer: fine){:host:hover:not(.granite-title):not([disabled]){background:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active)}}@media (hover: none) and (pointer: coarse){:host:active:not(.granite-title):not([disabled]){background:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active)}}:host.granite-title{-webkit-user-select:none;user-select:none;display:flex;align-items:center;line-height:1.5rem;width:100%;outline:none;border:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-decoration:none;color:var(--granite-color-text);font-size:var(--granite-font-size-micro);font-weight:var(--granite-font-weight-bold);cursor:default}:host.cdk-mouse-focused,:host.cdk-program-focused,:host.cdk-keyboard-focused,:host.granite-menu-item-highlighted{background:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active)}:host granite-icon{position:absolute;font-size:var(--granite-font-size-body-small);color:inherit;top:50%;transform:translateY(-50%)}:host.granite-menu-item-submenu-trigger{padding-inline-end:var(--granite-spacing-l)}html[dir=ltr] :host.granite-menu-item-submenu-trigger granite-icon{right:var(--granite-spacing-xs)}:host-context([dir=ltr]) :host.granite-menu-item-submenu-trigger granite-icon{right:var(--granite-spacing-xs)}html[dir=rtl] :host.granite-menu-item-submenu-trigger granite-icon{left:var(--granite-spacing-xs)}:host-context([dir=rtl]) :host.granite-menu-item-submenu-trigger granite-icon{left:var(--granite-spacing-xs)}[dir=rtl] :host.granite-menu-item-submenu-trigger granite-icon.caret-right{display:none}[dir=ltr] :host.granite-menu-item-submenu-trigger granite-icon.caret-left{display:none}:host.granite-divider-top{border-top:.0625rem solid var(--granite-color-border-soft)}:host.granite-divider-bottom{border-bottom:.0625rem solid var(--granite-color-border-soft)}:host.granite-device-output-touch{line-height:3rem;font-size:var(--granite-font-size-body-small);text-align:center;padding:0 var(--granite-spacing-l)}:host.granite-device-output-touch.granite-title{padding:0;justify-content:center;line-height:1.5rem;font-size:var(--granite-font-size-micro)}:host.granite-device-output-touch.granite-menu-item-back-trigger,:host.granite-device-output-touch.granite-menu-item-submenu-trigger{padding:0 var(--granite-spacing-l)}:host.granite-device-output-touch.granite-menu-item-title{line-height:3rem;height:3rem;font-size:var(--granite-font-size-micro);color:var(--granite-color-text-weak)}@media (hover: none) and (pointer: coarse){:host.granite-device-output-touch.granite-menu-item-title:active{background:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active)}}html[dir=ltr] :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon{left:var(--granite-spacing-xs)}:host-context([dir=ltr]) :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon{left:var(--granite-spacing-xs)}html[dir=rtl] :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon{right:var(--granite-spacing-xs)}:host-context([dir=rtl]) :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon{right:var(--granite-spacing-xs)}[dir=rtl] :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon.caret-left{display:none}[dir=ltr] :host.granite-device-output-touch.granite-menu-item-back-trigger granite-icon.caret-right{display:none}:host:disabled:not(.granite-menu-item-title){opacity:.4;cursor:default}\n"] }]
1238
+ }] });
1239
+
1240
+ class GraniteMenuComponent extends _MenuBaseComponent {
1241
+ }
1242
+ GraniteMenuComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteMenuComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1243
+ GraniteMenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: GraniteMenuComponent, selector: "granite-menu", providers: [
1244
+ { provide: GRANITE_MENU_PANEL, useExisting: GraniteMenuComponent },
1245
+ ], exportAs: ["graniteMenu"], usesInheritance: true, ngImport: i0, template: "<!--\n Using separate template part for desktop and touch output, because of\n animation triggers and slightly different content.\n-->\n<ng-template>\n <!-- Desktop -->\n <ng-container *ngIf=\"_clientOutput.device === 'desktop'\">\n <div\n #menu\n class=\"granite-menu\"\n [class.is-menu-empty]=\"_isMenuEmpty$ | async\"\n tabindex=\"-1\"\n [id]=\"panelId\"\n [@transformMenuDesktop]=\"_transformMenu | async\"\n (@transformMenuDesktop.start)=\"_onAnimationStart($event)\"\n (@transformMenuDesktop.done)=\"_onAnimationDone($event)\"\n (click)=\"_handleClick()\"\n (keydown)=\"_handleKeydown($event)\"\n >\n <div class=\"granite-menu-content\">\n <ng-container [ngTemplateOutlet]=\"content\"></ng-container>\n </div>\n </div>\n </ng-container>\n\n <!-- Touch -->\n <ng-container *ngIf=\"_clientOutput?.device === 'touch'\">\n <div\n #menu\n class=\"granite-menu granite-device-output-touch\"\n tabindex=\"-1\"\n [id]=\"panelId\"\n [@transformMenuTouch]=\"_transformMenu | async\"\n (@transformMenuTouch.start)=\"_onAnimationStart($event)\"\n (@transformMenuTouch.done)=\"_onAnimationDone($event)\"\n (click)=\"_handleClick()\"\n (keydown)=\"_handleKeydown($event)\"\n >\n <div class=\"granite-menu-content\">\n <div *ngIf=\"showTitle\" class=\"header-container\">\n <button\n [disabled]=\"!showBackButton\"\n graniteMenuTouchTitleItem\n (click)=\"_handleBackClick($event)\"\n >\n {{ title }}\n </button>\n </div>\n\n <ng-container [ngTemplateOutlet]=\"content\"></ng-container>\n\n <div class=\"footer-container\"></div>\n </div>\n </div>\n\n <!-- Close button -->\n <div class=\"close\" [@transformCloseButton]=\"_transformMenu | async\">\n <button\n *ngIf=\"showCloseButton\"\n graniteMenuTouchCloseItem\n (click)=\"_handleCloseClick()\"\n >\n {{ closeLabel }}\n </button>\n </div>\n </ng-container>\n\n <!--\n Content template shared between desktop and touch parts, as <ng-content>\n can't be used in two places in the same template\n -->\n <ng-template #content>\n <ng-content></ng-content>\n </ng-template>\n</ng-template>\n", styles: [".granite-menu:not(.granite-device-output-touch){background-color:var(--granite-color-background-variant);color:var(--granite-color-text);overflow:auto;-webkit-overflow-scrolling:touch;max-height:calc(100vh - 2rem);outline:0;-webkit-user-select:none;user-select:none;filter:drop-shadow(var(--granite-shadow-l));min-width:7rem;overflow-x:hidden;overflow-y:hidden}.granite-menu:not(.granite-device-output-touch).ng-animating{pointer-events:none}.granite-menu:not(.granite-device-output-touch):not(.is-menu-empty){min-height:2rem}.granite-menu:not(.granite-device-output-touch):hover{overflow-y:auto}.granite-menu:not(.granite-device-output-touch)::-webkit-scrollbar{width:var(--granite-spacing-xs)}.granite-menu:not(.granite-device-output-touch)::-webkit-scrollbar-thumb{background-color:var(--granite-color-border-hard);border-radius:calc(var(--granite-spacing-m) * .125)}.granite-menu:not(.granite-device-output-touch)::-webkit-scrollbar-track{background-color:var(--granite-color-background-hover)}.granite-menu.granite-device-output-touch{background-color:var(--granite-color-background-variant);color:var(--granite-color-text);overflow:auto;-webkit-overflow-scrolling:touch;max-height:calc(100vh - 2rem);outline:0;-webkit-user-select:none;user-select:none;filter:drop-shadow(var(--granite-shadow-l));border-radius:.25rem}.granite-menu.granite-device-output-touch.ng-animating{pointer-events:none}.granite-menu.granite-device-output-touch:not(.is-menu-empty){min-height:3rem}.granite-menu.granite-device-output-touch:not(.close){margin:var(--granite-spacing-xs)}.granite-menu.granite-device-output-touch.close{margin-inline-start:var(--granite-spacing-xs);margin-inline-end:var(--granite-spacing-xs);margin-block-end:var(--granite-spacing-xs)}.granite-menu.granite-device-output-touch .header-container{position:sticky;top:0;background-color:var(--granite-color-background-variant);z-index:1}.granite-menu.granite-device-output-touch .footer-container{position:sticky;bottom:0;height:0}.close:not(:empty){background-color:var(--granite-color-background-variant);color:var(--granite-color-text);overflow:auto;-webkit-overflow-scrolling:touch;max-height:calc(100vh - 2rem);outline:0;-webkit-user-select:none;user-select:none;filter:drop-shadow(var(--granite-shadow-l));border-radius:.25rem}.close:not(:empty).ng-animating{pointer-events:none}.close:not(:empty):not(.is-menu-empty){min-height:3rem}.close:not(:empty):not(.close){margin:var(--granite-spacing-xs)}.close:not(:empty).close{margin-inline-start:var(--granite-spacing-xs);margin-inline-end:var(--granite-spacing-xs);margin-block-end:var(--granite-spacing-xs)}\n"], components: [{ type: GraniteMenuTouchTitleItemComponent, selector: "[graniteMenuTouchTitleItem]", exportAs: ["graniteMenuTouchTitleItem"] }, { type: GraniteMenuTouchCloseComponent, selector: "[graniteMenuTouchCloseItem]", exportAs: ["graniteMenuTouchCloseItem"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i2.AsyncPipe }, animations: [
1246
+ graniteMenuDesktopAnimations.transformMenuDesktop,
1247
+ graniteMenuTouchAnimations.transformMenuTouch,
1248
+ graniteMenuTouchAnimations.transformCloseButton,
1249
+ ], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1250
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteMenuComponent, decorators: [{
1251
+ type: Component,
1252
+ args: [{ selector: 'granite-menu', changeDetection: ChangeDetectionStrategy.OnPush, exportAs: 'graniteMenu', animations: [
1253
+ graniteMenuDesktopAnimations.transformMenuDesktop,
1254
+ graniteMenuTouchAnimations.transformMenuTouch,
1255
+ graniteMenuTouchAnimations.transformCloseButton,
1256
+ ], providers: [
1257
+ { provide: GRANITE_MENU_PANEL, useExisting: GraniteMenuComponent },
1258
+ ], template: "<!--\n Using separate template part for desktop and touch output, because of\n animation triggers and slightly different content.\n-->\n<ng-template>\n <!-- Desktop -->\n <ng-container *ngIf=\"_clientOutput.device === 'desktop'\">\n <div\n #menu\n class=\"granite-menu\"\n [class.is-menu-empty]=\"_isMenuEmpty$ | async\"\n tabindex=\"-1\"\n [id]=\"panelId\"\n [@transformMenuDesktop]=\"_transformMenu | async\"\n (@transformMenuDesktop.start)=\"_onAnimationStart($event)\"\n (@transformMenuDesktop.done)=\"_onAnimationDone($event)\"\n (click)=\"_handleClick()\"\n (keydown)=\"_handleKeydown($event)\"\n >\n <div class=\"granite-menu-content\">\n <ng-container [ngTemplateOutlet]=\"content\"></ng-container>\n </div>\n </div>\n </ng-container>\n\n <!-- Touch -->\n <ng-container *ngIf=\"_clientOutput?.device === 'touch'\">\n <div\n #menu\n class=\"granite-menu granite-device-output-touch\"\n tabindex=\"-1\"\n [id]=\"panelId\"\n [@transformMenuTouch]=\"_transformMenu | async\"\n (@transformMenuTouch.start)=\"_onAnimationStart($event)\"\n (@transformMenuTouch.done)=\"_onAnimationDone($event)\"\n (click)=\"_handleClick()\"\n (keydown)=\"_handleKeydown($event)\"\n >\n <div class=\"granite-menu-content\">\n <div *ngIf=\"showTitle\" class=\"header-container\">\n <button\n [disabled]=\"!showBackButton\"\n graniteMenuTouchTitleItem\n (click)=\"_handleBackClick($event)\"\n >\n {{ title }}\n </button>\n </div>\n\n <ng-container [ngTemplateOutlet]=\"content\"></ng-container>\n\n <div class=\"footer-container\"></div>\n </div>\n </div>\n\n <!-- Close button -->\n <div class=\"close\" [@transformCloseButton]=\"_transformMenu | async\">\n <button\n *ngIf=\"showCloseButton\"\n graniteMenuTouchCloseItem\n (click)=\"_handleCloseClick()\"\n >\n {{ closeLabel }}\n </button>\n </div>\n </ng-container>\n\n <!--\n Content template shared between desktop and touch parts, as <ng-content>\n can't be used in two places in the same template\n -->\n <ng-template #content>\n <ng-content></ng-content>\n </ng-template>\n</ng-template>\n", styles: [".granite-menu:not(.granite-device-output-touch){background-color:var(--granite-color-background-variant);color:var(--granite-color-text);overflow:auto;-webkit-overflow-scrolling:touch;max-height:calc(100vh - 2rem);outline:0;-webkit-user-select:none;user-select:none;filter:drop-shadow(var(--granite-shadow-l));min-width:7rem;overflow-x:hidden;overflow-y:hidden}.granite-menu:not(.granite-device-output-touch).ng-animating{pointer-events:none}.granite-menu:not(.granite-device-output-touch):not(.is-menu-empty){min-height:2rem}.granite-menu:not(.granite-device-output-touch):hover{overflow-y:auto}.granite-menu:not(.granite-device-output-touch)::-webkit-scrollbar{width:var(--granite-spacing-xs)}.granite-menu:not(.granite-device-output-touch)::-webkit-scrollbar-thumb{background-color:var(--granite-color-border-hard);border-radius:calc(var(--granite-spacing-m) * .125)}.granite-menu:not(.granite-device-output-touch)::-webkit-scrollbar-track{background-color:var(--granite-color-background-hover)}.granite-menu.granite-device-output-touch{background-color:var(--granite-color-background-variant);color:var(--granite-color-text);overflow:auto;-webkit-overflow-scrolling:touch;max-height:calc(100vh - 2rem);outline:0;-webkit-user-select:none;user-select:none;filter:drop-shadow(var(--granite-shadow-l));border-radius:.25rem}.granite-menu.granite-device-output-touch.ng-animating{pointer-events:none}.granite-menu.granite-device-output-touch:not(.is-menu-empty){min-height:3rem}.granite-menu.granite-device-output-touch:not(.close){margin:var(--granite-spacing-xs)}.granite-menu.granite-device-output-touch.close{margin-inline-start:var(--granite-spacing-xs);margin-inline-end:var(--granite-spacing-xs);margin-block-end:var(--granite-spacing-xs)}.granite-menu.granite-device-output-touch .header-container{position:sticky;top:0;background-color:var(--granite-color-background-variant);z-index:1}.granite-menu.granite-device-output-touch .footer-container{position:sticky;bottom:0;height:0}.close:not(:empty){background-color:var(--granite-color-background-variant);color:var(--granite-color-text);overflow:auto;-webkit-overflow-scrolling:touch;max-height:calc(100vh - 2rem);outline:0;-webkit-user-select:none;user-select:none;filter:drop-shadow(var(--granite-shadow-l));border-radius:.25rem}.close:not(:empty).ng-animating{pointer-events:none}.close:not(:empty):not(.is-menu-empty){min-height:3rem}.close:not(:empty):not(.close){margin:var(--granite-spacing-xs)}.close:not(:empty).close{margin-inline-start:var(--granite-spacing-xs);margin-inline-end:var(--granite-spacing-xs);margin-block-end:var(--granite-spacing-xs)}\n"] }]
1259
+ }] });
1260
+
1261
+ /**
1262
+ * Injection token used to provide components knowledge of what device types
1263
+ * are being used for input.
1264
+ */
1265
+ const GRANITE_CLIENT_INPUT = new InjectionToken('GRANITE_CLIENT_INPUT');
1266
+ /**
1267
+ * Injection token used to provide components knowledge of what device type
1268
+ * is being used for output.
1269
+ */
1270
+ const GRANITE_CLIENT_OUTPUT = new InjectionToken('GRANITE_CLIENT_OUTPUT');
1271
+ const deviceDesktop = {
1272
+ input: { devices: ['mouse', 'keyboard'] },
1273
+ output: { device: 'desktop' },
1274
+ };
1275
+ const deviceTouch = {
1276
+ input: { devices: ['touch', 'onscreen-keyboard'] },
1277
+ output: { device: 'touch' },
1278
+ };
1279
+
1280
+ /** Options for binding a passive event listener. */
1281
+ const passiveEventListenerOptions = normalizePassiveListenerOptions({
1282
+ passive: true,
1283
+ });
1284
+ //#endregion --- Touch device customizations ---
1285
+ /**
1286
+ * Directive used to turn a button element into a (popup) menu trigger
1287
+ *
1288
+ * Stripped-down version of Angular Material's menu trigger directive (.../menu/menu-trigger.ts)
1289
+ */
1290
+ class GraniteMenuTriggerForDirective {
1291
+ constructor(_overlay, _element, _viewContainerRef,
1292
+ /** If this is a _submenu_ trigger, it will have a parent menu */
1293
+ _parentMenu,
1294
+ //#region --- Touch device customizations ---
1295
+ /** Client input device information */
1296
+ _clientInput,
1297
+ /** Client output device information */
1298
+ _clientOutput,
1299
+ //#endregion --- Touch device customizations ---
1300
+ /**
1301
+ * If this is a _submenu_ trigger, there should be a corresponding menu
1302
+ * item directive present as well:
1303
+ *
1304
+ * <button graniteMenuItem [graniteMenuTriggerFor]="...">
1305
+ * ^-- This one
1306
+ */
1307
+ _menuItemInstance, _dir, _focusMonitor,
1308
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
1309
+ document) {
1310
+ this._overlay = _overlay;
1311
+ this._element = _element;
1312
+ this._viewContainerRef = _viewContainerRef;
1313
+ this._parentMenu = _parentMenu;
1314
+ this._clientInput = _clientInput;
1315
+ this._clientOutput = _clientOutput;
1316
+ this._menuItemInstance = _menuItemInstance;
1317
+ this._dir = _dir;
1318
+ this._focusMonitor = _focusMonitor;
1319
+ /** Whether the associated menu is open */
1320
+ this._isMenuOpen = false;
1321
+ // Tracking input type is necessary so it's possible to only auto-focus
1322
+ // the first item of the list when the menu is opened via the keyboard
1323
+ this._openedBy = null;
1324
+ this._hoverSubscription = Subscription.EMPTY;
1325
+ this._menuCloseSubscription = Subscription.EMPTY;
1326
+ this._closingActionsSubscription = Subscription.EMPTY;
1327
+ this._portal = null;
1328
+ this._overlayRef = null;
1329
+ this._touchTouchingElement = false;
1330
+ /**
1331
+ * Handles touch start events on the trigger.
1332
+ * Needs to be an arrow function so we can easily use addEventListener and removeEventListener.
1333
+ */
1334
+ this._handleTouchStart = () => {
1335
+ this._openedBy = 'touch';
1336
+ };
1337
+ // ----------------------------------------- //
1338
+ // --- Here be poor man's touch gestures --- //
1339
+ // ----------------------------------------- //
1340
+ // TODO: Replace with Hammer or other gesture library
1341
+ /**
1342
+ * Handles touch start events on the overlay host element (wrapper).
1343
+ * Needs to be an arrow function so we can easily use addEventListener and removeEventListener.
1344
+ */
1345
+ this._handleOverlayTouchStart = (event) => {
1346
+ if (this.menu._isAnimating) {
1347
+ return;
1348
+ }
1349
+ this._touchStartTime = new Date().getTime();
1350
+ this._touchStartX = event.changedTouches[0].clientX;
1351
+ this._touchStartY = event.changedTouches[0].clientY;
1352
+ this._touchCurrentX = this._touchStartX;
1353
+ this._touchCurrentY = this._touchStartY;
1354
+ this._touchTranslateX = 0;
1355
+ this._touchMaxX =
1356
+ this._overlayRef.hostElement.getBoundingClientRect().width;
1357
+ this._touchLockedX = null;
1358
+ this._touchTouchingElement = true;
1359
+ };
1360
+ this._handleOverlayTouchMove = (event) => {
1361
+ if (!this._touchTouchingElement || this.menu._isAnimating) {
1362
+ return;
1363
+ }
1364
+ if (this._touchLockedX) {
1365
+ return;
1366
+ }
1367
+ this._touchCurrentX = event.changedTouches[0].clientX;
1368
+ this._touchCurrentY = event.changedTouches[0].clientY;
1369
+ // Lock X-axis pan if initiating pan on Y-axis
1370
+ if (this._touchLockedX === null) {
1371
+ const dy = Math.abs(this._touchCurrentY - this._touchStartY);
1372
+ const dx = Math.abs(this._touchCurrentX - this._touchStartX);
1373
+ if (dx > 10 || dy > 10) {
1374
+ this._touchLockedX = dy > dx;
1375
+ return;
1376
+ }
1377
+ }
1378
+ // Restrict to right pan/swipe and make menu movement extremely slow when
1379
+ // moved past allowed limits.
1380
+ const menuMargin = 16;
1381
+ this._touchTranslateX = this._touchCurrentX - this._touchStartX;
1382
+ if (this._touchTranslateX < 0) {
1383
+ this._touchTranslateX = this.easeOutExpo(this._touchTranslateX, 0, -menuMargin / 2, this._touchMaxX * -4);
1384
+ }
1385
+ else if (!this._parentMenu) {
1386
+ this._touchTranslateX = this.easeOutExpo(this._touchTranslateX, 0, menuMargin / 2, this._touchMaxX * 4);
1387
+ }
1388
+ else if (this._touchTranslateX > this._touchMaxX) {
1389
+ this._touchTranslateX = this.easeOutExpo(this._touchTranslateX - this._touchMaxX, this._touchMaxX, menuMargin / 2, this._touchMaxX * 4);
1390
+ }
1391
+ // Set new sub menu position and tell any parent to follow;
1392
+ this.animateSetMenuPosition(this._touchTranslateX);
1393
+ };
1394
+ this._handleOverlayTouchEnd = () => {
1395
+ if (!this._touchTouchingElement || this.menu._isAnimating) {
1396
+ return;
1397
+ }
1398
+ this._touchTranslateX = this._touchCurrentX - this._touchStartX;
1399
+ if (this._touchTranslateX === 0) {
1400
+ return;
1401
+ }
1402
+ this._touchTouchingElement = false;
1403
+ this._touchTimeTaken = new Date().getTime() - this._touchStartTime;
1404
+ const swipeMinDistance = 10;
1405
+ const swipeMinTime = 50;
1406
+ const swipeMaxTime = 300;
1407
+ const pannedHalfwayRight = this._touchTranslateX > this._touchMaxX / 2;
1408
+ const swipedRight = this._touchTranslateX > this._touchMaxX / swipeMinDistance &&
1409
+ this._touchTimeTaken > swipeMinTime &&
1410
+ this._touchTimeTaken < swipeMaxTime;
1411
+ if (!!this._parentMenu && (swipedRight || pannedHalfwayRight)) {
1412
+ // Close submenu keydown-style: close only this menu and leave parents open
1413
+ this.menu.closed.emit('keydown');
1414
+ }
1415
+ else {
1416
+ // Pan ended but the menu was not moved far enough. Reset menus to
1417
+ // where they were before panning stared.
1418
+ this.animateOpenMenu();
1419
+ }
1420
+ };
1421
+ _element.nativeElement.addEventListener('touchstart', this._handleTouchStart, passiveEventListenerOptions);
1422
+ if (_menuItemInstance) {
1423
+ _menuItemInstance._triggersSubmenu = this.triggersSubmenu();
1424
+ }
1425
+ this._document = document;
1426
+ }
1427
+ ngOnChanges(changes) {
1428
+ if (changes.menu) {
1429
+ this._handleMenuChange();
1430
+ }
1431
+ }
1432
+ ngAfterContentInit() {
1433
+ // removed checkMenu here to avoid errors in dynamically genarated menus
1434
+ // menu is checked when opening the menu
1435
+ // this._checkMenu();
1436
+ this._handleHover();
1437
+ }
1438
+ ngOnDestroy() {
1439
+ if (this._overlayRef) {
1440
+ //#region --- Touch device customizations ---
1441
+ this.removeOverlayListeners();
1442
+ //#endregion --- Touch device customizations ---
1443
+ this._overlayRef.dispose();
1444
+ this._overlayRef = null;
1445
+ }
1446
+ this._element.nativeElement.removeEventListener('touchstart', this._handleTouchStart, passiveEventListenerOptions);
1447
+ this._hoverSubscription.unsubscribe();
1448
+ this._menuCloseSubscription.unsubscribe();
1449
+ this._closingActionsSubscription.unsubscribe();
1450
+ }
1451
+ /** Handles change of associated menu */
1452
+ _handleMenuChange() {
1453
+ this._menuCloseSubscription.unsubscribe();
1454
+ // Close the menu overlay when the menu itself says it wants to be closed
1455
+ if (this.menu) {
1456
+ const closed = this.menu.closed;
1457
+ this._menuCloseSubscription = closed.subscribe((reason) => {
1458
+ //#region --- Touch device customizations ---
1459
+ if (this.menu._isClosing) {
1460
+ return;
1461
+ }
1462
+ this.menu._isClosing = true;
1463
+ // Get rid of the menu and tell any parent to restore its position
1464
+ if (this._clientOutput.device === 'touch') {
1465
+ // First we wait for any running animation to complete
1466
+ const runningAnimationDone = this.menu._isAnimating
1467
+ ? this.menu._animationDone
1468
+ : of([null]);
1469
+ runningAnimationDone
1470
+ .pipe(take(1), delay(0, asapScheduler))
1471
+ // eslint-disable-next-line rxjs/no-nested-subscribe
1472
+ .subscribe(() => {
1473
+ this.animateCloseMenu(reason !== 'keydown', reason === 'click');
1474
+ this.menu._animationDone
1475
+ .pipe(take(1), delay(0, asapScheduler))
1476
+ // eslint-disable-next-line rxjs/no-nested-subscribe
1477
+ .subscribe(() => this._destroyMenu());
1478
+ });
1479
+ }
1480
+ else {
1481
+ //#endregion --- Touch device customizations ---
1482
+ this._destroyMenu();
1483
+ }
1484
+ // If a click closed the menu, we should close the entire chain of nested menus.
1485
+ if ((reason === 'click' || reason === 'tab') && this._parentMenu) {
1486
+ this._parentMenu.closed.emit(reason);
1487
+ }
1488
+ });
1489
+ }
1490
+ }
1491
+ isOpen() {
1492
+ return this._isMenuOpen;
1493
+ }
1494
+ /** Open the associated menu */
1495
+ openMenu() {
1496
+ var _a;
1497
+ if (this._isMenuOpen) {
1498
+ return;
1499
+ }
1500
+ this._checkMenu();
1501
+ this.menu.parentMenu = this.triggersSubmenu()
1502
+ ? this._parentMenu
1503
+ : undefined;
1504
+ this.menu.direction = this._dir.value === 'rtl' ? 'rtl' : 'ltr';
1505
+ if (this._parentMenu) {
1506
+ // Menu triggers inherit target device types from their parent.
1507
+ // Ultimately it is the root trigger that determines device types for
1508
+ // the whole menu hierarchy.
1509
+ this._clientInput = this._parentMenu._clientInput;
1510
+ this._clientOutput = this._parentMenu._clientOutput;
1511
+ }
1512
+ //#region --- Touch device customizations ---
1513
+ // Make the menu we're about to open use the same devices as the trigger
1514
+ this.menu._setDevice(this._clientInput, this._clientOutput);
1515
+ if (this._clientOutput.device === 'touch') {
1516
+ this.menu.showBackButton = !!this._parentMenu;
1517
+ this.menu._updateShowTitle();
1518
+ if (!this.menu.closeLabel) {
1519
+ this.menu.closeLabel = (_a = this._parentMenu) === null || _a === void 0 ? void 0 : _a.closeLabel;
1520
+ }
1521
+ this.menu.showCloseButton = !!this.menu.closeLabel;
1522
+ }
1523
+ this.menu._isClosing = false;
1524
+ const panelClass = [];
1525
+ if (this._clientOutput.device === 'touch') {
1526
+ panelClass.push('granite-overlay-pane-fill-width-bottom');
1527
+ }
1528
+ const scrollStrategy = this._clientOutput.device !== 'touch'
1529
+ ? this._overlay.scrollStrategies.reposition()
1530
+ : undefined;
1531
+ const hasBackdrop = this._clientOutput.device === 'touch' && !this.triggersSubmenu();
1532
+ //#endregion --- Touch device customizations ---
1533
+ // Create an overlay to stuff the menu (portal) into below
1534
+ if (!this._overlayRef) {
1535
+ const config = new OverlayConfig({
1536
+ positionStrategy: this._positionStrategy(),
1537
+ backdropClass: 'granite-overlay-dark-glass-backdrop',
1538
+ scrollStrategy,
1539
+ direction: this._dir,
1540
+ panelClass,
1541
+ hasBackdrop,
1542
+ });
1543
+ this._overlayRef = this._overlay.create(config);
1544
+ //#region --- Touch device customizations ---
1545
+ // Add touch listener for submenu back pan/swipe
1546
+ if (this._clientOutput.device === 'touch') {
1547
+ this.addOverlayListeners();
1548
+ }
1549
+ //#endregion --- Touch device customizations ---
1550
+ }
1551
+ else {
1552
+ // Reset animation state for reused overlays
1553
+ if (this._clientOutput.device === 'touch') {
1554
+ this.menu._panelAnimationState = 'void';
1555
+ }
1556
+ }
1557
+ // Create portal from associated menu's template
1558
+ if (!this._portal || this._portal.templateRef !== this.menu.templateRef) {
1559
+ this._portal = new TemplatePortal(this.menu.templateRef, this._viewContainerRef);
1560
+ }
1561
+ // Attach menu portal to overlay ref (which is a portal outlet)
1562
+ this._overlayRef.attach(this._portal);
1563
+ // Subscribe to stream that emits whenever an action that should close the menu occurs
1564
+ this._closingActionsSubscription = this._menuClosingActions().subscribe(() => this.closeMenu());
1565
+ this.animateOpenMenu();
1566
+ this._setIsMenuOpen(true);
1567
+ this.menu.focusFirstItem(this._openedBy || 'program');
1568
+ }
1569
+ /** Whether the menu triggers a sub-menu or a top-level one. */
1570
+ triggersSubmenu() {
1571
+ return !!(this._menuItemInstance && this._parentMenu);
1572
+ }
1573
+ /** Toggles the menu between the open and closed states. */
1574
+ toggleMenu() {
1575
+ if (this._isMenuOpen) {
1576
+ this.closeMenu();
1577
+ }
1578
+ else {
1579
+ this.openMenu();
1580
+ }
1581
+ }
1582
+ /** Close the associated menu */
1583
+ closeMenu() {
1584
+ this.menu.closed.emit();
1585
+ }
1586
+ /**
1587
+ * Focuses the menu trigger.
1588
+ * @param origin Source of the menu trigger's focus.
1589
+ */
1590
+ focus(origin = 'program', options) {
1591
+ if (this._focusMonitor) {
1592
+ this._focusMonitor.focusVia(this._element, origin, options);
1593
+ }
1594
+ else {
1595
+ this._element.nativeElement.focus(options);
1596
+ }
1597
+ }
1598
+ /** Detach menu portal from overlay and update open state */
1599
+ _destroyMenu() {
1600
+ if (!this._overlayRef || !this._isMenuOpen) {
1601
+ return;
1602
+ }
1603
+ this._closingActionsSubscription.unsubscribe();
1604
+ this._overlayRef.detach();
1605
+ this._restoreFocus();
1606
+ this.menu._resetAnimation();
1607
+ this._setIsMenuOpen(false);
1608
+ }
1609
+ /** Handles mouse presses on the trigger. */
1610
+ _handleMousedown(event) {
1611
+ if (!isFakeMousedownFromScreenReader(event)) {
1612
+ if (this._openedBy !== 'touch') {
1613
+ // Since right or middle button clicks won't trigger the `click` event,
1614
+ // we shouldn't consider the menu as opened by mouse in those cases.
1615
+ this._openedBy = event.button === 0 ? 'mouse' : null;
1616
+ }
1617
+ // Since clicking on the trigger won't close the menu if it opens a sub-menu,
1618
+ // we should prevent focus from moving onto it via click to avoid the
1619
+ // highlight from lingering on the menu item.
1620
+ if (this.triggersSubmenu() && !this._toggleOnSubmenuClick()) {
1621
+ event.preventDefault();
1622
+ }
1623
+ }
1624
+ }
1625
+ /** Handles key presses on the trigger. */
1626
+ _handleKeydown(event) {
1627
+ const key = event.key;
1628
+ if (this.triggersSubmenu() &&
1629
+ ((key === 'ArrowRight' && this._dir.value === 'ltr') ||
1630
+ (key === 'ArrowLeft' && this._dir.value === 'rtl'))) {
1631
+ this.openMenu();
1632
+ }
1633
+ }
1634
+ /** Handles click events on the trigger. */
1635
+ _handleClick(event) {
1636
+ if (this.triggersSubmenu()) {
1637
+ // Stop event propagation to avoid closing the parent menu.
1638
+ event.stopPropagation();
1639
+ this._toggleOnSubmenuClick() ? this.toggleMenu() : this.openMenu();
1640
+ }
1641
+ else {
1642
+ this.toggleMenu();
1643
+ }
1644
+ }
1645
+ /** Handles the cases where the user hovers over the trigger. */
1646
+ _handleHover() {
1647
+ // Subscribe to changes in the hovered item in order to toggle the panel.
1648
+ if (!this.triggersSubmenu() || !this._parentMenu) {
1649
+ return;
1650
+ }
1651
+ this._hoverSubscription = this._parentMenu
1652
+ ._hovered()
1653
+ .pipe(filter(() => this._openOnHover()),
1654
+ // Since we might have multiple competing triggers for the same menu (e.g. a sub-menu
1655
+ // with different data and triggers), we have to delay it by a tick to ensure that
1656
+ // it won't be closed immediately after it is opened.
1657
+ filter((active) => active === this._menuItemInstance /*&& !active.disabled*/), delay(0, asapScheduler))
1658
+ .subscribe(() => {
1659
+ this._openedBy = 'mouse';
1660
+ // If the same menu is used between multiple triggers, it might still be animating
1661
+ // while the new trigger tries to re-open it. Wait for the animation to finish
1662
+ // before doing so. Also interrupt if the user moves to another item.
1663
+ if (this.menu instanceof _MenuBaseComponent && this.menu._isAnimating) {
1664
+ // We need the `delay(0)` here in order to avoid
1665
+ // 'changed after checked' errors in some cases. See Angular Material #12194.
1666
+ this.menu._animationDone
1667
+ .pipe(take(1), delay(0, asapScheduler), takeUntil(this._parentMenu._hovered()))
1668
+ // eslint-disable-next-line rxjs/no-nested-subscribe
1669
+ .subscribe(() => this.openMenu());
1670
+ }
1671
+ else {
1672
+ this.openMenu();
1673
+ }
1674
+ });
1675
+ }
1676
+ /**
1677
+ * Restores focus to the element that was focused before the menu was open.
1678
+ * Could be the root trigger button or a submenu trigger item
1679
+ */
1680
+ _restoreFocus() {
1681
+ // We should reset focus if the user is navigating using a keyboard or
1682
+ // if we have a top-level trigger which might cause focus to be lost
1683
+ // when clicking outside of the menu.
1684
+ if (!this._openedBy) {
1685
+ // Note that the focus style will show up both for `program` and
1686
+ // `keyboard` so we don't have to specify which one it is.
1687
+ this.focus();
1688
+ }
1689
+ else if (!this.triggersSubmenu()) {
1690
+ this.focus(this._openedBy);
1691
+ }
1692
+ this._openedBy = null;
1693
+ }
1694
+ // Set state rather than toggle to support triggers sharing a menu
1695
+ _setIsMenuOpen(isOpen) {
1696
+ this._isMenuOpen = isOpen;
1697
+ if (this.triggersSubmenu()) {
1698
+ this._menuItemInstance._highlighted =
1699
+ isOpen && this._clientOutput.device !== 'touch';
1700
+ }
1701
+ }
1702
+ /**
1703
+ * This method checks that a valid instance of MenuComponent has been passed into
1704
+ * graniteMenuTriggerFor. If not, an exception is thrown.
1705
+ */
1706
+ _checkMenu() {
1707
+ if (!this.menu) {
1708
+ throwGraniteMenuMissingError();
1709
+ }
1710
+ }
1711
+ /**
1712
+ * Returns strategy for positioning the overlay for desktop devices:
1713
+ * Place adjacent to the trigger button (preferably immediately below)
1714
+ * in order to show as much of the menu as possible.
1715
+ */
1716
+ _desktopPositionStrategy() {
1717
+ const positionStrategy = this._overlay
1718
+ .position()
1719
+ .flexibleConnectedTo(this._element)
1720
+ .withLockedPosition()
1721
+ .withTransformOriginOn('.granite-menu')
1722
+ .withPush(false);
1723
+ this._setPosition(positionStrategy);
1724
+ return positionStrategy;
1725
+ }
1726
+ /**
1727
+ * Sets the appropriate positions on a position strategy
1728
+ * so the overlay connects with the trigger correctly.
1729
+ * @param positionStrategy Strategy whose position to update.
1730
+ */
1731
+ _setPosition(positionStrategy) {
1732
+ const MENU_PANEL_TOP_PADDING = 0;
1733
+ let [originX, originFallbackX] = this.menu.xPosition === 'before' ? ['end', 'start'] : ['start', 'end'];
1734
+ const [overlayY, overlayFallbackY] = this.menu.yPosition === 'above' ? ['bottom', 'top'] : ['top', 'bottom'];
1735
+ let [originY, originFallbackY] = [overlayY, overlayFallbackY];
1736
+ let [overlayX, overlayFallbackX] = [originX, originFallbackX];
1737
+ let offsetY = 0;
1738
+ if (this.triggersSubmenu()) {
1739
+ // When the menu is a sub-menu, it should always align itself
1740
+ // to the edges of the trigger, instead of overlapping it.
1741
+ overlayFallbackX = originX =
1742
+ this.menu.xPosition === 'before' ? 'start' : 'end';
1743
+ originFallbackX = overlayX = originX === 'end' ? 'start' : 'end';
1744
+ offsetY =
1745
+ overlayY === 'bottom'
1746
+ ? MENU_PANEL_TOP_PADDING
1747
+ : -MENU_PANEL_TOP_PADDING;
1748
+ }
1749
+ else {
1750
+ originY = overlayY === 'top' ? 'bottom' : 'top';
1751
+ originFallbackY = overlayFallbackY === 'top' ? 'bottom' : 'top';
1752
+ }
1753
+ positionStrategy.withPositions([
1754
+ { originX, originY, overlayX, overlayY, offsetY },
1755
+ {
1756
+ originX: originFallbackX,
1757
+ originY,
1758
+ overlayX: overlayFallbackX,
1759
+ overlayY,
1760
+ offsetY,
1761
+ },
1762
+ {
1763
+ originX,
1764
+ originY: originFallbackY,
1765
+ overlayX,
1766
+ overlayY: overlayFallbackY,
1767
+ offsetY: -offsetY,
1768
+ },
1769
+ {
1770
+ originX: originFallbackX,
1771
+ originY: originFallbackY,
1772
+ overlayX: overlayFallbackX,
1773
+ overlayY: overlayFallbackY,
1774
+ offsetY: -offsetY,
1775
+ },
1776
+ ]);
1777
+ }
1778
+ /** Returns a stream that emits whenever an action that should close the menu occurs. */
1779
+ _menuClosingActions() {
1780
+ var _a;
1781
+ const detachments = (_a = this._overlayRef) === null || _a === void 0 ? void 0 : _a.detachments();
1782
+ const parentClose = this._parentMenu
1783
+ ? this._parentMenu.closed
1784
+ : of();
1785
+ const hover = this._clientOutput.device === 'desktop' && this._parentMenu
1786
+ ? this._parentMenu._hovered().pipe(filter((item) => item !== this._menuItemInstance), filter(() => this._isMenuOpen))
1787
+ : of();
1788
+ // Note: Quick fix. Feature reportedly exists in CDK for Angular 10
1789
+ // Filter to prevent closing when animating added though. Applied to
1790
+ // root menu only.
1791
+ const outsideClick = !this._parentMenu
1792
+ ? fromEvent(this._document, 'click').pipe(filter((e) => e.target !== this._element.nativeElement &&
1793
+ e.target.closest('.granite-menu') === null), filter(() => !this.menu._isAnimating))
1794
+ : of();
1795
+ return merge(detachments, hover, parentClose, outsideClick);
1796
+ }
1797
+ /**
1798
+ * Whether to automatically open submenus on hover. This is true when showing
1799
+ * desktop menus and having mouse support.
1800
+ */
1801
+ _openOnHover() {
1802
+ var _a, _b;
1803
+ return ((this.triggersSubmenu()
1804
+ ? this._parentMenu.openOnHover
1805
+ : this.menu.openOnHover) &&
1806
+ ((_a = this._parentMenu._clientOutput) === null || _a === void 0 ? void 0 : _a.device) === 'desktop' &&
1807
+ ((_b = this._parentMenu._clientInput) === null || _b === void 0 ? void 0 : _b.devices.includes('mouse')));
1808
+ }
1809
+ /**
1810
+ * Whether to toggle submenus on click. This is true when showing desktop menus
1811
+ * without mouse support. Which, by the way, is not a great idea to begin with.
1812
+ */
1813
+ _toggleOnSubmenuClick() {
1814
+ var _a, _b;
1815
+ return (!(this.triggersSubmenu()
1816
+ ? this._parentMenu.openOnHover
1817
+ : this.menu.openOnHover) ||
1818
+ (((_a = this._parentMenu._clientOutput) === null || _a === void 0 ? void 0 : _a.device) === 'desktop' &&
1819
+ !((_b = this._parentMenu._clientInput) === null || _b === void 0 ? void 0 : _b.devices.includes('mouse'))));
1820
+ }
1821
+ // ------------------------------------------- //
1822
+ // --- Here be touch device customizations --- //
1823
+ // ------------------------------------------- //
1824
+ /** Set animation state to bring a newly opened menu into view */
1825
+ animateOpenMenu() {
1826
+ this._clientOutput.device === 'touch'
1827
+ ? this.animateTouchOpenMenu()
1828
+ : this.menu._startAnimation();
1829
+ }
1830
+ animateTouchOpenMenu() {
1831
+ if (this.triggersSubmenu()) {
1832
+ // Slide newly opened sub menu into view from the side,
1833
+ // pushing any parent menu out of view on the other side
1834
+ this.menu._startTouchSubmenuEnterAnimation();
1835
+ this._parentMenu._startTouchHideAnimation();
1836
+ }
1837
+ else {
1838
+ // Slide root menu into view from below
1839
+ this.menu._startTouchRootEnterAnimation();
1840
+ }
1841
+ }
1842
+ /** Set animation state to close the active menu */
1843
+ animateCloseMenu(toBelow, withDelay) {
1844
+ this._clientOutput.device === 'touch'
1845
+ ? this._animateTouchCloseMenu(toBelow, withDelay)
1846
+ : this._parentMenu._resetAnimation();
1847
+ }
1848
+ _animateTouchCloseMenu(toBelow, withDelay) {
1849
+ var _a;
1850
+ if (toBelow) {
1851
+ // Slide menu out of view below the viewport
1852
+ withDelay
1853
+ ? this.menu._startTouchCloseDownAnimationWithDelay()
1854
+ : this.menu._startTouchCloseDownAnimation();
1855
+ }
1856
+ else {
1857
+ // Slide the closed menu out of view to the side
1858
+ // and slide any parent menu back into view
1859
+ this.menu._startTouchCloseSideAnimation();
1860
+ (_a = this._parentMenu) === null || _a === void 0 ? void 0 : _a._startTouchSubmenuEnterAnimation();
1861
+ }
1862
+ }
1863
+ /**
1864
+ * Set animation state to place the menu and any parent at the given
1865
+ * horizontal position, i.e. following touch pan movement.
1866
+ *
1867
+ * @param xOffset Horizontal offset
1868
+ */
1869
+ animateSetMenuPosition(xOffset) {
1870
+ this.menu._startTouchPanAnimation(xOffset);
1871
+ if (this._parentMenu) {
1872
+ this._parentMenu._startTouchHidePanAnimation(xOffset);
1873
+ }
1874
+ }
1875
+ /**
1876
+ * Returns strategy for positioning the overlay depending on what type of
1877
+ * device the menu is being shown on
1878
+ */
1879
+ _positionStrategy() {
1880
+ return this._clientOutput.device === 'touch'
1881
+ ? this._touchPositionStrategy()
1882
+ : this._desktopPositionStrategy();
1883
+ }
1884
+ /**
1885
+ * Returns strategy for positioning the overlay for touch devices:
1886
+ * Place centered at the bottom of the screen.
1887
+ */
1888
+ _touchPositionStrategy() {
1889
+ return this._overlay.position().global();
1890
+ }
1891
+ /**
1892
+ * Remove touch device pan/swipe listeners from overlay host element
1893
+ */
1894
+ addOverlayListeners() {
1895
+ this._overlayRef.hostElement.addEventListener('touchstart', this._handleOverlayTouchStart, passiveEventListenerOptions);
1896
+ this._overlayRef.hostElement.addEventListener('touchmove', this._handleOverlayTouchMove, passiveEventListenerOptions);
1897
+ this._overlayRef.hostElement.addEventListener('touchend', this._handleOverlayTouchEnd, passiveEventListenerOptions);
1898
+ }
1899
+ /**
1900
+ * Remove touch device pan/swipe listeners from overlay host element
1901
+ */
1902
+ removeOverlayListeners() {
1903
+ this._overlayRef.hostElement.removeEventListener('touchstart', this._handleOverlayTouchStart, passiveEventListenerOptions);
1904
+ this._overlayRef.hostElement.removeEventListener('touchmove', this._handleOverlayTouchMove, passiveEventListenerOptions);
1905
+ this._overlayRef.hostElement.removeEventListener('touchend', this._handleOverlayTouchEnd, passiveEventListenerOptions);
1906
+ }
1907
+ /**
1908
+ * Standard exponential ease out function
1909
+ *
1910
+ * @param current Current value
1911
+ * @param offset Offset value, to which calculated value will be added
1912
+ * @param target The target value
1913
+ * @param end Value to which current value is compared
1914
+ */
1915
+ easeOutExpo(current, offset, target, end) {
1916
+ return current === end
1917
+ ? offset + target
1918
+ : target * (-Math.pow(2, (-10 * current) / end) + 1) + offset;
1919
+ }
1920
+ }
1921
+ GraniteMenuTriggerForDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteMenuTriggerForDirective, deps: [{ token: i1$1.Overlay }, { token: i0.ElementRef }, { token: i0.ViewContainerRef }, { token: GRANITE_MENU_PANEL, optional: true }, { token: GRANITE_CLIENT_INPUT, optional: true }, { token: GRANITE_CLIENT_OUTPUT, optional: true }, { token: GraniteMenuItemComponent, optional: true, self: true }, { token: i3.Directionality, optional: true }, { token: i1.FocusMonitor }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Directive });
1922
+ GraniteMenuTriggerForDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.11", type: GraniteMenuTriggerForDirective, selector: "[graniteMenuTriggerFor]", inputs: { menu: ["graniteMenuTriggerFor", "menu"] }, host: { attributes: { "aria-haspopup": "true" }, listeners: { "mousedown": "_handleMousedown($event)", "keydown": "_handleKeydown($event)", "click": "_handleClick($event)" }, properties: { "attr.aria-expanded": "_isMenuOpen || null", "attr.aria-controls": "_isMenuOpen ? menu.panelId : null" }, classAttribute: "granite-menu-trigger" }, usesOnChanges: true, ngImport: i0 });
1923
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteMenuTriggerForDirective, decorators: [{
1924
+ type: Directive,
1925
+ args: [{
1926
+ selector: `[graniteMenuTriggerFor]`,
1927
+ host: {
1928
+ class: 'granite-menu-trigger',
1929
+ 'aria-haspopup': 'true',
1930
+ '[attr.aria-expanded]': '_isMenuOpen || null',
1931
+ '[attr.aria-controls]': '_isMenuOpen ? menu.panelId : null',
1932
+ '(mousedown)': '_handleMousedown($event)',
1933
+ '(keydown)': '_handleKeydown($event)',
1934
+ '(click)': '_handleClick($event)',
1935
+ },
1936
+ }]
1937
+ }], ctorParameters: function () {
1938
+ return [{ type: i1$1.Overlay }, { type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: _MenuBaseComponent, decorators: [{
1939
+ type: Inject,
1940
+ args: [GRANITE_MENU_PANEL]
1941
+ }, {
1942
+ type: Optional
1943
+ }] }, { type: undefined, decorators: [{
1944
+ type: Inject,
1945
+ args: [GRANITE_CLIENT_INPUT]
1946
+ }, {
1947
+ type: Optional
1948
+ }] }, { type: undefined, decorators: [{
1949
+ type: Inject,
1950
+ args: [GRANITE_CLIENT_OUTPUT]
1951
+ }, {
1952
+ type: Optional
1953
+ }] }, { type: GraniteMenuItemComponent, decorators: [{
1954
+ type: Optional
1955
+ }, {
1956
+ type: Self
1957
+ }] }, { type: i3.Directionality, decorators: [{
1958
+ type: Optional
1959
+ }] }, { type: i1.FocusMonitor }, { type: undefined, decorators: [{
1960
+ type: Inject,
1961
+ args: [DOCUMENT]
1962
+ }] }];
1963
+ }, propDecorators: { menu: [{
1964
+ type: Input,
1965
+ args: ['graniteMenuTriggerFor']
1966
+ }] } });
1967
+
1968
+ class GraniteDividerDirective {
1969
+ constructor() {
1970
+ this.dividerDirection = 'top';
1971
+ }
1972
+ }
1973
+ GraniteDividerDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteDividerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1974
+ GraniteDividerDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.11", type: GraniteDividerDirective, selector: "[graniteDivider]", inputs: { dividerDirection: "dividerDirection" }, host: { properties: { "class.granite-divider-top": "dividerDirection === \"top\"", "class.granite-divider-bottom": "dividerDirection === \"bottom\"" } }, exportAs: ["graniteDivider"], ngImport: i0 });
1975
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteDividerDirective, decorators: [{
1976
+ type: Directive,
1977
+ args: [{
1978
+ selector: '[graniteDivider]',
1979
+ exportAs: 'graniteDivider',
1980
+ host: {
1981
+ '[class.granite-divider-top]': 'dividerDirection === "top"',
1982
+ '[class.granite-divider-bottom]': 'dividerDirection === "bottom"',
1983
+ },
1984
+ }]
1985
+ }], propDecorators: { dividerDirection: [{
1986
+ type: Input
1987
+ }] } });
1988
+
1989
+ class GraniteIconModule {
1990
+ }
1991
+ GraniteIconModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteIconModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1992
+ GraniteIconModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteIconModule, declarations: [GraniteIconComponent], exports: [GraniteIconComponent] });
1993
+ GraniteIconModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteIconModule });
1994
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteIconModule, decorators: [{
1995
+ type: NgModule,
1996
+ args: [{
1997
+ declarations: [GraniteIconComponent],
1998
+ exports: [GraniteIconComponent],
1999
+ }]
2000
+ }] });
2001
+
2002
+ class GraniteTitleDirective {
2003
+ }
2004
+ GraniteTitleDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteTitleDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2005
+ GraniteTitleDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.11", type: GraniteTitleDirective, selector: "[graniteTitle]", host: { properties: { "class.granite-title": "true" } }, exportAs: ["graniteTitle"], ngImport: i0 });
2006
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteTitleDirective, decorators: [{
2007
+ type: Directive,
2008
+ args: [{
2009
+ selector: '[graniteTitle]',
2010
+ exportAs: 'graniteTitle',
2011
+ host: {
2012
+ '[class.granite-title]': 'true',
2013
+ },
2014
+ }]
2015
+ }] });
2016
+
2017
+ class GraniteMenuModule {
2018
+ }
2019
+ GraniteMenuModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteMenuModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2020
+ GraniteMenuModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteMenuModule, declarations: [GraniteMenuComponent,
2021
+ GraniteMenuItemComponent,
2022
+ GraniteMenuTriggerForDirective,
2023
+ GraniteMenuTouchCloseComponent,
2024
+ GraniteMenuTouchTitleItemComponent,
2025
+ GraniteDividerDirective,
2026
+ GraniteTitleDirective], imports: [CommonModule, OverlayModule, PortalModule, GraniteIconModule], exports: [GraniteMenuComponent,
2027
+ GraniteMenuItemComponent,
2028
+ GraniteMenuTriggerForDirective,
2029
+ GraniteMenuTouchCloseComponent,
2030
+ GraniteMenuTouchTitleItemComponent,
2031
+ GraniteDividerDirective,
2032
+ GraniteTitleDirective] });
2033
+ GraniteMenuModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteMenuModule, imports: [[CommonModule, OverlayModule, PortalModule, GraniteIconModule]] });
2034
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteMenuModule, decorators: [{
2035
+ type: NgModule,
2036
+ args: [{
2037
+ declarations: [
2038
+ GraniteMenuComponent,
2039
+ GraniteMenuItemComponent,
2040
+ GraniteMenuTriggerForDirective,
2041
+ GraniteMenuTouchCloseComponent,
2042
+ GraniteMenuTouchTitleItemComponent,
2043
+ GraniteDividerDirective,
2044
+ GraniteTitleDirective,
2045
+ ],
2046
+ imports: [CommonModule, OverlayModule, PortalModule, GraniteIconModule],
2047
+ exports: [
2048
+ GraniteMenuComponent,
2049
+ GraniteMenuItemComponent,
2050
+ GraniteMenuTriggerForDirective,
2051
+ GraniteMenuTouchCloseComponent,
2052
+ GraniteMenuTouchTitleItemComponent,
2053
+ GraniteDividerDirective,
2054
+ GraniteTitleDirective,
2055
+ ],
2056
+ }]
2057
+ }] });
2058
+
2059
+ /**
2060
+ * Test harness for menu component
2061
+ *
2062
+ * Stripped-down version of the Angular Material menu test harness (.../menu/menu-harness.ts)
2063
+ * just to get things going.
2064
+ */
2065
+ class GraniteMenuHarness extends ComponentHarness {
2066
+ constructor() {
2067
+ super(...arguments);
2068
+ this._documentRootLocator = this.documentRootLocatorFactory();
2069
+ }
2070
+ /**
2071
+ * Gets a `HarnessPredicate` that can be used to search for a `MenuHarness` that meets
2072
+ * certain criteria.
2073
+ * @param options Options for filtering which menu item instances are considered a match.
2074
+ * @return a `HarnessPredicate` configured with the given options.
2075
+ */
2076
+ static with(options = {}) {
2077
+ return new HarnessPredicate(GraniteMenuHarness, options).addOption('text', options.text,
2078
+ /* @dynamic */ (harness, text) => HarnessPredicate.stringMatches(harness.getText(), text));
2079
+ }
2080
+ /** Gets the text of the menu trigger */
2081
+ getText() {
2082
+ return __awaiter(this, void 0, void 0, function* () {
2083
+ return (yield this.host()).text();
2084
+ });
2085
+ }
2086
+ /** Opens the menu, unless already open */
2087
+ open() {
2088
+ return __awaiter(this, void 0, void 0, function* () {
2089
+ if (!(yield this.isOpen())) {
2090
+ yield (yield this.host()).click();
2091
+ // This is necessary so that we wait for the opening animation to finish.
2092
+ return this.forceStabilize();
2093
+ }
2094
+ });
2095
+ }
2096
+ /** Closes the menu, unless already closed */
2097
+ close() {
2098
+ var _a;
2099
+ return __awaiter(this, void 0, void 0, function* () {
2100
+ yield ((_a = (yield this._getMenuPanel())) === null || _a === void 0 ? void 0 : _a.sendKeys(TestKey.ESCAPE));
2101
+ // This is necessary so that we wait for the closing animation to finish.
2102
+ return this.forceStabilize();
2103
+ });
2104
+ }
2105
+ /** Whether the menu is open */
2106
+ isOpen() {
2107
+ return __awaiter(this, void 0, void 0, function* () {
2108
+ return !!(yield this._getMenuPanel());
2109
+ });
2110
+ }
2111
+ /**
2112
+ * Gets a list of `GraniteMenuItemHarness` representing the items in the menu.
2113
+ * @param filters Optionally filters which menu items are included.
2114
+ */
2115
+ getItems(filters = {}) {
2116
+ return __awaiter(this, void 0, void 0, function* () {
2117
+ const panelId = yield this._getPanelId();
2118
+ if (panelId) {
2119
+ return this._documentRootLocator.locatorForAll(GraniteMenuItemHarness.with(Object.assign(Object.assign({}, filters), { ancestor: `#${panelId}` })))();
2120
+ }
2121
+ return [];
2122
+ });
2123
+ }
2124
+ /** Gets the menu panel (popup) associated with the menu */
2125
+ _getMenuPanel() {
2126
+ return __awaiter(this, void 0, void 0, function* () {
2127
+ const panelId = yield this._getPanelId();
2128
+ return panelId
2129
+ ? this._documentRootLocator.locatorForOptional(`#${panelId}`)()
2130
+ : null;
2131
+ });
2132
+ }
2133
+ /** Gets the id of the menu panel (popup) associated with this menu */
2134
+ _getPanelId() {
2135
+ return __awaiter(this, void 0, void 0, function* () {
2136
+ const panelId = yield (yield this.host()).getAttribute('aria-controls');
2137
+ return panelId || null;
2138
+ });
2139
+ }
2140
+ }
2141
+ /**
2142
+ * The selector for the host element of a `MenuComponent` instance,
2143
+ * i.e. the button element used to open the menu.
2144
+ */
2145
+ GraniteMenuHarness.hostSelector = '.granite-menu-trigger';
2146
+ class GraniteMenuItemHarness extends ComponentHarness {
2147
+ /**
2148
+ * Gets a `HarnessPredicate` that can be used to search for a `GraniteMenuItemHarness` that meets
2149
+ * certain criteria.
2150
+ * @param options Options for filtering which menu item instances are considered a match.
2151
+ * @return a `HarnessPredicate` configured with the given options.
2152
+ */
2153
+ static with(options = {}) {
2154
+ return new HarnessPredicate(GraniteMenuItemHarness, options).addOption('text', options.text,
2155
+ /* @dynamic */ (harness, text) => HarnessPredicate.stringMatches(harness.getText(), text));
2156
+ }
2157
+ /** Gets the text of the menu item. */
2158
+ getText() {
2159
+ return __awaiter(this, void 0, void 0, function* () {
2160
+ return (yield this.host()).text();
2161
+ });
2162
+ }
2163
+ /** Whether this item has a submenu. */
2164
+ hasSubmenu() {
2165
+ return __awaiter(this, void 0, void 0, function* () {
2166
+ return (yield this.host()).matchesSelector(GraniteMenuHarness.hostSelector);
2167
+ });
2168
+ }
2169
+ /** Gets the submenu associated with this menu item, or null if none. */
2170
+ getSubmenu() {
2171
+ return __awaiter(this, void 0, void 0, function* () {
2172
+ if (yield this.hasSubmenu()) {
2173
+ return new GraniteMenuHarness(this.locatorFactory);
2174
+ }
2175
+ return null;
2176
+ });
2177
+ }
2178
+ /** Clicks the menu item. */
2179
+ click() {
2180
+ return __awaiter(this, void 0, void 0, function* () {
2181
+ yield (yield this.host()).click();
2182
+ // This is necessary so that we wait for the opening animation to finish. (i.e. if it opens another menu)
2183
+ return this.forceStabilize();
2184
+ });
2185
+ }
2186
+ }
2187
+ /** The selector for the host element of a `MenuItemComponent` instance. */
2188
+ GraniteMenuItemHarness.hostSelector = '.granite-menu-item';
2189
+
2190
+ class GraniteToggleSwitchComponent {
2191
+ constructor(_focusMonitor) {
2192
+ this._focusMonitor = _focusMonitor;
2193
+ this.id = null;
2194
+ this.checked = false;
2195
+ this.disabled = false;
2196
+ this.readonly = false;
2197
+ this.labelPosition = 'after';
2198
+ this.ariaLabel = null;
2199
+ this.ariaLabelledby = null;
2200
+ this.valueChange = new EventEmitter();
2201
+ this.toggleChange = new EventEmitter();
2202
+ this.toggleBlur = new EventEmitter();
2203
+ this._positionBefore = false;
2204
+ this._toggleSwitchDisabled = false;
2205
+ }
2206
+ ngOnChanges(changes) {
2207
+ if (changes.checked) {
2208
+ this.checked = coerceBooleanProperty(changes.checked.currentValue);
2209
+ }
2210
+ if (changes.disabled) {
2211
+ this.disabled = coerceBooleanProperty(changes.disabled.currentValue);
2212
+ }
2213
+ if (changes.readonly) {
2214
+ this.readonly = coerceBooleanProperty(changes.readonly.currentValue);
2215
+ }
2216
+ if (changes.labelPosition != null) {
2217
+ this._positionBefore =
2218
+ changes.labelPosition.currentValue != null &&
2219
+ changes.labelPosition.currentValue === 'before';
2220
+ }
2221
+ if ((changes.disabled || changes.readonly) &&
2222
+ (this.disabled || this.readonly)) {
2223
+ this._toggleSwitchDisabled = true;
2224
+ }
2225
+ }
2226
+ focus(origin = 'program', options) {
2227
+ this._focusMonitor.focusVia(this._getInputElement(), origin, options);
2228
+ }
2229
+ _onBlur() {
2230
+ this.toggleBlur.emit();
2231
+ }
2232
+ _toggleSwitchChange() {
2233
+ this.checked = this._getInputElement().checked;
2234
+ this.valueChange.emit(this.checked);
2235
+ }
2236
+ _toggleSwitchClick() {
2237
+ this.toggleChange.emit();
2238
+ }
2239
+ _getInputElement() {
2240
+ return this._inputElement.nativeElement;
2241
+ }
2242
+ }
2243
+ GraniteToggleSwitchComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteToggleSwitchComponent, deps: [{ token: i1.FocusMonitor }], target: i0.ɵɵFactoryTarget.Component });
2244
+ GraniteToggleSwitchComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: GraniteToggleSwitchComponent, selector: "granite-toggle-switch", inputs: { id: "id", checked: "checked", disabled: "disabled", readonly: "readonly", labelPosition: "labelPosition", ariaLabel: ["aria-label", "ariaLabel"], ariaLabelledby: ["aria-labelledby", "ariaLabelledby"] }, outputs: { valueChange: "valueChange", toggleChange: "toggleChange", toggleBlur: "toggleBlur" }, host: { properties: { "class.granite-toggle-switch-checked": "checked", "class.granite-toggle-switch-disabled": "disabled", "class.granite-toggle-switch-readonly": "readonly", "class.granite-toggle-switch-label-before": "_positionBefore" }, classAttribute: "granite-toggle-switch" }, viewQueries: [{ propertyName: "_inputElement", first: true, predicate: ["input"], descendants: true }], exportAs: ["graniteToggleSwitch"], usesOnChanges: true, ngImport: i0, template: "<label [attr.for]=\"id\" class=\"granite-toggle-switch-label\">\n <div class=\"granite-toggle-switch-bar\">\n <input\n #input\n [id]=\"id\"\n class=\"granite-toggle-switch-input cdk-visually-hidden\"\n role=\"switch\"\n type=\"checkbox\"\n [attr.aria-checked]=\"checked.toString()\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-labelledby]=\"ariaLabelledby\"\n [checked]=\"checked\"\n [disabled]=\"_toggleSwitchDisabled\"\n [readonly]=\"readonly\"\n (click)=\"_toggleSwitchClick()\"\n (change)=\"_toggleSwitchChange()\"\n (blur)=\"_onBlur()\"\n />\n <div class=\"granite-toggle-switch-thumb\"></div>\n </div>\n <span class=\"granite-toggle-switch-text\"><ng-content></ng-content></span>\n</label>\n", styles: [".cdk-visually-hidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;white-space:nowrap;outline:0;-webkit-appearance:none;-moz-appearance:none;left:0}[dir=rtl] .cdk-visually-hidden{left:auto;right:0}:host{box-sizing:border-box}:host *,:host *:before,:host *:after{box-sizing:inherit;cursor:pointer}:host(.granite-toggle-switch){color:var(--granite-color-text)}:host(.granite-toggle-switch-checked) .granite-toggle-switch-bar{background-color:var(--granite-color-background-active)}:host(.granite-toggle-switch-checked) .granite-toggle-switch-thumb{border:.0625rem solid var(--granite-color-background-active)}html[dir=ltr] :host(.granite-toggle-switch-checked) .granite-toggle-switch-thumb{float:right}:host-context([dir=ltr]) :host(.granite-toggle-switch-checked) .granite-toggle-switch-thumb{float:right}html[dir=rtl] :host(.granite-toggle-switch-checked) .granite-toggle-switch-thumb{float:left}:host-context([dir=rtl]) :host(.granite-toggle-switch-checked) .granite-toggle-switch-thumb{float:left}:host(.granite-toggle-switch-disabled) .granite-toggle-switch-label{opacity:.6}:host(.granite-toggle-switch-disabled) *{cursor:default}:host(.granite-toggle-switch-readonly) *{cursor:default}:host(.granite-toggle-switch-label-before) .granite-toggle-switch-label{flex-direction:row-reverse}:host(.granite-toggle-switch-label-before) .granite-toggle-switch-text{padding-inline-start:0;padding-inline-end:var(--granite-spacing-s)}.granite-toggle-switch-label{display:flex;align-items:center;width:max-content}.granite-toggle-switch-bar{width:2rem;height:1rem;border-radius:.5rem;background-color:var(--granite-color-background-inactive);transition:background-color .1s linear;position:relative}.granite-toggle-switch-bar:focus-within{box-shadow:0 0 0 .0625rem var(--granite-color-focus)}.granite-toggle-switch-thumb{width:1rem;height:1rem;border-radius:1rem;background-color:var(--granite-color-text-static-light);border:.0625rem solid var(--granite-color-background-inactive);transition:float .1s linear}html[dir=ltr] .granite-toggle-switch-thumb{float:left}:host-context([dir=ltr]) .granite-toggle-switch-thumb{float:left}html[dir=rtl] .granite-toggle-switch-thumb{float:right}:host-context([dir=rtl]) .granite-toggle-switch-thumb{float:right}.granite-toggle-switch-text{padding-inline-start:var(--granite-spacing-s)}.granite-toggle-switch-text:empty{display:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2245
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteToggleSwitchComponent, decorators: [{
2246
+ type: Component,
2247
+ args: [{ selector: 'granite-toggle-switch', exportAs: 'graniteToggleSwitch', host: {
2248
+ class: 'granite-toggle-switch',
2249
+ '[class.granite-toggle-switch-checked]': 'checked',
2250
+ '[class.granite-toggle-switch-disabled]': 'disabled',
2251
+ '[class.granite-toggle-switch-readonly]': 'readonly',
2252
+ '[class.granite-toggle-switch-label-before]': '_positionBefore',
2253
+ }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<label [attr.for]=\"id\" class=\"granite-toggle-switch-label\">\n <div class=\"granite-toggle-switch-bar\">\n <input\n #input\n [id]=\"id\"\n class=\"granite-toggle-switch-input cdk-visually-hidden\"\n role=\"switch\"\n type=\"checkbox\"\n [attr.aria-checked]=\"checked.toString()\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-labelledby]=\"ariaLabelledby\"\n [checked]=\"checked\"\n [disabled]=\"_toggleSwitchDisabled\"\n [readonly]=\"readonly\"\n (click)=\"_toggleSwitchClick()\"\n (change)=\"_toggleSwitchChange()\"\n (blur)=\"_onBlur()\"\n />\n <div class=\"granite-toggle-switch-thumb\"></div>\n </div>\n <span class=\"granite-toggle-switch-text\"><ng-content></ng-content></span>\n</label>\n", styles: [".cdk-visually-hidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;white-space:nowrap;outline:0;-webkit-appearance:none;-moz-appearance:none;left:0}[dir=rtl] .cdk-visually-hidden{left:auto;right:0}:host{box-sizing:border-box}:host *,:host *:before,:host *:after{box-sizing:inherit;cursor:pointer}:host(.granite-toggle-switch){color:var(--granite-color-text)}:host(.granite-toggle-switch-checked) .granite-toggle-switch-bar{background-color:var(--granite-color-background-active)}:host(.granite-toggle-switch-checked) .granite-toggle-switch-thumb{border:.0625rem solid var(--granite-color-background-active)}html[dir=ltr] :host(.granite-toggle-switch-checked) .granite-toggle-switch-thumb{float:right}:host-context([dir=ltr]) :host(.granite-toggle-switch-checked) .granite-toggle-switch-thumb{float:right}html[dir=rtl] :host(.granite-toggle-switch-checked) .granite-toggle-switch-thumb{float:left}:host-context([dir=rtl]) :host(.granite-toggle-switch-checked) .granite-toggle-switch-thumb{float:left}:host(.granite-toggle-switch-disabled) .granite-toggle-switch-label{opacity:.6}:host(.granite-toggle-switch-disabled) *{cursor:default}:host(.granite-toggle-switch-readonly) *{cursor:default}:host(.granite-toggle-switch-label-before) .granite-toggle-switch-label{flex-direction:row-reverse}:host(.granite-toggle-switch-label-before) .granite-toggle-switch-text{padding-inline-start:0;padding-inline-end:var(--granite-spacing-s)}.granite-toggle-switch-label{display:flex;align-items:center;width:max-content}.granite-toggle-switch-bar{width:2rem;height:1rem;border-radius:.5rem;background-color:var(--granite-color-background-inactive);transition:background-color .1s linear;position:relative}.granite-toggle-switch-bar:focus-within{box-shadow:0 0 0 .0625rem var(--granite-color-focus)}.granite-toggle-switch-thumb{width:1rem;height:1rem;border-radius:1rem;background-color:var(--granite-color-text-static-light);border:.0625rem solid var(--granite-color-background-inactive);transition:float .1s linear}html[dir=ltr] .granite-toggle-switch-thumb{float:left}:host-context([dir=ltr]) .granite-toggle-switch-thumb{float:left}html[dir=rtl] .granite-toggle-switch-thumb{float:right}:host-context([dir=rtl]) .granite-toggle-switch-thumb{float:right}.granite-toggle-switch-text{padding-inline-start:var(--granite-spacing-s)}.granite-toggle-switch-text:empty{display:none}\n"] }]
2254
+ }], ctorParameters: function () { return [{ type: i1.FocusMonitor }]; }, propDecorators: { id: [{
2255
+ type: Input
2256
+ }], checked: [{
2257
+ type: Input
2258
+ }], disabled: [{
2259
+ type: Input
2260
+ }], readonly: [{
2261
+ type: Input
2262
+ }], labelPosition: [{
2263
+ type: Input
2264
+ }], ariaLabel: [{
2265
+ type: Input,
2266
+ args: ['aria-label']
2267
+ }], ariaLabelledby: [{
2268
+ type: Input,
2269
+ args: ['aria-labelledby']
2270
+ }], valueChange: [{
2271
+ type: Output
2272
+ }], toggleChange: [{
2273
+ type: Output
2274
+ }], toggleBlur: [{
2275
+ type: Output
2276
+ }], _inputElement: [{
2277
+ type: ViewChild,
2278
+ args: ['input']
2279
+ }] } });
2280
+
2281
+ class GraniteToggleSwitchModule {
2282
+ }
2283
+ GraniteToggleSwitchModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteToggleSwitchModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2284
+ GraniteToggleSwitchModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteToggleSwitchModule, declarations: [GraniteToggleSwitchComponent], exports: [GraniteToggleSwitchComponent] });
2285
+ GraniteToggleSwitchModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteToggleSwitchModule });
2286
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteToggleSwitchModule, decorators: [{
2287
+ type: NgModule,
2288
+ args: [{
2289
+ declarations: [GraniteToggleSwitchComponent],
2290
+ exports: [GraniteToggleSwitchComponent],
2291
+ }]
2292
+ }] });
2293
+
2294
+ class GraniteRadioButtonComponent {
2295
+ constructor(_focusMonitor, _radioDispatcher) {
2296
+ this._focusMonitor = _focusMonitor;
2297
+ this._radioDispatcher = _radioDispatcher;
2298
+ this.id = null;
2299
+ this.checked = false;
2300
+ this.required = false;
2301
+ this.disabled = false;
2302
+ this.readonly = false;
2303
+ this.labelPosition = 'after';
2304
+ this.ariaLabel = null;
2305
+ this.ariaLabelledby = null;
2306
+ this.radioChange = new EventEmitter();
2307
+ this.radioBlur = new EventEmitter();
2308
+ this._positionBefore = false;
2309
+ this._radioDisabled = false;
2310
+ this._removeUniqueSelectionListenerFn = _radioDispatcher.listen((id, name) => {
2311
+ if (id !== this.id && name === this.name) {
2312
+ this.checked = false;
2313
+ }
2314
+ });
2315
+ }
2316
+ ngOnChanges(changes) {
2317
+ if (changes.checked) {
2318
+ this.checked = coerceBooleanProperty(changes.checked.currentValue);
2319
+ }
2320
+ if (changes.required) {
2321
+ this.required = coerceBooleanProperty(changes.required.currentValue);
2322
+ }
2323
+ if (changes.readonly) {
2324
+ this.readonly = coerceBooleanProperty(changes.readonly.currentValue);
2325
+ }
2326
+ if (changes.disabled) {
2327
+ this.disabled = coerceBooleanProperty(changes.disabled.currentValue);
2328
+ }
2329
+ if (changes.labelPosition != null) {
2330
+ this._positionBefore =
2331
+ changes.labelPosition.currentValue != null &&
2332
+ changes.labelPosition.currentValue === 'before';
2333
+ }
2334
+ if ((changes.disabled || changes.readonly) &&
2335
+ (this.disabled || this.readonly)) {
2336
+ this._radioDisabled = true;
2337
+ }
2338
+ }
2339
+ ngOnDestroy() {
2340
+ if (this._removeUniqueSelectionListenerFn instanceof Function) {
2341
+ this._removeUniqueSelectionListenerFn();
2342
+ }
2343
+ }
2344
+ // Focuses the radio button.
2345
+ focus(origin = 'program', options) {
2346
+ this._focusMonitor.focusVia(this._getInputElement(), origin, options);
2347
+ }
2348
+ _radioClick(element) {
2349
+ this.radioChange.emit(element === null || element === void 0 ? void 0 : element.value);
2350
+ }
2351
+ _radioChange() {
2352
+ this.checked = this._getInputElement().checked;
2353
+ // Notify all radio buttons with the same name to un-check
2354
+ this._radioDispatcher.notify(this.id, this.name);
2355
+ }
2356
+ _onBlur() {
2357
+ this.radioBlur.emit();
2358
+ }
2359
+ _getInputElement() {
2360
+ return this._inputElement.nativeElement;
2361
+ }
2362
+ }
2363
+ GraniteRadioButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteRadioButtonComponent, deps: [{ token: i1.FocusMonitor }, { token: i2$1.UniqueSelectionDispatcher }], target: i0.ɵɵFactoryTarget.Component });
2364
+ GraniteRadioButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: GraniteRadioButtonComponent, selector: "granite-radio-button", inputs: { value: "value", id: "id", name: "name", checked: "checked", required: "required", disabled: "disabled", readonly: "readonly", labelPosition: "labelPosition", ariaLabel: ["aria-label", "ariaLabel"], ariaLabelledby: ["aria-labelledby", "ariaLabelledby"] }, outputs: { radioChange: "radioChange", radioBlur: "radioBlur" }, host: { properties: { "class.granite-radio-button-disabled": "disabled", "class.granite-radio-button-label-before": "_positionBefore", "class.granite-radio-button-checked": "checked", "class.granite-radio-button-readonly": "readonly" }, classAttribute: "granite-radio-button" }, viewQueries: [{ propertyName: "_inputElement", first: true, predicate: ["input"], descendants: true }], exportAs: ["graniteRadioButton"], usesOnChanges: true, ngImport: i0, template: "<label class=\"granite-radio-button-label\">\n <div class=\"granite-radio-button-outer-circle\">\n <input\n #input\n [id]=\"id\"\n class=\"granite-radio-button-input cdk-visually-hidden\"\n type=\"radio\"\n [attr.name]=\"name\"\n [disabled]=\"_radioDisabled\"\n [checked]=\"checked\"\n [readonly]=\"readonly\"\n [required]=\"required\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-labelledby]=\"ariaLabelledby\"\n [attr.aria-checked]=\"checked.toString()\"\n [value]=\"value\"\n (click)=\"_radioClick($event.target)\"\n (change)=\"_radioChange()\"\n (blur)=\"_onBlur()\"\n />\n <div class=\"granite-radio-button-inner-circle\"></div>\n </div>\n <span class=\"granite-radio-button-text\">\n <ng-content></ng-content>\n </span>\n</label>\n", styles: [".cdk-visually-hidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;white-space:nowrap;outline:0;-webkit-appearance:none;-moz-appearance:none;left:0}[dir=rtl] .cdk-visually-hidden{left:auto;right:0}:host(.granite-radio-button):not(.granite-radio-button-readonly):not(.granite-radio-button-disabled) .granite-radio-button-label:hover{cursor:pointer}:host(.granite-radio-button):not(.granite-radio-button-readonly):not(.granite-radio-button-disabled) .granite-radio-button-label:hover .granite-radio-button-outer-circle{border-color:var(--granite-color-background-active-hover)}:host(.granite-radio-button):not(.granite-radio-button-readonly):not(.granite-radio-button-disabled) .granite-radio-button-label:hover .granite-radio-button-inner-circle{background-color:var(--granite-color-background-active-hover)}:host(.granite-radio-button):not(.granite-radio-button-readonly):not(.granite-radio-button-disabled) .granite-radio-button-outer-circle:focus-within{border:.0625rem solid var(--granite-color-focus)}:host(.granite-radio-button-label-before) .granite-radio-button-label{flex-direction:row-reverse}:host(.granite-radio-button-label-before) .granite-radio-button-text{padding-inline-start:0;padding-inline-end:var(--granite-spacing-s)}:host(.granite-radio-button-checked) .granite-radio-button-inner-circle{visibility:visible;animation:growAnimation .1s}:host(.granite-radio-button-checked) .granite-radio-button-outer-circle{border-color:var(--granite-color-background-active)}:host(.granite-radio-button-checked).granite-radio-button-disabled .granite-radio-button-inner-circle{background-color:var(--granite-color-text)}:host(.granite-radio-button-checked).granite-radio-button-disabled .granite-radio-button-outer-circle{border:.0625rem solid var(--granite-color-text);background-color:transparent}:host(.granite-radio-button-checked).granite-radio-button-readonly .granite-radio-button-inner-circle{background-color:var(--granite-color-text)}:host(.granite-radio-button-checked).granite-radio-button-readonly .granite-radio-button-outer-circle{border:.0625rem solid var(--granite-color-text)}.granite-radio-button-text{padding-inline-start:var(--granite-spacing-s);color:var(--granite-color-text)}.granite-radio-button-text:empty{display:none}.granite-radio-button-label{display:flex;align-items:center;width:max-content;margin-inline-end:var(--granite-spacing-xl)}:host(.granite-radio-button-disabled) .granite-radio-button-text{opacity:.6}:host(.granite-radio-button-disabled) .granite-radio-button-outer-circle{opacity:.3;background-color:var(--granite-color-border-soft)}.granite-radio-button-outer-circle{height:1rem;width:1rem;border-radius:50%;box-sizing:border-box;border:.0625rem solid var(--granite-color-border-hard);display:flex;justify-content:center;position:relative;align-items:center}.granite-radio-button-inner-circle{width:.625rem;height:.625rem;visibility:hidden;position:absolute;border-radius:50%;background-color:var(--granite-color-background-active);margin:auto}@keyframes growAnimation{0%{transform:scale(0)}to{transform:scale(1)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2365
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteRadioButtonComponent, decorators: [{
2366
+ type: Component,
2367
+ args: [{ selector: 'granite-radio-button', exportAs: 'graniteRadioButton', host: {
2368
+ class: 'granite-radio-button',
2369
+ '[class.granite-radio-button-disabled]': 'disabled',
2370
+ '[class.granite-radio-button-label-before]': '_positionBefore',
2371
+ '[class.granite-radio-button-checked]': 'checked',
2372
+ '[class.granite-radio-button-readonly]': 'readonly',
2373
+ }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<label class=\"granite-radio-button-label\">\n <div class=\"granite-radio-button-outer-circle\">\n <input\n #input\n [id]=\"id\"\n class=\"granite-radio-button-input cdk-visually-hidden\"\n type=\"radio\"\n [attr.name]=\"name\"\n [disabled]=\"_radioDisabled\"\n [checked]=\"checked\"\n [readonly]=\"readonly\"\n [required]=\"required\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-labelledby]=\"ariaLabelledby\"\n [attr.aria-checked]=\"checked.toString()\"\n [value]=\"value\"\n (click)=\"_radioClick($event.target)\"\n (change)=\"_radioChange()\"\n (blur)=\"_onBlur()\"\n />\n <div class=\"granite-radio-button-inner-circle\"></div>\n </div>\n <span class=\"granite-radio-button-text\">\n <ng-content></ng-content>\n </span>\n</label>\n", styles: [".cdk-visually-hidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;white-space:nowrap;outline:0;-webkit-appearance:none;-moz-appearance:none;left:0}[dir=rtl] .cdk-visually-hidden{left:auto;right:0}:host(.granite-radio-button):not(.granite-radio-button-readonly):not(.granite-radio-button-disabled) .granite-radio-button-label:hover{cursor:pointer}:host(.granite-radio-button):not(.granite-radio-button-readonly):not(.granite-radio-button-disabled) .granite-radio-button-label:hover .granite-radio-button-outer-circle{border-color:var(--granite-color-background-active-hover)}:host(.granite-radio-button):not(.granite-radio-button-readonly):not(.granite-radio-button-disabled) .granite-radio-button-label:hover .granite-radio-button-inner-circle{background-color:var(--granite-color-background-active-hover)}:host(.granite-radio-button):not(.granite-radio-button-readonly):not(.granite-radio-button-disabled) .granite-radio-button-outer-circle:focus-within{border:.0625rem solid var(--granite-color-focus)}:host(.granite-radio-button-label-before) .granite-radio-button-label{flex-direction:row-reverse}:host(.granite-radio-button-label-before) .granite-radio-button-text{padding-inline-start:0;padding-inline-end:var(--granite-spacing-s)}:host(.granite-radio-button-checked) .granite-radio-button-inner-circle{visibility:visible;animation:growAnimation .1s}:host(.granite-radio-button-checked) .granite-radio-button-outer-circle{border-color:var(--granite-color-background-active)}:host(.granite-radio-button-checked).granite-radio-button-disabled .granite-radio-button-inner-circle{background-color:var(--granite-color-text)}:host(.granite-radio-button-checked).granite-radio-button-disabled .granite-radio-button-outer-circle{border:.0625rem solid var(--granite-color-text);background-color:transparent}:host(.granite-radio-button-checked).granite-radio-button-readonly .granite-radio-button-inner-circle{background-color:var(--granite-color-text)}:host(.granite-radio-button-checked).granite-radio-button-readonly .granite-radio-button-outer-circle{border:.0625rem solid var(--granite-color-text)}.granite-radio-button-text{padding-inline-start:var(--granite-spacing-s);color:var(--granite-color-text)}.granite-radio-button-text:empty{display:none}.granite-radio-button-label{display:flex;align-items:center;width:max-content;margin-inline-end:var(--granite-spacing-xl)}:host(.granite-radio-button-disabled) .granite-radio-button-text{opacity:.6}:host(.granite-radio-button-disabled) .granite-radio-button-outer-circle{opacity:.3;background-color:var(--granite-color-border-soft)}.granite-radio-button-outer-circle{height:1rem;width:1rem;border-radius:50%;box-sizing:border-box;border:.0625rem solid var(--granite-color-border-hard);display:flex;justify-content:center;position:relative;align-items:center}.granite-radio-button-inner-circle{width:.625rem;height:.625rem;visibility:hidden;position:absolute;border-radius:50%;background-color:var(--granite-color-background-active);margin:auto}@keyframes growAnimation{0%{transform:scale(0)}to{transform:scale(1)}}\n"] }]
2374
+ }], ctorParameters: function () { return [{ type: i1.FocusMonitor }, { type: i2$1.UniqueSelectionDispatcher }]; }, propDecorators: { value: [{
2375
+ type: Input
2376
+ }], id: [{
2377
+ type: Input
2378
+ }], name: [{
2379
+ type: Input
2380
+ }], checked: [{
2381
+ type: Input
2382
+ }], required: [{
2383
+ type: Input
2384
+ }], disabled: [{
2385
+ type: Input
2386
+ }], readonly: [{
2387
+ type: Input
2388
+ }], labelPosition: [{
2389
+ type: Input
2390
+ }], ariaLabel: [{
2391
+ type: Input,
2392
+ args: ['aria-label']
2393
+ }], ariaLabelledby: [{
2394
+ type: Input,
2395
+ args: ['aria-labelledby']
2396
+ }], radioChange: [{
2397
+ type: Output
2398
+ }], radioBlur: [{
2399
+ type: Output
2400
+ }], _inputElement: [{
2401
+ type: ViewChild,
2402
+ args: ['input']
2403
+ }] } });
2404
+
2405
+ class GraniteRadioCheckboxBase {
2406
+ constructor() {
2407
+ this.layout = 'horizontal';
2408
+ this.ariaLabelledby = null;
2409
+ }
2410
+ }
2411
+ GraniteRadioCheckboxBase.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteRadioCheckboxBase, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2412
+ GraniteRadioCheckboxBase.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.11", type: GraniteRadioCheckboxBase, inputs: { layout: "layout", ariaLabelledby: ["aria-labelledby", "ariaLabelledby"] }, ngImport: i0 });
2413
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteRadioCheckboxBase, decorators: [{
2414
+ type: Directive
2415
+ }], propDecorators: { layout: [{
2416
+ type: Input
2417
+ }], ariaLabelledby: [{
2418
+ type: Input,
2419
+ args: ['aria-labelledby']
2420
+ }] } });
2421
+
2422
+ class GraniteRadioGroupComponent extends GraniteRadioCheckboxBase {
2423
+ }
2424
+ GraniteRadioGroupComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteRadioGroupComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
2425
+ GraniteRadioGroupComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: GraniteRadioGroupComponent, selector: "granite-radio-group", host: { properties: { "attr.role": "\"radiogroup\"", "attr.aria-labelledby": "ariaLabelledby", "class.granite-radio-checkbox-base-layout-horizontal": "layout === \"horizontal\"" }, classAttribute: "granite-radio-group" }, usesInheritance: true, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host(.granite-radio-checkbox-base-layout-horizontal){display:flex;align-items:flex-start}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2426
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteRadioGroupComponent, decorators: [{
2427
+ type: Component,
2428
+ args: [{ selector: 'granite-radio-group', host: {
2429
+ class: 'granite-radio-group',
2430
+ '[attr.role]': '"radiogroup"',
2431
+ '[attr.aria-labelledby]': 'ariaLabelledby',
2432
+ '[class.granite-radio-checkbox-base-layout-horizontal]': 'layout === "horizontal"',
2433
+ }, template: '<ng-content></ng-content>', changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host(.granite-radio-checkbox-base-layout-horizontal){display:flex;align-items:flex-start}\n"] }]
2434
+ }] });
2435
+
2436
+ class GraniteRadioButtonModule {
2437
+ }
2438
+ GraniteRadioButtonModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteRadioButtonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2439
+ GraniteRadioButtonModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteRadioButtonModule, declarations: [GraniteRadioButtonComponent, GraniteRadioGroupComponent], exports: [GraniteRadioButtonComponent, GraniteRadioGroupComponent] });
2440
+ GraniteRadioButtonModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteRadioButtonModule });
2441
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteRadioButtonModule, decorators: [{
2442
+ type: NgModule,
2443
+ args: [{
2444
+ declarations: [GraniteRadioButtonComponent, GraniteRadioGroupComponent],
2445
+ exports: [GraniteRadioButtonComponent, GraniteRadioGroupComponent],
2446
+ }]
2447
+ }] });
2448
+
2449
+ class GraniteCheckboxComponent {
2450
+ constructor(_focusMonitor) {
2451
+ this._focusMonitor = _focusMonitor;
2452
+ this.id = null;
2453
+ this.checked = false;
2454
+ this.disabled = false;
2455
+ this.readonly = false;
2456
+ this.labelPosition = 'after';
2457
+ this.ariaLabel = null;
2458
+ this.ariaLabelledby = null;
2459
+ this.valueChange = new EventEmitter();
2460
+ this.checkboxChange = new EventEmitter();
2461
+ this.checkboxBlur = new EventEmitter();
2462
+ this._positionBefore = false;
2463
+ this._checkboxDisabled = false;
2464
+ }
2465
+ ngOnChanges(changes) {
2466
+ if (changes.checked) {
2467
+ this.checked = coerceBooleanProperty(changes.checked.currentValue);
2468
+ }
2469
+ if (changes.disabled) {
2470
+ this.disabled = coerceBooleanProperty(changes.disabled.currentValue);
2471
+ }
2472
+ if (changes.readonly) {
2473
+ this.readonly = coerceBooleanProperty(changes.readonly.currentValue);
2474
+ }
2475
+ if (changes.labelPosition != null) {
2476
+ this._positionBefore =
2477
+ changes.labelPosition.currentValue != null &&
2478
+ changes.labelPosition.currentValue === 'before';
2479
+ }
2480
+ if ((changes.disabled || changes.readonly) &&
2481
+ (this.disabled || this.readonly)) {
2482
+ this._checkboxDisabled = true;
2483
+ }
2484
+ }
2485
+ focus(origin = 'program', options) {
2486
+ this._focusMonitor.focusVia(this._getInputElement(), origin, options);
2487
+ }
2488
+ _onBlur() {
2489
+ this.checkboxBlur.emit();
2490
+ }
2491
+ _checkboxChange() {
2492
+ this.checked = this._getInputElement().checked;
2493
+ this.valueChange.emit(this.checked);
2494
+ }
2495
+ _checkboxClick() {
2496
+ this.checkboxChange.emit();
2497
+ }
2498
+ _getInputElement() {
2499
+ return this._inputElement.nativeElement;
2500
+ }
2501
+ }
2502
+ GraniteCheckboxComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteCheckboxComponent, deps: [{ token: i1.FocusMonitor }], target: i0.ɵɵFactoryTarget.Component });
2503
+ GraniteCheckboxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: GraniteCheckboxComponent, selector: "granite-checkbox", inputs: { id: "id", checked: "checked", disabled: "disabled", readonly: "readonly", labelPosition: "labelPosition", ariaLabel: ["aria-label", "ariaLabel"], ariaLabelledby: ["aria-labelledby", "ariaLabelledby"] }, outputs: { valueChange: "valueChange", checkboxChange: "checkboxChange", checkboxBlur: "checkboxBlur" }, host: { properties: { "class.granite-checkbox-checked": "checked", "class.granite-checkbox-disabled": "disabled", "class.granite-checkbox-readonly": "readonly", "class.granite-checkbox-label-before": "_positionBefore" }, classAttribute: "granite-checkbox" }, viewQueries: [{ propertyName: "_inputElement", first: true, predicate: ["input"], descendants: true }], exportAs: ["graniteCheckbox"], usesOnChanges: true, ngImport: i0, template: "<label [attr.for]=\"id\" class=\"granite-checkbox-label\">\n <div class=\"granite-checkbox-box\">\n <input\n #input\n [id]=\"id\"\n class=\"granite-checkbox-input cdk-visually-hidden\"\n role=\"checkbox\"\n type=\"checkbox\"\n [attr.aria-checked]=\"checked.toString()\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-labelledby]=\"ariaLabelledby\"\n [checked]=\"checked\"\n [disabled]=\"_checkboxDisabled\"\n [readonly]=\"readonly\"\n (click)=\"_checkboxClick()\"\n (change)=\"_checkboxChange()\"\n (blur)=\"_onBlur()\"\n />\n <div class=\"granite-checkbox-check\"></div>\n </div>\n <span class=\"granite-checkbox-text\"><ng-content></ng-content></span>\n</label>\n", styles: [".cdk-visually-hidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;white-space:nowrap;outline:0;-webkit-appearance:none;-moz-appearance:none;left:0}[dir=rtl] .cdk-visually-hidden{left:auto;right:0}:host{box-sizing:border-box}:host *,:host *:before,:host *:after{box-sizing:inherit;cursor:pointer}:host(.granite-checkbox){color:var(--granite-color-text)}:host(.granite-checkbox):not(.granite-checkbox-checked):not(.granite-checkbox-readonly):not(.granite-checkbox-disabled) .granite-checkbox-label:hover .granite-checkbox-box{border-color:var(--granite-color-background-active)}:host(.granite-checkbox-checked):not(.granite-checkbox-readonly):not(.granite-checkbox-disabled) .granite-checkbox-label:hover .granite-checkbox-box{background-color:var(--granite-color-background-active-hover);border-color:var(--granite-color-background-active-hover)}:host(.granite-checkbox-checked) .granite-checkbox-box{border-color:var(--granite-color-background-active);background-color:var(--granite-color-background-active)}:host(.granite-checkbox-checked) .granite-checkbox-box:focus-within{border-color:var(--granite-color-focus)}:host(.granite-checkbox-checked) .granite-checkbox-check{display:flex}:host(.granite-checkbox-checked):not(.granite-checkbox-readonly):not(.granite-checkbox-disabled) .granite-checkbox-box{animation:fadeInAnimation .2s;animation-iteration-count:1}:host(:not(.granite-checkbox-checked)) .granite-checkbox-box{animation:fadeOutAnimation .2s;animation-iteration-count:1}:host(.granite-checkbox-readonly.granite-checkbox-checked) .granite-checkbox-box{background-color:var(--granite-color-text);border-color:var(--granite-color-text)}:host(.granite-checkbox-readonly.granite-checkbox-checked) .granite-checkbox-box .granite-checkbox-check{border-color:var(--granite-color-background)}:host(.granite-checkbox-disabled) .granite-checkbox-box{opacity:.3;background-color:var(--granite-color-border-soft)}:host(.granite-checkbox-disabled) .granite-checkbox-label{opacity:.6}:host(.granite-checkbox-disabled) *{cursor:default}:host(.granite-checkbox-readonly) *{cursor:default}:host(.granite-checkbox-label-before) .granite-checkbox-label{flex-direction:row-reverse}:host(.granite-checkbox-label-before) .granite-checkbox-text{padding-inline-start:0;padding-inline-end:var(--granite-spacing-s)}.granite-checkbox-label{display:flex;align-items:center;width:max-content;margin-inline-end:var(--granite-spacing-xl)}.granite-checkbox-box{width:1rem;height:1rem;border:solid var(--granite-color-background-inactive);border-width:.0625rem;border-radius:.25rem;display:flex;justify-content:center;position:relative}.granite-checkbox-box:focus-within{border:.0625rem solid var(--granite-color-focus)}.granite-checkbox-check{position:relative;display:none;width:.5625rem;height:.3125rem;background-color:transparent;border:solid var(--granite-color-text-static-light);transform:rotate(-45deg);margin-top:var(--granite-spacing-xs);border-width:0 0 .125rem .125rem}.granite-checkbox-text{padding-inline-start:var(--granite-spacing-s)}.granite-checkbox-text:empty{display:none}@keyframes fadeInAnimation{0%{opacity:0}to{opacity:1}}@keyframes fadeOutAnimation{0%{opacity:1}to{opacity:0}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2504
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteCheckboxComponent, decorators: [{
2505
+ type: Component,
2506
+ args: [{ selector: 'granite-checkbox', exportAs: 'graniteCheckbox', host: {
2507
+ class: 'granite-checkbox',
2508
+ '[class.granite-checkbox-checked]': 'checked',
2509
+ '[class.granite-checkbox-disabled]': 'disabled',
2510
+ '[class.granite-checkbox-readonly]': 'readonly',
2511
+ '[class.granite-checkbox-label-before]': '_positionBefore',
2512
+ }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<label [attr.for]=\"id\" class=\"granite-checkbox-label\">\n <div class=\"granite-checkbox-box\">\n <input\n #input\n [id]=\"id\"\n class=\"granite-checkbox-input cdk-visually-hidden\"\n role=\"checkbox\"\n type=\"checkbox\"\n [attr.aria-checked]=\"checked.toString()\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-labelledby]=\"ariaLabelledby\"\n [checked]=\"checked\"\n [disabled]=\"_checkboxDisabled\"\n [readonly]=\"readonly\"\n (click)=\"_checkboxClick()\"\n (change)=\"_checkboxChange()\"\n (blur)=\"_onBlur()\"\n />\n <div class=\"granite-checkbox-check\"></div>\n </div>\n <span class=\"granite-checkbox-text\"><ng-content></ng-content></span>\n</label>\n", styles: [".cdk-visually-hidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;white-space:nowrap;outline:0;-webkit-appearance:none;-moz-appearance:none;left:0}[dir=rtl] .cdk-visually-hidden{left:auto;right:0}:host{box-sizing:border-box}:host *,:host *:before,:host *:after{box-sizing:inherit;cursor:pointer}:host(.granite-checkbox){color:var(--granite-color-text)}:host(.granite-checkbox):not(.granite-checkbox-checked):not(.granite-checkbox-readonly):not(.granite-checkbox-disabled) .granite-checkbox-label:hover .granite-checkbox-box{border-color:var(--granite-color-background-active)}:host(.granite-checkbox-checked):not(.granite-checkbox-readonly):not(.granite-checkbox-disabled) .granite-checkbox-label:hover .granite-checkbox-box{background-color:var(--granite-color-background-active-hover);border-color:var(--granite-color-background-active-hover)}:host(.granite-checkbox-checked) .granite-checkbox-box{border-color:var(--granite-color-background-active);background-color:var(--granite-color-background-active)}:host(.granite-checkbox-checked) .granite-checkbox-box:focus-within{border-color:var(--granite-color-focus)}:host(.granite-checkbox-checked) .granite-checkbox-check{display:flex}:host(.granite-checkbox-checked):not(.granite-checkbox-readonly):not(.granite-checkbox-disabled) .granite-checkbox-box{animation:fadeInAnimation .2s;animation-iteration-count:1}:host(:not(.granite-checkbox-checked)) .granite-checkbox-box{animation:fadeOutAnimation .2s;animation-iteration-count:1}:host(.granite-checkbox-readonly.granite-checkbox-checked) .granite-checkbox-box{background-color:var(--granite-color-text);border-color:var(--granite-color-text)}:host(.granite-checkbox-readonly.granite-checkbox-checked) .granite-checkbox-box .granite-checkbox-check{border-color:var(--granite-color-background)}:host(.granite-checkbox-disabled) .granite-checkbox-box{opacity:.3;background-color:var(--granite-color-border-soft)}:host(.granite-checkbox-disabled) .granite-checkbox-label{opacity:.6}:host(.granite-checkbox-disabled) *{cursor:default}:host(.granite-checkbox-readonly) *{cursor:default}:host(.granite-checkbox-label-before) .granite-checkbox-label{flex-direction:row-reverse}:host(.granite-checkbox-label-before) .granite-checkbox-text{padding-inline-start:0;padding-inline-end:var(--granite-spacing-s)}.granite-checkbox-label{display:flex;align-items:center;width:max-content;margin-inline-end:var(--granite-spacing-xl)}.granite-checkbox-box{width:1rem;height:1rem;border:solid var(--granite-color-background-inactive);border-width:.0625rem;border-radius:.25rem;display:flex;justify-content:center;position:relative}.granite-checkbox-box:focus-within{border:.0625rem solid var(--granite-color-focus)}.granite-checkbox-check{position:relative;display:none;width:.5625rem;height:.3125rem;background-color:transparent;border:solid var(--granite-color-text-static-light);transform:rotate(-45deg);margin-top:var(--granite-spacing-xs);border-width:0 0 .125rem .125rem}.granite-checkbox-text{padding-inline-start:var(--granite-spacing-s)}.granite-checkbox-text:empty{display:none}@keyframes fadeInAnimation{0%{opacity:0}to{opacity:1}}@keyframes fadeOutAnimation{0%{opacity:1}to{opacity:0}}\n"] }]
2513
+ }], ctorParameters: function () { return [{ type: i1.FocusMonitor }]; }, propDecorators: { id: [{
2514
+ type: Input
2515
+ }], checked: [{
2516
+ type: Input
2517
+ }], disabled: [{
2518
+ type: Input
2519
+ }], readonly: [{
2520
+ type: Input
2521
+ }], labelPosition: [{
2522
+ type: Input
2523
+ }], ariaLabel: [{
2524
+ type: Input,
2525
+ args: ['aria-label']
2526
+ }], ariaLabelledby: [{
2527
+ type: Input,
2528
+ args: ['aria-labelledby']
2529
+ }], valueChange: [{
2530
+ type: Output
2531
+ }], checkboxChange: [{
2532
+ type: Output
2533
+ }], checkboxBlur: [{
2534
+ type: Output
2535
+ }], _inputElement: [{
2536
+ type: ViewChild,
2537
+ args: ['input']
2538
+ }] } });
2539
+
2540
+ class GraniteCheckboxGroupComponent extends GraniteRadioCheckboxBase {
2541
+ }
2542
+ GraniteCheckboxGroupComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteCheckboxGroupComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
2543
+ GraniteCheckboxGroupComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: GraniteCheckboxGroupComponent, selector: "granite-checkbox-group", host: { properties: { "attr.role": "\"group\"", "attr.aria-labelledby": "ariaLabelledby", "class.granite-radio-checkbox-base-layout-horizontal": "layout === \"horizontal\"" }, classAttribute: "granite-checkbox-group" }, usesInheritance: true, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host(.granite-radio-checkbox-base-layout-horizontal){display:flex;align-items:flex-start}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2544
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteCheckboxGroupComponent, decorators: [{
2545
+ type: Component,
2546
+ args: [{ selector: 'granite-checkbox-group', host: {
2547
+ class: 'granite-checkbox-group',
2548
+ '[attr.role]': '"group"',
2549
+ '[attr.aria-labelledby]': 'ariaLabelledby',
2550
+ '[class.granite-radio-checkbox-base-layout-horizontal]': 'layout === "horizontal"',
2551
+ }, template: '<ng-content></ng-content>', changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host(.granite-radio-checkbox-base-layout-horizontal){display:flex;align-items:flex-start}\n"] }]
2552
+ }] });
2553
+
2554
+ class GraniteCheckboxModule {
2555
+ }
2556
+ GraniteCheckboxModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteCheckboxModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2557
+ GraniteCheckboxModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteCheckboxModule, declarations: [GraniteCheckboxComponent, GraniteCheckboxGroupComponent], exports: [GraniteCheckboxComponent, GraniteCheckboxGroupComponent] });
2558
+ GraniteCheckboxModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteCheckboxModule });
2559
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteCheckboxModule, decorators: [{
2560
+ type: NgModule,
2561
+ args: [{
2562
+ declarations: [GraniteCheckboxComponent, GraniteCheckboxGroupComponent],
2563
+ exports: [GraniteCheckboxComponent, GraniteCheckboxGroupComponent],
2564
+ }]
2565
+ }] });
2566
+
2567
+ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
2568
+ const disabledMixin = (Base = class {
2569
+ }) => {
2570
+ class Derived extends Base {
2571
+ constructor() {
2572
+ super(...arguments);
2573
+ this.disabled = false;
2574
+ }
2575
+ ngOnChanges(changes) {
2576
+ if (changes.disabled) {
2577
+ this.disabled = coerceBooleanProperty(changes.disabled.currentValue);
2578
+ }
2579
+ }
2580
+ }
2581
+ Derived.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: Derived, deps: null, target: i0.ɵɵFactoryTarget.Directive });
2582
+ Derived.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.11", type: Derived, inputs: { disabled: "disabled" }, usesInheritance: true, usesOnChanges: true, ngImport: i0 });
2583
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: Derived, decorators: [{
2584
+ type: Directive
2585
+ }], propDecorators: { disabled: [{
2586
+ type: Input
2587
+ }] } });
2588
+ return Derived;
2589
+ };
2590
+
2591
+ var ButtonSelectors;
2592
+ (function (ButtonSelectors) {
2593
+ ButtonSelectors["graniteButton"] = "granite-button";
2594
+ ButtonSelectors["granitePrimaryButton"] = "granite-primary-button";
2595
+ ButtonSelectors["graniteFlatButton"] = "granite-flat-button";
2596
+ ButtonSelectors["graniteToolbarButton"] = "granite-toolbar-button";
2597
+ })(ButtonSelectors || (ButtonSelectors = {}));
2598
+ const ButtonComponentMixin = disabledMixin();
2599
+ class GraniteButtonComponent extends ButtonComponentMixin {
2600
+ constructor(_focusMonitor, _elementRef) {
2601
+ super();
2602
+ this._focusMonitor = _focusMonitor;
2603
+ this._elementRef = _elementRef;
2604
+ this.toggled = false;
2605
+ this._buttonToggled = false;
2606
+ for (const selector of Object.keys(ButtonSelectors)) {
2607
+ if (this._getHostElement().hasAttribute(selector)) {
2608
+ this._getHostElement().classList.add(ButtonSelectors[selector]);
2609
+ }
2610
+ }
2611
+ }
2612
+ ngOnChanges(changes) {
2613
+ super.ngOnChanges(changes);
2614
+ if (changes.toggled &&
2615
+ (this._getHostElement().classList.contains(ButtonSelectors.graniteFlatButton) ||
2616
+ this._getHostElement().classList.contains(ButtonSelectors.graniteToolbarButton))) {
2617
+ this._buttonToggled = coerceBooleanProperty(changes.toggled.currentValue);
2618
+ }
2619
+ }
2620
+ focus(origin = 'program', options) {
2621
+ this._focusMonitor.focusVia(this._getHostElement(), origin, options);
2622
+ }
2623
+ _getHostElement() {
2624
+ return this._elementRef.nativeElement;
2625
+ }
2626
+ }
2627
+ GraniteButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteButtonComponent, deps: [{ token: i1.FocusMonitor }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
2628
+ GraniteButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: GraniteButtonComponent, selector: "button[graniteButton],\n button[granitePrimaryButton],\n button[graniteFlatButton],\n button[graniteToolbarButton]\n ", inputs: { disabled: "disabled", toggled: "toggled" }, host: { properties: { "class.granite-button-disabled": "disabled", "class.granite-button-toggled": "_buttonToggled", "attr.disabled": "disabled || null" }, classAttribute: "granite-button-base" }, exportAs: ["graniteButton"], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host{box-sizing:border-box}:host *,:host *:before,:host *:after{box-sizing:inherit;cursor:pointer}button:host{background-color:inherit;-webkit-appearance:none;appearance:none;outline:none;border:none;font:inherit;border-radius:inherit;height:inherit;font-weight:inherit;line-height:inherit;color:inherit;margin:inherit;cursor:pointer;padding:inherit}a:host{outline:none}:host.granite-button-base{border-radius:.25rem;font-size:var(--granite-font-size-body-small);font-weight:var(--granite-font-weight-regular);padding:var(--granite-spacing-s) var(--granite-spacing-s);position:relative;line-height:var(--granite-font-size-body);display:flex;justify-content:center;align-items:center;width:-moz-fit-content;width:fit-content}:host:focus:not(.granite-button-disabled):not(:active){outline-offset:-2px;outline-width:.125rem;outline-color:var(--granite-color-focus);outline-style:solid}button:host.granite-button{background-color:var(--granite-color-background-variant);color:var(--granite-color-text);outline:.0625rem solid var(--granite-color-border-soft);outline-offset:-1px}button:host.granite-button:hover:not(.granite-button-disabled){background-color:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active);outline:none}button:host.granite-button:active:not(.granite-button-disabled){background-color:var(--granite-color-background-active-pressed);color:var(--granite-color-text-on-active);outline:none}button:host.granite-button.granite-button-toggled{background-color:none;color:none;outline:none}button:host.granite-primary-button{background-color:var(--granite-color-background-active);color:var(--granite-color-text-on-active);outline:none;outline-offset:-1px}button:host.granite-primary-button:hover:not(.granite-button-disabled){background-color:var(--granite-color-background-active-hover);color:none;outline:none}button:host.granite-primary-button:active:not(.granite-button-disabled){background-color:var(--granite-color-background-active-pressed);color:none;outline:none}button:host.granite-primary-button.granite-button-toggled{background-color:none;color:none;outline:none}button:host.granite-flat-button{background-color:transparent;color:var(--granite-color-text);outline:none;outline-offset:-1px}button:host.granite-flat-button:hover:not(.granite-button-disabled){background-color:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active);outline:none}button:host.granite-flat-button:active:not(.granite-button-disabled){background-color:var(--granite-color-background-active-pressed);color:var(--granite-color-text-on-active);outline:none}button:host.granite-flat-button.granite-button-toggled{background-color:var(--granite-color-background-selected);color:var(--granite-color-focus);outline:none}button:host.granite-toolbar-button{background-color:var(--granite-color-background);color:var(--granite-color-text);outline:.0625rem solid var(--granite-color-border-soft);outline-offset:-1px}button:host.granite-toolbar-button:hover:not(.granite-button-disabled){background-color:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active);outline:none}button:host.granite-toolbar-button:active:not(.granite-button-disabled){background-color:var(--granite-color-background-active-pressed);color:var(--granite-color-text-on-active);outline:none}button:host.granite-toolbar-button.granite-button-toggled{background-color:var(--granite-color-background-selected);color:var(--granite-color-focus);outline:none}button:host.granite-button-disabled,button:host.granite-button-disabled:active,button:host.granite-button-disabled:focus,button:host.granite-button-disabled:hover{opacity:.4;cursor:default}a:host.granite-button{background-color:var(--granite-color-background);color:var(--granite-color-text-link);outline:.0625rem solid var(--granite-color-border-soft);outline-offset:-1px}a:host.granite-button:hover:not(.granite-button-disabled){background-color:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active);outline:none}a:host.granite-button:active:not(.granite-button-disabled){background-color:var(--granite-color-background-active-pressed);color:var(--granite-color-text-on-active);outline:none}a:host.granite-button.granite-button-toggled{background-color:none;color:none;outline:none}a:host.granite-flat-button{background-color:transparent;color:var(--granite-color-text-link);outline:none;outline-offset:-1px}a:host.granite-flat-button:hover:not(.granite-button-disabled){background-color:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active);outline:none}a:host.granite-flat-button:active:not(.granite-button-disabled){background-color:var(--granite-color-background-active-pressed);color:var(--granite-color-text-on-active);outline:none}a:host.granite-flat-button.granite-button-toggled{background-color:none;color:none;outline:none}a:host.granite-button-disabled,a:host.granite-button-disabled:active,a:host.granite-button-disabled:focus,a:host.granite-button-disabled:hover{opacity:.4;text-decoration:none;cursor:default;pointer-events:none;-webkit-user-select:none;user-select:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2629
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteButtonComponent, decorators: [{
2630
+ type: Component,
2631
+ args: [{ selector: `button[graniteButton],
2632
+ button[granitePrimaryButton],
2633
+ button[graniteFlatButton],
2634
+ button[graniteToolbarButton]
2635
+ `, host: {
2636
+ class: 'granite-button-base',
2637
+ '[class.granite-button-disabled]': 'disabled',
2638
+ '[class.granite-button-toggled]': '_buttonToggled',
2639
+ '[attr.disabled]': 'disabled || null',
2640
+ }, exportAs: 'graniteButton', template: '<ng-content></ng-content>', inputs: ['disabled'], changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{box-sizing:border-box}:host *,:host *:before,:host *:after{box-sizing:inherit;cursor:pointer}button:host{background-color:inherit;-webkit-appearance:none;appearance:none;outline:none;border:none;font:inherit;border-radius:inherit;height:inherit;font-weight:inherit;line-height:inherit;color:inherit;margin:inherit;cursor:pointer;padding:inherit}a:host{outline:none}:host.granite-button-base{border-radius:.25rem;font-size:var(--granite-font-size-body-small);font-weight:var(--granite-font-weight-regular);padding:var(--granite-spacing-s) var(--granite-spacing-s);position:relative;line-height:var(--granite-font-size-body);display:flex;justify-content:center;align-items:center;width:-moz-fit-content;width:fit-content}:host:focus:not(.granite-button-disabled):not(:active){outline-offset:-2px;outline-width:.125rem;outline-color:var(--granite-color-focus);outline-style:solid}button:host.granite-button{background-color:var(--granite-color-background-variant);color:var(--granite-color-text);outline:.0625rem solid var(--granite-color-border-soft);outline-offset:-1px}button:host.granite-button:hover:not(.granite-button-disabled){background-color:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active);outline:none}button:host.granite-button:active:not(.granite-button-disabled){background-color:var(--granite-color-background-active-pressed);color:var(--granite-color-text-on-active);outline:none}button:host.granite-button.granite-button-toggled{background-color:none;color:none;outline:none}button:host.granite-primary-button{background-color:var(--granite-color-background-active);color:var(--granite-color-text-on-active);outline:none;outline-offset:-1px}button:host.granite-primary-button:hover:not(.granite-button-disabled){background-color:var(--granite-color-background-active-hover);color:none;outline:none}button:host.granite-primary-button:active:not(.granite-button-disabled){background-color:var(--granite-color-background-active-pressed);color:none;outline:none}button:host.granite-primary-button.granite-button-toggled{background-color:none;color:none;outline:none}button:host.granite-flat-button{background-color:transparent;color:var(--granite-color-text);outline:none;outline-offset:-1px}button:host.granite-flat-button:hover:not(.granite-button-disabled){background-color:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active);outline:none}button:host.granite-flat-button:active:not(.granite-button-disabled){background-color:var(--granite-color-background-active-pressed);color:var(--granite-color-text-on-active);outline:none}button:host.granite-flat-button.granite-button-toggled{background-color:var(--granite-color-background-selected);color:var(--granite-color-focus);outline:none}button:host.granite-toolbar-button{background-color:var(--granite-color-background);color:var(--granite-color-text);outline:.0625rem solid var(--granite-color-border-soft);outline-offset:-1px}button:host.granite-toolbar-button:hover:not(.granite-button-disabled){background-color:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active);outline:none}button:host.granite-toolbar-button:active:not(.granite-button-disabled){background-color:var(--granite-color-background-active-pressed);color:var(--granite-color-text-on-active);outline:none}button:host.granite-toolbar-button.granite-button-toggled{background-color:var(--granite-color-background-selected);color:var(--granite-color-focus);outline:none}button:host.granite-button-disabled,button:host.granite-button-disabled:active,button:host.granite-button-disabled:focus,button:host.granite-button-disabled:hover{opacity:.4;cursor:default}a:host.granite-button{background-color:var(--granite-color-background);color:var(--granite-color-text-link);outline:.0625rem solid var(--granite-color-border-soft);outline-offset:-1px}a:host.granite-button:hover:not(.granite-button-disabled){background-color:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active);outline:none}a:host.granite-button:active:not(.granite-button-disabled){background-color:var(--granite-color-background-active-pressed);color:var(--granite-color-text-on-active);outline:none}a:host.granite-button.granite-button-toggled{background-color:none;color:none;outline:none}a:host.granite-flat-button{background-color:transparent;color:var(--granite-color-text-link);outline:none;outline-offset:-1px}a:host.granite-flat-button:hover:not(.granite-button-disabled){background-color:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active);outline:none}a:host.granite-flat-button:active:not(.granite-button-disabled){background-color:var(--granite-color-background-active-pressed);color:var(--granite-color-text-on-active);outline:none}a:host.granite-flat-button.granite-button-toggled{background-color:none;color:none;outline:none}a:host.granite-button-disabled,a:host.granite-button-disabled:active,a:host.granite-button-disabled:focus,a:host.granite-button-disabled:hover{opacity:.4;text-decoration:none;cursor:default;pointer-events:none;-webkit-user-select:none;user-select:none}\n"] }]
2641
+ }], ctorParameters: function () { return [{ type: i1.FocusMonitor }, { type: i0.ElementRef }]; }, propDecorators: { toggled: [{
2642
+ type: Input
2643
+ }] } });
2644
+ class GraniteAnchorComponent extends GraniteButtonComponent {
2645
+ constructor(_focusMonitor, _elementRef) {
2646
+ super(_focusMonitor, _elementRef);
2647
+ this._focusMonitor = _focusMonitor;
2648
+ this._elementRef = _elementRef;
2649
+ }
2650
+ _anchorClick(event) {
2651
+ if (this.disabled) {
2652
+ event.preventDefault();
2653
+ }
2654
+ }
2655
+ ngOnChanges(changes) {
2656
+ super.ngOnChanges(changes);
2657
+ }
2658
+ }
2659
+ GraniteAnchorComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteAnchorComponent, deps: [{ token: i1.FocusMonitor }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
2660
+ GraniteAnchorComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: GraniteAnchorComponent, selector: "a[graniteButton],\n a[graniteFlatButton]", inputs: { disabled: "disabled" }, host: { listeners: { "click": "_anchorClick($event)" }, properties: { "attr.tabindex": "disabled ? -1 : 0", "class.granite-button-disabled": "disabled" }, classAttribute: "granite-button-base" }, exportAs: ["graniteAnchor"], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host{box-sizing:border-box}:host *,:host *:before,:host *:after{box-sizing:inherit;cursor:pointer}button:host{background-color:inherit;-webkit-appearance:none;appearance:none;outline:none;border:none;font:inherit;border-radius:inherit;height:inherit;font-weight:inherit;line-height:inherit;color:inherit;margin:inherit;cursor:pointer;padding:inherit}a:host{outline:none}:host.granite-button-base{border-radius:.25rem;font-size:var(--granite-font-size-body-small);font-weight:var(--granite-font-weight-regular);padding:var(--granite-spacing-s) var(--granite-spacing-s);position:relative;line-height:var(--granite-font-size-body);display:flex;justify-content:center;align-items:center;width:-moz-fit-content;width:fit-content}:host:focus:not(.granite-button-disabled):not(:active){outline-offset:-2px;outline-width:.125rem;outline-color:var(--granite-color-focus);outline-style:solid}button:host.granite-button{background-color:var(--granite-color-background-variant);color:var(--granite-color-text);outline:.0625rem solid var(--granite-color-border-soft);outline-offset:-1px}button:host.granite-button:hover:not(.granite-button-disabled){background-color:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active);outline:none}button:host.granite-button:active:not(.granite-button-disabled){background-color:var(--granite-color-background-active-pressed);color:var(--granite-color-text-on-active);outline:none}button:host.granite-button.granite-button-toggled{background-color:none;color:none;outline:none}button:host.granite-primary-button{background-color:var(--granite-color-background-active);color:var(--granite-color-text-on-active);outline:none;outline-offset:-1px}button:host.granite-primary-button:hover:not(.granite-button-disabled){background-color:var(--granite-color-background-active-hover);color:none;outline:none}button:host.granite-primary-button:active:not(.granite-button-disabled){background-color:var(--granite-color-background-active-pressed);color:none;outline:none}button:host.granite-primary-button.granite-button-toggled{background-color:none;color:none;outline:none}button:host.granite-flat-button{background-color:transparent;color:var(--granite-color-text);outline:none;outline-offset:-1px}button:host.granite-flat-button:hover:not(.granite-button-disabled){background-color:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active);outline:none}button:host.granite-flat-button:active:not(.granite-button-disabled){background-color:var(--granite-color-background-active-pressed);color:var(--granite-color-text-on-active);outline:none}button:host.granite-flat-button.granite-button-toggled{background-color:var(--granite-color-background-selected);color:var(--granite-color-focus);outline:none}button:host.granite-toolbar-button{background-color:var(--granite-color-background);color:var(--granite-color-text);outline:.0625rem solid var(--granite-color-border-soft);outline-offset:-1px}button:host.granite-toolbar-button:hover:not(.granite-button-disabled){background-color:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active);outline:none}button:host.granite-toolbar-button:active:not(.granite-button-disabled){background-color:var(--granite-color-background-active-pressed);color:var(--granite-color-text-on-active);outline:none}button:host.granite-toolbar-button.granite-button-toggled{background-color:var(--granite-color-background-selected);color:var(--granite-color-focus);outline:none}button:host.granite-button-disabled,button:host.granite-button-disabled:active,button:host.granite-button-disabled:focus,button:host.granite-button-disabled:hover{opacity:.4;cursor:default}a:host.granite-button{background-color:var(--granite-color-background);color:var(--granite-color-text-link);outline:.0625rem solid var(--granite-color-border-soft);outline-offset:-1px}a:host.granite-button:hover:not(.granite-button-disabled){background-color:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active);outline:none}a:host.granite-button:active:not(.granite-button-disabled){background-color:var(--granite-color-background-active-pressed);color:var(--granite-color-text-on-active);outline:none}a:host.granite-button.granite-button-toggled{background-color:none;color:none;outline:none}a:host.granite-flat-button{background-color:transparent;color:var(--granite-color-text-link);outline:none;outline-offset:-1px}a:host.granite-flat-button:hover:not(.granite-button-disabled){background-color:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active);outline:none}a:host.granite-flat-button:active:not(.granite-button-disabled){background-color:var(--granite-color-background-active-pressed);color:var(--granite-color-text-on-active);outline:none}a:host.granite-flat-button.granite-button-toggled{background-color:none;color:none;outline:none}a:host.granite-button-disabled,a:host.granite-button-disabled:active,a:host.granite-button-disabled:focus,a:host.granite-button-disabled:hover{opacity:.4;text-decoration:none;cursor:default;pointer-events:none;-webkit-user-select:none;user-select:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2661
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteAnchorComponent, decorators: [{
2662
+ type: Component,
2663
+ args: [{ selector: `a[graniteButton],
2664
+ a[graniteFlatButton]`, host: {
2665
+ class: 'granite-button-base',
2666
+ '[attr.tabindex]': 'disabled ? -1 : 0',
2667
+ '[class.granite-button-disabled]': 'disabled',
2668
+ }, exportAs: 'graniteAnchor', template: '<ng-content></ng-content>', inputs: ['disabled'], changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{box-sizing:border-box}:host *,:host *:before,:host *:after{box-sizing:inherit;cursor:pointer}button:host{background-color:inherit;-webkit-appearance:none;appearance:none;outline:none;border:none;font:inherit;border-radius:inherit;height:inherit;font-weight:inherit;line-height:inherit;color:inherit;margin:inherit;cursor:pointer;padding:inherit}a:host{outline:none}:host.granite-button-base{border-radius:.25rem;font-size:var(--granite-font-size-body-small);font-weight:var(--granite-font-weight-regular);padding:var(--granite-spacing-s) var(--granite-spacing-s);position:relative;line-height:var(--granite-font-size-body);display:flex;justify-content:center;align-items:center;width:-moz-fit-content;width:fit-content}:host:focus:not(.granite-button-disabled):not(:active){outline-offset:-2px;outline-width:.125rem;outline-color:var(--granite-color-focus);outline-style:solid}button:host.granite-button{background-color:var(--granite-color-background-variant);color:var(--granite-color-text);outline:.0625rem solid var(--granite-color-border-soft);outline-offset:-1px}button:host.granite-button:hover:not(.granite-button-disabled){background-color:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active);outline:none}button:host.granite-button:active:not(.granite-button-disabled){background-color:var(--granite-color-background-active-pressed);color:var(--granite-color-text-on-active);outline:none}button:host.granite-button.granite-button-toggled{background-color:none;color:none;outline:none}button:host.granite-primary-button{background-color:var(--granite-color-background-active);color:var(--granite-color-text-on-active);outline:none;outline-offset:-1px}button:host.granite-primary-button:hover:not(.granite-button-disabled){background-color:var(--granite-color-background-active-hover);color:none;outline:none}button:host.granite-primary-button:active:not(.granite-button-disabled){background-color:var(--granite-color-background-active-pressed);color:none;outline:none}button:host.granite-primary-button.granite-button-toggled{background-color:none;color:none;outline:none}button:host.granite-flat-button{background-color:transparent;color:var(--granite-color-text);outline:none;outline-offset:-1px}button:host.granite-flat-button:hover:not(.granite-button-disabled){background-color:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active);outline:none}button:host.granite-flat-button:active:not(.granite-button-disabled){background-color:var(--granite-color-background-active-pressed);color:var(--granite-color-text-on-active);outline:none}button:host.granite-flat-button.granite-button-toggled{background-color:var(--granite-color-background-selected);color:var(--granite-color-focus);outline:none}button:host.granite-toolbar-button{background-color:var(--granite-color-background);color:var(--granite-color-text);outline:.0625rem solid var(--granite-color-border-soft);outline-offset:-1px}button:host.granite-toolbar-button:hover:not(.granite-button-disabled){background-color:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active);outline:none}button:host.granite-toolbar-button:active:not(.granite-button-disabled){background-color:var(--granite-color-background-active-pressed);color:var(--granite-color-text-on-active);outline:none}button:host.granite-toolbar-button.granite-button-toggled{background-color:var(--granite-color-background-selected);color:var(--granite-color-focus);outline:none}button:host.granite-button-disabled,button:host.granite-button-disabled:active,button:host.granite-button-disabled:focus,button:host.granite-button-disabled:hover{opacity:.4;cursor:default}a:host.granite-button{background-color:var(--granite-color-background);color:var(--granite-color-text-link);outline:.0625rem solid var(--granite-color-border-soft);outline-offset:-1px}a:host.granite-button:hover:not(.granite-button-disabled){background-color:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active);outline:none}a:host.granite-button:active:not(.granite-button-disabled){background-color:var(--granite-color-background-active-pressed);color:var(--granite-color-text-on-active);outline:none}a:host.granite-button.granite-button-toggled{background-color:none;color:none;outline:none}a:host.granite-flat-button{background-color:transparent;color:var(--granite-color-text-link);outline:none;outline-offset:-1px}a:host.granite-flat-button:hover:not(.granite-button-disabled){background-color:var(--granite-color-background-active-hover);color:var(--granite-color-text-on-active);outline:none}a:host.granite-flat-button:active:not(.granite-button-disabled){background-color:var(--granite-color-background-active-pressed);color:var(--granite-color-text-on-active);outline:none}a:host.granite-flat-button.granite-button-toggled{background-color:none;color:none;outline:none}a:host.granite-button-disabled,a:host.granite-button-disabled:active,a:host.granite-button-disabled:focus,a:host.granite-button-disabled:hover{opacity:.4;text-decoration:none;cursor:default;pointer-events:none;-webkit-user-select:none;user-select:none}\n"] }]
2669
+ }], ctorParameters: function () { return [{ type: i1.FocusMonitor }, { type: i0.ElementRef }]; }, propDecorators: { _anchorClick: [{
2670
+ type: HostListener,
2671
+ args: ['click', ['$event']]
2672
+ }] } });
2673
+
2674
+ class GraniteButtonModule {
2675
+ }
2676
+ GraniteButtonModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteButtonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2677
+ GraniteButtonModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteButtonModule, declarations: [GraniteButtonComponent, GraniteAnchorComponent], exports: [GraniteButtonComponent, GraniteAnchorComponent] });
2678
+ GraniteButtonModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteButtonModule });
2679
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteButtonModule, decorators: [{
2680
+ type: NgModule,
2681
+ args: [{
2682
+ declarations: [GraniteButtonComponent, GraniteAnchorComponent],
2683
+ exports: [GraniteButtonComponent, GraniteAnchorComponent],
2684
+ }]
2685
+ }] });
2686
+
2687
+ class GraniteTableColumnDirective {
2688
+ }
2689
+ GraniteTableColumnDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteTableColumnDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2690
+ GraniteTableColumnDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.11", type: GraniteTableColumnDirective, selector: "granite-table-column", inputs: { name: "name", title: "title", staticType: "staticType" }, queries: [{ propertyName: "tableCellTemplateRef", first: true, predicate: ["graniteTableCellTemplate"], descendants: true }], ngImport: i0 });
2691
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteTableColumnDirective, decorators: [{
2692
+ type: Directive,
2693
+ args: [{
2694
+ // eslint-disable-next-line @angular-eslint/directive-selector
2695
+ selector: 'granite-table-column',
2696
+ }]
2697
+ }], propDecorators: { name: [{
2698
+ type: Input
2699
+ }], title: [{
2700
+ type: Input
2701
+ }], staticType: [{
2702
+ type: Input
2703
+ }], tableCellTemplateRef: [{
2704
+ type: ContentChild,
2705
+ args: ['graniteTableCellTemplate', { static: false }]
2706
+ }] } });
2707
+
2708
+ class TableConstants {
2709
+ }
2710
+ TableConstants.CELL_ID_PREFIX = 'granite-cell';
2711
+
2712
+ class GraniteCell {
2713
+ }
2714
+ GraniteCell.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteCell, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2715
+ GraniteCell.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.11", type: GraniteCell, inputs: { id: "id", column: "column" }, ngImport: i0 });
2716
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteCell, decorators: [{
2717
+ type: Directive
2718
+ }], propDecorators: { id: [{
2719
+ type: Input
2720
+ }], column: [{
2721
+ type: Input
2722
+ }] } });
2723
+
2724
+ class GraniteTableHeaderCellComponent extends GraniteCell {
2725
+ }
2726
+ GraniteTableHeaderCellComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteTableHeaderCellComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
2727
+ GraniteTableHeaderCellComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: GraniteTableHeaderCellComponent, selector: "cdk-header-cell[graniteTableHeaderCell]", usesInheritance: true, ngImport: i0, template: "<span class=\"granite-table-header-cell-title\">\n <ng-content></ng-content>\n</span>\n", styles: [":host{box-sizing:border-box}:host *,:host *:before,:host *:after{box-sizing:inherit}.granite-table-header-cell-title{padding:var(--granite-spacing-s);height:inherit;font-size:var(--granite-font-size-micro);line-height:var(--granite-line-height-flowing);letter-spacing:.015em;font-weight:400;display:flex;justify-content:center;align-items:center;color:var(--granite-color-text-weak)}\n"] });
2728
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteTableHeaderCellComponent, decorators: [{
2729
+ type: Component,
2730
+ args: [{ selector: 'cdk-header-cell[graniteTableHeaderCell]', template: "<span class=\"granite-table-header-cell-title\">\n <ng-content></ng-content>\n</span>\n", styles: [":host{box-sizing:border-box}:host *,:host *:before,:host *:after{box-sizing:inherit}.granite-table-header-cell-title{padding:var(--granite-spacing-s);height:inherit;font-size:var(--granite-font-size-micro);line-height:var(--granite-line-height-flowing);letter-spacing:.015em;font-weight:400;display:flex;justify-content:center;align-items:center;color:var(--granite-color-text-weak)}\n"] }]
2731
+ }] });
2732
+
2733
+ class GraniteTableDataCellComponent extends GraniteCell {
2734
+ }
2735
+ GraniteTableDataCellComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteTableDataCellComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
2736
+ GraniteTableDataCellComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: GraniteTableDataCellComponent, selector: "cdk-cell[graniteTableDataCell]", inputs: { value: "value", staticType: "staticType", rowIndex: "rowIndex", columnIndex: "columnIndex", tableCellTemplateRef: "tableCellTemplateRef", row: "row" }, usesInheritance: true, ngImport: i0, template: "<span class=\"granite-table-data-cell-static-container\">\n <ng-template\n [ngTemplateOutlet]=\"tableCellTemplateRef || defaultTableCellTemplate\"\n [ngTemplateOutletContext]=\"{\n data: value,\n rowIndex: rowIndex,\n columnIndex: columnIndex,\n column: column,\n row: row\n }\"\n ></ng-template>\n</span>\n\n<ng-template #defaultTableCellTemplate>\n <ng-container [ngSwitch]=\"staticType\">\n <ng-container *ngSwitchCase=\"'badge'\">\n <granite-badge>{{ value }}</granite-badge>\n </ng-container>\n <ng-container *ngSwitchDefault>{{ value }}</ng-container>\n </ng-container>\n</ng-template>\n", styles: [":host{box-sizing:border-box}:host *,:host *:before,:host *:after{box-sizing:inherit}.granite-table-data-cell-static-container{padding:var(--granite-spacing-s);height:inherit;font-size:var(--granite-font-size-body-small);line-height:var(--granite-line-height-regular);display:flex;justify-content:center;align-items:center;color:var(--granite-color-text)}\n"], components: [{ type: GraniteBadgeComponent, selector: "granite-badge", inputs: ["backgroundColor", "color", "pill"], exportAs: ["graniteBadge"] }], directives: [{ type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i2.NgSwitchDefault, selector: "[ngSwitchDefault]" }] });
2737
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteTableDataCellComponent, decorators: [{
2738
+ type: Component,
2739
+ args: [{ selector: 'cdk-cell[graniteTableDataCell]', template: "<span class=\"granite-table-data-cell-static-container\">\n <ng-template\n [ngTemplateOutlet]=\"tableCellTemplateRef || defaultTableCellTemplate\"\n [ngTemplateOutletContext]=\"{\n data: value,\n rowIndex: rowIndex,\n columnIndex: columnIndex,\n column: column,\n row: row\n }\"\n ></ng-template>\n</span>\n\n<ng-template #defaultTableCellTemplate>\n <ng-container [ngSwitch]=\"staticType\">\n <ng-container *ngSwitchCase=\"'badge'\">\n <granite-badge>{{ value }}</granite-badge>\n </ng-container>\n <ng-container *ngSwitchDefault>{{ value }}</ng-container>\n </ng-container>\n</ng-template>\n", styles: [":host{box-sizing:border-box}:host *,:host *:before,:host *:after{box-sizing:inherit}.granite-table-data-cell-static-container{padding:var(--granite-spacing-s);height:inherit;font-size:var(--granite-font-size-body-small);line-height:var(--granite-line-height-regular);display:flex;justify-content:center;align-items:center;color:var(--granite-color-text)}\n"] }]
2740
+ }], propDecorators: { value: [{
2741
+ type: Input
2742
+ }], staticType: [{
2743
+ type: Input
2744
+ }], rowIndex: [{
2745
+ type: Input
2746
+ }], columnIndex: [{
2747
+ type: Input
2748
+ }], tableCellTemplateRef: [{
2749
+ type: Input
2750
+ }], row: [{
2751
+ type: Input
2752
+ }] } });
2753
+
2754
+ class GraniteTitlePipe {
2755
+ transform(value) {
2756
+ const words = value.split(/(?=[A-Z ])/);
2757
+ return words
2758
+ .map((word) => word.trim())
2759
+ .filter(Boolean)
2760
+ .map((word) => word.charAt(0).toLocaleUpperCase() + word.slice(1))
2761
+ .join(' ');
2762
+ }
2763
+ }
2764
+ GraniteTitlePipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteTitlePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
2765
+ GraniteTitlePipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteTitlePipe, name: "graniteTitle" });
2766
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteTitlePipe, decorators: [{
2767
+ type: Pipe,
2768
+ args: [{
2769
+ name: 'graniteTitle',
2770
+ }]
2771
+ }] });
2772
+
2773
+ class GraniteTableComponent {
2774
+ constructor() {
2775
+ this.ariaLabel = null;
2776
+ this.cellIdPrefix = TableConstants.CELL_ID_PREFIX;
2777
+ }
2778
+ ngAfterContentInit() {
2779
+ this.columns = this.tableColumnsComponent.toArray();
2780
+ this.renderedColumns = this.columns.map((column) => column.name);
2781
+ }
2782
+ }
2783
+ GraniteTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2784
+ GraniteTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: GraniteTableComponent, selector: "granite-table", inputs: { dataSource: "dataSource", trackBy: "trackBy", ariaLabel: ["aria-label", "ariaLabel"] }, queries: [{ propertyName: "tableColumnsComponent", predicate: GraniteTableColumnDirective }], ngImport: i0, template: "<cdk-table\n [dataSource]=\"dataSource\"\n multiTemplateDataRows\n [trackBy]=\"trackBy\"\n [attr.aria-label]=\"ariaLabel\"\n>\n <ng-container\n *ngFor=\"let column of columns; index as columnI\"\n [cdkColumnDef]=\"column.name\"\n >\n <!-- Cell Header -->\n <cdk-header-cell *cdkHeaderCellDef graniteTableHeaderCell>\n {{ (column.title ? column.title : column.name) | graniteTitle }}\n </cdk-header-cell>\n\n <!-- Cell Data -->\n <cdk-cell\n graniteTableDataCell\n *cdkCellDef=\"let row; let rowI = dataIndex\"\n [id]=\"cellIdPrefix + '-' + rowI + '-' + columnI\"\n [value]=\"row[column.name]\"\n [rowIndex]=\"rowI\"\n [columnIndex]=\"columnI\"\n [staticType]=\"column.staticType\"\n [column]=\"column\"\n [tableCellTemplateRef]=\"column.tableCellTemplateRef\"\n [row]=\"row\"\n ></cdk-cell>\n </ng-container>\n\n <cdk-header-row *cdkHeaderRowDef=\"renderedColumns\"></cdk-header-row>\n <cdk-row\n *cdkRowDef=\"let row; let rowI = dataIndex; columns: renderedColumns\"\n [attr.aria-rowindex]=\"rowI + 1\"\n ></cdk-row>\n</cdk-table>\n", styles: [":host{box-sizing:border-box}:host *,:host *:before,:host *:after{box-sizing:inherit}cdk-table{display:flex;flex-direction:column;background-color:var(--granite-color-background-variant)}cdk-header-row,cdk-row{display:flex}cdk-header-cell,cdk-cell{flex:1}cdk-header-cell,cdk-cell{height:2.5rem}cdk-cell{border-top:1px solid var(--granite-color-border-soft)}\n"], components: [{ type: i1$2.CdkTable, selector: "cdk-table, table[cdk-table]", inputs: ["trackBy", "dataSource", "multiTemplateDataRows", "fixedLayout"], outputs: ["contentChanged"], exportAs: ["cdkTable"] }, { type: GraniteTableHeaderCellComponent, selector: "cdk-header-cell[graniteTableHeaderCell]" }, { type: GraniteTableDataCellComponent, selector: "cdk-cell[graniteTableDataCell]", inputs: ["value", "staticType", "rowIndex", "columnIndex", "tableCellTemplateRef", "row"] }, { type: i1$2.CdkHeaderRow, selector: "cdk-header-row, tr[cdk-header-row]" }, { type: i1$2.CdkRow, selector: "cdk-row, tr[cdk-row]" }], directives: [{ type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i1$2.CdkColumnDef, selector: "[cdkColumnDef]", inputs: ["sticky", "cdkColumnDef", "stickyEnd"] }, { type: i1$2.CdkHeaderCellDef, selector: "[cdkHeaderCellDef]" }, { type: i1$2.CdkHeaderCell, selector: "cdk-header-cell, th[cdk-header-cell]" }, { type: i1$2.CdkCellDef, selector: "[cdkCellDef]" }, { type: i1$2.CdkCell, selector: "cdk-cell, td[cdk-cell]" }, { type: i1$2.CdkHeaderRowDef, selector: "[cdkHeaderRowDef]", inputs: ["cdkHeaderRowDef", "cdkHeaderRowDefSticky"] }, { type: i1$2.CdkRowDef, selector: "[cdkRowDef]", inputs: ["cdkRowDefColumns", "cdkRowDefWhen"] }], pipes: { "graniteTitle": GraniteTitlePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush });
2785
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteTableComponent, decorators: [{
2786
+ type: Component,
2787
+ args: [{ selector: 'granite-table', changeDetection: ChangeDetectionStrategy.OnPush, template: "<cdk-table\n [dataSource]=\"dataSource\"\n multiTemplateDataRows\n [trackBy]=\"trackBy\"\n [attr.aria-label]=\"ariaLabel\"\n>\n <ng-container\n *ngFor=\"let column of columns; index as columnI\"\n [cdkColumnDef]=\"column.name\"\n >\n <!-- Cell Header -->\n <cdk-header-cell *cdkHeaderCellDef graniteTableHeaderCell>\n {{ (column.title ? column.title : column.name) | graniteTitle }}\n </cdk-header-cell>\n\n <!-- Cell Data -->\n <cdk-cell\n graniteTableDataCell\n *cdkCellDef=\"let row; let rowI = dataIndex\"\n [id]=\"cellIdPrefix + '-' + rowI + '-' + columnI\"\n [value]=\"row[column.name]\"\n [rowIndex]=\"rowI\"\n [columnIndex]=\"columnI\"\n [staticType]=\"column.staticType\"\n [column]=\"column\"\n [tableCellTemplateRef]=\"column.tableCellTemplateRef\"\n [row]=\"row\"\n ></cdk-cell>\n </ng-container>\n\n <cdk-header-row *cdkHeaderRowDef=\"renderedColumns\"></cdk-header-row>\n <cdk-row\n *cdkRowDef=\"let row; let rowI = dataIndex; columns: renderedColumns\"\n [attr.aria-rowindex]=\"rowI + 1\"\n ></cdk-row>\n</cdk-table>\n", styles: [":host{box-sizing:border-box}:host *,:host *:before,:host *:after{box-sizing:inherit}cdk-table{display:flex;flex-direction:column;background-color:var(--granite-color-background-variant)}cdk-header-row,cdk-row{display:flex}cdk-header-cell,cdk-cell{flex:1}cdk-header-cell,cdk-cell{height:2.5rem}cdk-cell{border-top:1px solid var(--granite-color-border-soft)}\n"] }]
2788
+ }], propDecorators: { dataSource: [{
2789
+ type: Input
2790
+ }], trackBy: [{
2791
+ type: Input
2792
+ }], ariaLabel: [{
2793
+ type: Input,
2794
+ args: ['aria-label']
2795
+ }], tableColumnsComponent: [{
2796
+ type: ContentChildren,
2797
+ args: [GraniteTableColumnDirective]
2798
+ }] } });
2799
+
2800
+ class PurePipesModule {
2801
+ }
2802
+ PurePipesModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PurePipesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2803
+ PurePipesModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PurePipesModule, declarations: [GraniteTitlePipe], exports: [GraniteTitlePipe] });
2804
+ PurePipesModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PurePipesModule });
2805
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: PurePipesModule, decorators: [{
2806
+ type: NgModule,
2807
+ args: [{
2808
+ exports: [GraniteTitlePipe],
2809
+ declarations: [GraniteTitlePipe],
2810
+ }]
2811
+ }] });
2812
+
2813
+ class GraniteTableModule {
2814
+ }
2815
+ GraniteTableModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteTableModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2816
+ GraniteTableModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteTableModule, declarations: [GraniteTableComponent,
2817
+ GraniteTableDataCellComponent,
2818
+ GraniteTableHeaderCellComponent,
2819
+ GraniteTableColumnDirective], imports: [CommonModule, CdkTableModule, GraniteBadgeModule, PurePipesModule], exports: [GraniteTableComponent, GraniteTableColumnDirective] });
2820
+ GraniteTableModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteTableModule, imports: [[CommonModule, CdkTableModule, GraniteBadgeModule, PurePipesModule]] });
2821
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteTableModule, decorators: [{
2822
+ type: NgModule,
2823
+ args: [{
2824
+ declarations: [
2825
+ GraniteTableComponent,
2826
+ GraniteTableDataCellComponent,
2827
+ GraniteTableHeaderCellComponent,
2828
+ GraniteTableColumnDirective,
2829
+ ],
2830
+ imports: [CommonModule, CdkTableModule, GraniteBadgeModule, PurePipesModule],
2831
+ exports: [GraniteTableComponent, GraniteTableColumnDirective],
2832
+ }]
2833
+ }] });
2834
+
2835
+ const GRANITE_INPUT_INCLUDES = ['text', 'number', 'password', 'textarea'];
2836
+ class GraniteInputFieldComponent {
2837
+ constructor(_focusMonitor) {
2838
+ this._focusMonitor = _focusMonitor;
2839
+ this.id = null;
2840
+ this.name = null;
2841
+ this.type = 'text';
2842
+ this.value = '';
2843
+ this.required = false;
2844
+ this.readonly = false;
2845
+ this.invalid = false;
2846
+ this.disabled = false;
2847
+ this.placeholder = '';
2848
+ this.maxlength = 255;
2849
+ this.countcharacters = false;
2850
+ this.ariaLabel = null;
2851
+ this.ariaLabelledby = null;
2852
+ this.valueChange = new EventEmitter();
2853
+ this._supported = true;
2854
+ this._empty = false;
2855
+ this._passwordFieldIcon = 'view';
2856
+ this._passwordField = false;
2857
+ this._currentCharCount = 0;
2858
+ this._passwordToggled = false;
2859
+ }
2860
+ ngOnInit() {
2861
+ this._validateType();
2862
+ this._passwordField = this.type == 'password';
2863
+ this._empty = this.value == null || this.value === '';
2864
+ }
2865
+ ngOnChanges(changes) {
2866
+ if (changes.required) {
2867
+ this.required = coerceBooleanProperty(changes.required.currentValue);
2868
+ }
2869
+ if (changes.readonly) {
2870
+ this.readonly = coerceBooleanProperty(changes.readonly.currentValue);
2871
+ }
2872
+ if (changes.invalid) {
2873
+ this.invalid = coerceBooleanProperty(changes.invalid.currentValue);
2874
+ }
2875
+ if (changes.disabled) {
2876
+ this.disabled = coerceBooleanProperty(changes.disabled.currentValue);
2877
+ }
2878
+ if (changes.countcharacters) {
2879
+ this.countcharacters = coerceBooleanProperty(changes.countcharacters.currentValue);
2880
+ }
2881
+ if (changes.value) {
2882
+ this._empty = this.value == null || this.value === '';
2883
+ }
2884
+ if (changes.type) {
2885
+ this._validateType();
2886
+ }
2887
+ }
2888
+ focus(origin = 'program', options) {
2889
+ if (this.type === 'text') {
2890
+ this._focusMonitor.focusVia(this._getInputElement(), origin, options);
2891
+ }
2892
+ else if (this.type === 'textarea') {
2893
+ this._focusMonitor.focusVia(this._getTextareaElement(), origin, options);
2894
+ }
2895
+ }
2896
+ _togglePassword() {
2897
+ if (this._passwordToggled) {
2898
+ this._passwordToggled = false;
2899
+ this.type = 'password';
2900
+ this._passwordFieldIcon = 'view';
2901
+ }
2902
+ else {
2903
+ this._passwordToggled = true;
2904
+ this.type = 'text';
2905
+ this._passwordFieldIcon = 'view-disabled';
2906
+ }
2907
+ }
2908
+ _onKeyUp(event) {
2909
+ const inputEvent = event.target;
2910
+ this._applyCharacterCount(inputEvent.value);
2911
+ this._empty = inputEvent.value == null || inputEvent.value === '';
2912
+ this.valueChange.emit(inputEvent.value);
2913
+ }
2914
+ _onInput(event) {
2915
+ const inputEvent = event.target;
2916
+ this._empty = inputEvent.value == null || inputEvent.value === '';
2917
+ this.valueChange.emit(inputEvent.value);
2918
+ }
2919
+ _validateType() {
2920
+ if (GRANITE_INPUT_INCLUDES.indexOf(this.type) < 0) {
2921
+ this._supported = false;
2922
+ throw Error(`Input type "${this.type}" isn't supported by graniteInputField.`);
2923
+ }
2924
+ }
2925
+ _applyCharacterCount(inputString) {
2926
+ if (this.countcharacters) {
2927
+ this._currentCharCount = inputString.length;
2928
+ if (this._currentCharCount > this.maxlength) {
2929
+ inputString = inputString.slice(0, this.maxlength);
2930
+ this._currentCharCount = this.maxlength;
2931
+ }
2932
+ }
2933
+ }
2934
+ _getInputElement() {
2935
+ return this._inputElement.nativeElement;
2936
+ }
2937
+ _getTextareaElement() {
2938
+ return this._textareaElement.nativeElement;
2939
+ }
2940
+ }
2941
+ GraniteInputFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteInputFieldComponent, deps: [{ token: i1.FocusMonitor }], target: i0.ɵɵFactoryTarget.Component });
2942
+ GraniteInputFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: GraniteInputFieldComponent, selector: "granite-input-field", inputs: { id: "id", name: "name", type: "type", value: "value", required: "required", readonly: "readonly", invalid: "invalid", disabled: "disabled", placeholder: "placeholder", prefixicon: "prefixicon", maxlength: "maxlength", countcharacters: "countcharacters", ariaLabel: ["aria-label", "ariaLabel"], ariaLabelledby: ["aria-labelledby", "ariaLabelledby"] }, outputs: { valueChange: "valueChange" }, host: { classAttribute: "granite-input-field" }, viewQueries: [{ propertyName: "_inputElement", first: true, predicate: ["input"], descendants: true }, { propertyName: "_textareaElement", first: true, predicate: ["textarea"], descendants: true }], exportAs: ["graniteInputField"], usesOnChanges: true, ngImport: i0, template: "<div\n *ngIf=\"_supported\"\n class=\"granite-input-container\"\n [class.granite-input-disabled]=\"disabled\"\n [class.granite-input-readonly]=\"readonly\"\n [class.granite-input-disabled]=\"disabled\"\n [class.granite-input-readonly]=\"readonly\"\n>\n <div\n class=\"granite-input-top-row\"\n [class.granite-input-required]=\"required\"\n [class.granite-input-empty]=\"_empty\"\n [class.granite-input-disabled]=\"disabled\"\n [class.granite-input-readonly]=\"readonly\"\n >\n <div\n *ngIf=\"prefixicon\"\n class=\"granite-input-prepend\"\n [class.granite-input-required]=\"required\"\n [class.granite-input-empty]=\"_empty\"\n >\n <granite-icon class=\"granite-input-prepend-icon\">\n {{ prefixicon }}\n </granite-icon>\n </div>\n\n <ng-container\n *ngIf=\"type !== 'textarea'; then inputElement; else textareaElement\"\n ></ng-container>\n\n <ng-template #inputElement>\n <input\n #input\n [id]=\"id\"\n class=\"granite-input-base\"\n [class.granite-input-invalid]=\"invalid\"\n [class.granite-input-empty]=\"_empty\"\n [name]=\"name\"\n [attr.type]=\"type\"\n [required]=\"required\"\n [readonly]=\"readonly\"\n [disabled]=\"disabled\"\n [placeholder]=\"placeholder\"\n [attr.maxlength]=\"maxlength\"\n [value]=\"value\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-labelledby]=\"ariaLabelledby\"\n [attr.aria-invalid]=\"invalid\"\n (keyup)=\"_onKeyUp($event)\"\n (input)=\"_onInput($event)\"\n />\n </ng-template>\n\n <button\n *ngIf=\"_passwordField\"\n class=\"granite-input-append\"\n [class.granite-input-required]=\"required\"\n [class.granite-input-empty]=\"_empty\"\n (click)=\"_togglePassword()\"\n >\n <granite-icon class=\"granite-input-password-toggle-icon\">\n {{ _passwordFieldIcon }}\n </granite-icon>\n </button>\n\n <ng-template #textareaElement>\n <textarea\n #textarea\n [id]=\"id\"\n class=\"granite-input-base granite-text-area\"\n [class.granite-input-invalid]=\"invalid\"\n [class.granite-input-empty]=\"_empty\"\n rows=\"1\"\n [name]=\"name\"\n [attr.type]=\"type\"\n [required]=\"required\"\n [readonly]=\"readonly\"\n [disabled]=\"disabled\"\n [placeholder]=\"placeholder\"\n [value]=\"value\"\n [attr.maxlength]=\"maxlength\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-labelledby]=\"ariaLabelledby\"\n [attr.aria-required]=\"required\"\n [attr.aria-invalid]=\"invalid\"\n (keyup)=\"_onKeyUp($event)\"\n (input)=\"_onInput($event)\"\n ></textarea>\n </ng-template>\n\n <div\n class=\"granite-input-hover-bar\"\n [class.granite-input-invalid]=\"invalid\"\n [class.granite-input-empty]=\"_empty\"\n ></div>\n </div>\n\n <div *ngIf=\"countcharacters\" class=\"granite-input-bottom-row\">\n <div class=\"granite-input-char-count\">\n {{ _currentCharCount }}/{{ maxlength }}\n </div>\n </div>\n</div>\n", styles: [":host{transition:all .2s ease-out;width:14.5rem;box-sizing:border-box}:host *,:host *:before,:host *:after{box-sizing:inherit}.granite-input-container{width:inherit;font-size:var(--granite-font-size-body-small)}.granite-input-container .granite-input-top-row{display:inline-flex;width:inherit;position:relative;background:var(--granite-color-background)}.granite-input-container .granite-input-top-row:hover .granite-input-hover-bar{height:.125rem}.granite-input-container .granite-input-top-row:hover .granite-input-hover-bar.granite-input-invalid.granite-input-empty{background-color:var(--granite-color-focus)}.granite-input-container .granite-input-top-row .granite-text-area{min-width:14.5rem;min-height:2rem}.granite-input-container .granite-input-top-row.granite-input-disabled,.granite-input-container .granite-input-top-row.granite-input-readonly{background-color:transparent;box-shadow:none}.granite-input-container .granite-input-top-row.granite-input-disabled .granite-input-hover-bar,.granite-input-container .granite-input-top-row.granite-input-readonly .granite-input-hover-bar{background-color:transparent}.granite-input-container .granite-input-top-row .granite-input-base{-webkit-appearance:none;appearance:none;outline:none;border:none;background-color:var(--granite-color-background-input);padding:var(--granite-spacing-s);width:inherit;color:var(--granite-color-text);font:inherit;font-weight:var(--granite-font-weight-regular);line-height:var(--granite-line-height-regular)}.granite-input-container .granite-input-top-row .granite-input-base:required.granite-input-empty{background-color:var(--granite-color-background-failure)}.granite-input-container .granite-input-top-row .granite-input-base:required::placeholder{color:var(--granite-color-text-weak)}.granite-input-container .granite-input-top-row .granite-input-base:read-only{background-color:transparent}.granite-input-container .granite-input-top-row .granite-input-base:disabled{opacity:.3}.granite-input-container .granite-input-top-row .granite-input-base::placeholder{color:var(--granite-color-text-hint)}.granite-input-container .granite-input-top-row .granite-input-base:hover::placeholder{color:var(--granite-color-text)}.granite-input-container .granite-input-top-row .granite-input-base:focus{box-shadow:inset 0 .125rem var(--granite-color-focus),inset .125rem 0 var(--granite-color-focus),inset -.125rem 0 var(--granite-color-focus),inset 0 -.125rem var(--granite-color-focus)}.granite-input-container .granite-input-top-row .granite-input-base:focus.granite-input-invalid{box-shadow:inset 0 -.125rem var(--granite-color-signal-failure),inset 0 .125rem var(--granite-color-focus),inset .125rem 0 var(--granite-color-focus),inset -.125rem 0 var(--granite-color-focus)}.granite-input-container .granite-input-top-row .granite-input-base:focus::placeholder{color:transparent}.granite-input-container .granite-input-top-row .granite-input-hover-bar{height:.0625rem;background-color:var(--granite-color-border-hard);position:absolute;width:inherit;bottom:0px}.granite-input-container .granite-input-top-row .granite-input-hover-bar.granite-input-invalid{background-color:var(--granite-color-signal-failure)}.granite-input-container .granite-input-top-row:focus-within .granite-input-hover-bar{background-color:transparent}.granite-input-container .granite-input-prepend{display:flex;align-items:center;padding:0 var(--granite-spacing-s);background:var(--granite-color-background-input)}.granite-input-container .granite-input-prepend .granite-input-prepend-icon{width:1rem;height:1rem;color:var(--granite-color-text);box-shadow:none}.granite-input-container .granite-input-prepend.granite-input-required.granite-input-empty{background-color:var(--granite-color-background-failure)}.granite-input-container .granite-input-append{-webkit-appearance:none;appearance:none;outline:none;border:none;background-color:var(--granite-color-background-input);position:relative}.granite-input-container .granite-input-append:focus{box-shadow:inset 0 .125rem var(--granite-color-focus),inset .125rem 0 var(--granite-color-focus),inset -.125rem 0 var(--granite-color-focus),inset 0 -.125rem var(--granite-color-focus)}.granite-input-container .granite-input-append .granite-input-password-toggle-icon{width:max-content;height:max-content;color:var(--granite-color-text);box-shadow:none}.granite-input-container .granite-input-append.granite-input-required.granite-input-empty{background-color:var(--granite-color-background-failure)}.granite-input-container .granite-input-bottom-row{box-shadow:none}.granite-input-container .granite-input-char-count{background:var(--granite-color-background-warning);border-radius:0 0 .25rem .25rem;padding:var(--granite-spacing-s);background-size:contain;width:-moz-fit-content;width:fit-content;box-shadow:none}.granite-input-container.granite-input-disabled,.granite-input-container.granite-input-readonly{background-color:transparent}\n"], components: [{ type: GraniteIconComponent, selector: "granite-icon", inputs: ["fontIcon"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2943
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteInputFieldComponent, decorators: [{
2944
+ type: Component,
2945
+ args: [{ selector: 'granite-input-field', exportAs: 'graniteInputField', host: {
2946
+ class: 'granite-input-field',
2947
+ }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n *ngIf=\"_supported\"\n class=\"granite-input-container\"\n [class.granite-input-disabled]=\"disabled\"\n [class.granite-input-readonly]=\"readonly\"\n [class.granite-input-disabled]=\"disabled\"\n [class.granite-input-readonly]=\"readonly\"\n>\n <div\n class=\"granite-input-top-row\"\n [class.granite-input-required]=\"required\"\n [class.granite-input-empty]=\"_empty\"\n [class.granite-input-disabled]=\"disabled\"\n [class.granite-input-readonly]=\"readonly\"\n >\n <div\n *ngIf=\"prefixicon\"\n class=\"granite-input-prepend\"\n [class.granite-input-required]=\"required\"\n [class.granite-input-empty]=\"_empty\"\n >\n <granite-icon class=\"granite-input-prepend-icon\">\n {{ prefixicon }}\n </granite-icon>\n </div>\n\n <ng-container\n *ngIf=\"type !== 'textarea'; then inputElement; else textareaElement\"\n ></ng-container>\n\n <ng-template #inputElement>\n <input\n #input\n [id]=\"id\"\n class=\"granite-input-base\"\n [class.granite-input-invalid]=\"invalid\"\n [class.granite-input-empty]=\"_empty\"\n [name]=\"name\"\n [attr.type]=\"type\"\n [required]=\"required\"\n [readonly]=\"readonly\"\n [disabled]=\"disabled\"\n [placeholder]=\"placeholder\"\n [attr.maxlength]=\"maxlength\"\n [value]=\"value\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-labelledby]=\"ariaLabelledby\"\n [attr.aria-invalid]=\"invalid\"\n (keyup)=\"_onKeyUp($event)\"\n (input)=\"_onInput($event)\"\n />\n </ng-template>\n\n <button\n *ngIf=\"_passwordField\"\n class=\"granite-input-append\"\n [class.granite-input-required]=\"required\"\n [class.granite-input-empty]=\"_empty\"\n (click)=\"_togglePassword()\"\n >\n <granite-icon class=\"granite-input-password-toggle-icon\">\n {{ _passwordFieldIcon }}\n </granite-icon>\n </button>\n\n <ng-template #textareaElement>\n <textarea\n #textarea\n [id]=\"id\"\n class=\"granite-input-base granite-text-area\"\n [class.granite-input-invalid]=\"invalid\"\n [class.granite-input-empty]=\"_empty\"\n rows=\"1\"\n [name]=\"name\"\n [attr.type]=\"type\"\n [required]=\"required\"\n [readonly]=\"readonly\"\n [disabled]=\"disabled\"\n [placeholder]=\"placeholder\"\n [value]=\"value\"\n [attr.maxlength]=\"maxlength\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-labelledby]=\"ariaLabelledby\"\n [attr.aria-required]=\"required\"\n [attr.aria-invalid]=\"invalid\"\n (keyup)=\"_onKeyUp($event)\"\n (input)=\"_onInput($event)\"\n ></textarea>\n </ng-template>\n\n <div\n class=\"granite-input-hover-bar\"\n [class.granite-input-invalid]=\"invalid\"\n [class.granite-input-empty]=\"_empty\"\n ></div>\n </div>\n\n <div *ngIf=\"countcharacters\" class=\"granite-input-bottom-row\">\n <div class=\"granite-input-char-count\">\n {{ _currentCharCount }}/{{ maxlength }}\n </div>\n </div>\n</div>\n", styles: [":host{transition:all .2s ease-out;width:14.5rem;box-sizing:border-box}:host *,:host *:before,:host *:after{box-sizing:inherit}.granite-input-container{width:inherit;font-size:var(--granite-font-size-body-small)}.granite-input-container .granite-input-top-row{display:inline-flex;width:inherit;position:relative;background:var(--granite-color-background)}.granite-input-container .granite-input-top-row:hover .granite-input-hover-bar{height:.125rem}.granite-input-container .granite-input-top-row:hover .granite-input-hover-bar.granite-input-invalid.granite-input-empty{background-color:var(--granite-color-focus)}.granite-input-container .granite-input-top-row .granite-text-area{min-width:14.5rem;min-height:2rem}.granite-input-container .granite-input-top-row.granite-input-disabled,.granite-input-container .granite-input-top-row.granite-input-readonly{background-color:transparent;box-shadow:none}.granite-input-container .granite-input-top-row.granite-input-disabled .granite-input-hover-bar,.granite-input-container .granite-input-top-row.granite-input-readonly .granite-input-hover-bar{background-color:transparent}.granite-input-container .granite-input-top-row .granite-input-base{-webkit-appearance:none;appearance:none;outline:none;border:none;background-color:var(--granite-color-background-input);padding:var(--granite-spacing-s);width:inherit;color:var(--granite-color-text);font:inherit;font-weight:var(--granite-font-weight-regular);line-height:var(--granite-line-height-regular)}.granite-input-container .granite-input-top-row .granite-input-base:required.granite-input-empty{background-color:var(--granite-color-background-failure)}.granite-input-container .granite-input-top-row .granite-input-base:required::placeholder{color:var(--granite-color-text-weak)}.granite-input-container .granite-input-top-row .granite-input-base:read-only{background-color:transparent}.granite-input-container .granite-input-top-row .granite-input-base:disabled{opacity:.3}.granite-input-container .granite-input-top-row .granite-input-base::placeholder{color:var(--granite-color-text-hint)}.granite-input-container .granite-input-top-row .granite-input-base:hover::placeholder{color:var(--granite-color-text)}.granite-input-container .granite-input-top-row .granite-input-base:focus{box-shadow:inset 0 .125rem var(--granite-color-focus),inset .125rem 0 var(--granite-color-focus),inset -.125rem 0 var(--granite-color-focus),inset 0 -.125rem var(--granite-color-focus)}.granite-input-container .granite-input-top-row .granite-input-base:focus.granite-input-invalid{box-shadow:inset 0 -.125rem var(--granite-color-signal-failure),inset 0 .125rem var(--granite-color-focus),inset .125rem 0 var(--granite-color-focus),inset -.125rem 0 var(--granite-color-focus)}.granite-input-container .granite-input-top-row .granite-input-base:focus::placeholder{color:transparent}.granite-input-container .granite-input-top-row .granite-input-hover-bar{height:.0625rem;background-color:var(--granite-color-border-hard);position:absolute;width:inherit;bottom:0px}.granite-input-container .granite-input-top-row .granite-input-hover-bar.granite-input-invalid{background-color:var(--granite-color-signal-failure)}.granite-input-container .granite-input-top-row:focus-within .granite-input-hover-bar{background-color:transparent}.granite-input-container .granite-input-prepend{display:flex;align-items:center;padding:0 var(--granite-spacing-s);background:var(--granite-color-background-input)}.granite-input-container .granite-input-prepend .granite-input-prepend-icon{width:1rem;height:1rem;color:var(--granite-color-text);box-shadow:none}.granite-input-container .granite-input-prepend.granite-input-required.granite-input-empty{background-color:var(--granite-color-background-failure)}.granite-input-container .granite-input-append{-webkit-appearance:none;appearance:none;outline:none;border:none;background-color:var(--granite-color-background-input);position:relative}.granite-input-container .granite-input-append:focus{box-shadow:inset 0 .125rem var(--granite-color-focus),inset .125rem 0 var(--granite-color-focus),inset -.125rem 0 var(--granite-color-focus),inset 0 -.125rem var(--granite-color-focus)}.granite-input-container .granite-input-append .granite-input-password-toggle-icon{width:max-content;height:max-content;color:var(--granite-color-text);box-shadow:none}.granite-input-container .granite-input-append.granite-input-required.granite-input-empty{background-color:var(--granite-color-background-failure)}.granite-input-container .granite-input-bottom-row{box-shadow:none}.granite-input-container .granite-input-char-count{background:var(--granite-color-background-warning);border-radius:0 0 .25rem .25rem;padding:var(--granite-spacing-s);background-size:contain;width:-moz-fit-content;width:fit-content;box-shadow:none}.granite-input-container.granite-input-disabled,.granite-input-container.granite-input-readonly{background-color:transparent}\n"] }]
2948
+ }], ctorParameters: function () { return [{ type: i1.FocusMonitor }]; }, propDecorators: { id: [{
2949
+ type: Input
2950
+ }], name: [{
2951
+ type: Input
2952
+ }], type: [{
2953
+ type: Input
2954
+ }], value: [{
2955
+ type: Input
2956
+ }], required: [{
2957
+ type: Input
2958
+ }], readonly: [{
2959
+ type: Input
2960
+ }], invalid: [{
2961
+ type: Input
2962
+ }], disabled: [{
2963
+ type: Input
2964
+ }], placeholder: [{
2965
+ type: Input
2966
+ }], prefixicon: [{
2967
+ type: Input
2968
+ }], maxlength: [{
2969
+ type: Input
2970
+ }], countcharacters: [{
2971
+ type: Input
2972
+ }], ariaLabel: [{
2973
+ type: Input,
2974
+ args: ['aria-label']
2975
+ }], ariaLabelledby: [{
2976
+ type: Input,
2977
+ args: ['aria-labelledby']
2978
+ }], valueChange: [{
2979
+ type: Output
2980
+ }], _inputElement: [{
2981
+ type: ViewChild,
2982
+ args: ['input']
2983
+ }], _textareaElement: [{
2984
+ type: ViewChild,
2985
+ args: ['textarea']
2986
+ }] } });
2987
+
2988
+ class GraniteInputFieldModule {
2989
+ }
2990
+ GraniteInputFieldModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteInputFieldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2991
+ GraniteInputFieldModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteInputFieldModule, declarations: [GraniteInputFieldComponent], imports: [CommonModule, GraniteIconModule, GraniteButtonModule], exports: [GraniteInputFieldComponent] });
2992
+ GraniteInputFieldModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteInputFieldModule, imports: [[CommonModule, GraniteIconModule, GraniteButtonModule]] });
2993
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteInputFieldModule, decorators: [{
2994
+ type: NgModule,
2995
+ args: [{
2996
+ imports: [CommonModule, GraniteIconModule, GraniteButtonModule],
2997
+ declarations: [GraniteInputFieldComponent],
2998
+ exports: [GraniteInputFieldComponent],
2999
+ }]
3000
+ }] });
3001
+
3002
+ /**
3003
+ * Directive used to tell components and their sub components that client output
3004
+ * should be adapted for desktop devices like personal computers.
3005
+ */
3006
+ class ClientOutputDesktopDirective {
3007
+ }
3008
+ ClientOutputDesktopDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ClientOutputDesktopDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3009
+ ClientOutputDesktopDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.11", type: ClientOutputDesktopDirective, selector: "[graniteClientOutputDesktop]", providers: [
3010
+ {
3011
+ provide: GRANITE_CLIENT_OUTPUT,
3012
+ useValue: deviceDesktop.output,
3013
+ },
3014
+ ], ngImport: i0 });
3015
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ClientOutputDesktopDirective, decorators: [{
3016
+ type: Directive,
3017
+ args: [{
3018
+ selector: `[graniteClientOutputDesktop]`,
3019
+ providers: [
3020
+ {
3021
+ provide: GRANITE_CLIENT_OUTPUT,
3022
+ useValue: deviceDesktop.output,
3023
+ },
3024
+ ],
3025
+ }]
3026
+ }] });
3027
+
3028
+ /**
3029
+ * Directive used to tell components and their sub components that client output
3030
+ * should be adapted for touch devices like mobiles and tablets.
3031
+ */
3032
+ class ClientOutputTouchDirective {
3033
+ }
3034
+ ClientOutputTouchDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ClientOutputTouchDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3035
+ ClientOutputTouchDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.11", type: ClientOutputTouchDirective, selector: "[graniteClientOutputTouch]", providers: [
3036
+ {
3037
+ provide: GRANITE_CLIENT_OUTPUT,
3038
+ useValue: deviceTouch.output,
3039
+ },
3040
+ ], ngImport: i0 });
3041
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ClientOutputTouchDirective, decorators: [{
3042
+ type: Directive,
3043
+ args: [{
3044
+ selector: `[graniteClientOutputTouch]`,
3045
+ providers: [
3046
+ {
3047
+ provide: GRANITE_CLIENT_OUTPUT,
3048
+ useValue: deviceTouch.output,
3049
+ },
3050
+ ],
3051
+ }]
3052
+ }] });
3053
+
3054
+ /**
3055
+ * Directive used to tell components and their sub components that client input
3056
+ * should be adapted for desktop devices, like personal computers.
3057
+ */
3058
+ class ClientInputDesktopDirective {
3059
+ }
3060
+ ClientInputDesktopDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ClientInputDesktopDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3061
+ ClientInputDesktopDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.11", type: ClientInputDesktopDirective, selector: "[graniteClientInputDesktop]", providers: [
3062
+ {
3063
+ provide: GRANITE_CLIENT_INPUT,
3064
+ useValue: deviceDesktop.input,
3065
+ },
3066
+ ], ngImport: i0 });
3067
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ClientInputDesktopDirective, decorators: [{
3068
+ type: Directive,
3069
+ args: [{
3070
+ selector: `[graniteClientInputDesktop]`,
3071
+ providers: [
3072
+ {
3073
+ provide: GRANITE_CLIENT_INPUT,
3074
+ useValue: deviceDesktop.input,
3075
+ },
3076
+ ],
3077
+ }]
3078
+ }] });
3079
+
3080
+ /**
3081
+ * Directive used to tell components and their sub components that client input
3082
+ * should be adapted for touch devices, like mobiles and tablets.
3083
+ */
3084
+ class ClientInputTouchDirective {
3085
+ }
3086
+ ClientInputTouchDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ClientInputTouchDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3087
+ ClientInputTouchDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.3.11", type: ClientInputTouchDirective, selector: "[graniteClientInputTouch]", providers: [
3088
+ {
3089
+ provide: GRANITE_CLIENT_INPUT,
3090
+ useValue: deviceTouch.input,
3091
+ },
3092
+ ], ngImport: i0 });
3093
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: ClientInputTouchDirective, decorators: [{
3094
+ type: Directive,
3095
+ args: [{
3096
+ selector: `[graniteClientInputTouch]`,
3097
+ providers: [
3098
+ {
3099
+ provide: GRANITE_CLIENT_INPUT,
3100
+ useValue: deviceTouch.input,
3101
+ },
3102
+ ],
3103
+ }]
3104
+ }] });
3105
+
3106
+ // TODO: Move client devices into a separate module
3107
+ class GraniteCoreModule {
3108
+ }
3109
+ GraniteCoreModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteCoreModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
3110
+ GraniteCoreModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteCoreModule, declarations: [ClientOutputDesktopDirective,
3111
+ ClientOutputTouchDirective,
3112
+ ClientInputDesktopDirective,
3113
+ ClientInputTouchDirective], exports: [ClientOutputDesktopDirective,
3114
+ ClientOutputTouchDirective,
3115
+ ClientInputDesktopDirective,
3116
+ ClientInputTouchDirective] });
3117
+ GraniteCoreModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteCoreModule });
3118
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: GraniteCoreModule, decorators: [{
3119
+ type: NgModule,
3120
+ args: [{
3121
+ declarations: [
3122
+ ClientOutputDesktopDirective,
3123
+ ClientOutputTouchDirective,
3124
+ ClientInputDesktopDirective,
3125
+ ClientInputTouchDirective,
3126
+ ],
3127
+ exports: [
3128
+ ClientOutputDesktopDirective,
3129
+ ClientOutputTouchDirective,
3130
+ ClientInputDesktopDirective,
3131
+ ClientInputTouchDirective,
3132
+ ],
3133
+ }]
3134
+ }] });
3135
+
3136
+ /*
3137
+ * Public API Surface of ui
3138
+ */
3139
+
3140
+ /**
3141
+ * Generated bundle index. Do not edit.
3142
+ */
3143
+
3144
+ export { ButtonSelectors, ClientInputDesktopDirective, ClientInputTouchDirective, ClientOutputDesktopDirective, ClientOutputTouchDirective, GRANITE_CLIENT_INPUT, GRANITE_CLIENT_OUTPUT, GraniteAnchorComponent, GraniteArrangeGridComponent, GraniteArrangeGridItemComponent, GraniteArrangeGridModule, GraniteArrangeGridOrientation, GraniteBadgeComponent, GraniteBadgeHarness, GraniteBadgeModule, GraniteButtonComponent, GraniteButtonModule, GraniteCheckboxComponent, GraniteCheckboxGroupComponent, GraniteCheckboxModule, GraniteCoreModule, GraniteDividerDirective, GraniteGridComponent, GraniteGridItemComponent, GraniteGridModule, GraniteIconComponent, GraniteIconModule, GraniteInputFieldComponent, GraniteInputFieldModule, GraniteMenuComponent, GraniteMenuHarness, GraniteMenuItemComponent, GraniteMenuItemHarness, GraniteMenuModule, GraniteMenuTouchCloseComponent, GraniteMenuTouchTitleItemComponent, GraniteMenuTriggerForDirective, GraniteRadioButtonComponent, GraniteRadioButtonModule, GraniteRadioGroupComponent, GraniteTableColumnDirective, GraniteTableComponent, GraniteTableModule, GraniteTitleDirective, GraniteToggleSwitchComponent, GraniteToggleSwitchModule, deviceDesktop, deviceTouch, disabledMixin, graniteMenuDesktopAnimations, graniteMenuTouchAnimations };
3145
+ //# sourceMappingURL=ifsworld-granite-components.mjs.map