@tft/crispr-forms 13.0.23 → 14.0.1-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (320) hide show
  1. package/README.md +77 -76
  2. package/esm2020/public-api.mjs +5 -0
  3. package/esm2020/src/index.mjs +2 -0
  4. package/esm2020/src/lib/crispr-forms.module.mjs +57 -0
  5. package/esm2020/src/lib/field-component-map.const.mjs +27 -0
  6. package/esm2020/src/lib/field.directive.mjs +69 -0
  7. package/esm2020/src/lib/form/form.component.mjs +63 -0
  8. package/esm2020/src/lib/form-group-list/form-group-list.component.mjs +93 -0
  9. package/esm2020/src/lib/form-group-list/index.mjs +2 -0
  10. package/esm2020/src/lib/pipes/crispr-pipes.module.mjs +24 -0
  11. package/esm2020/src/lib/pipes/initial-control-value.pipe.mjs +21 -0
  12. package/esm2020/src/lib/public_api.mjs +3 -0
  13. package/esm2020/src/lib/sub-group/index.mjs +3 -0
  14. package/esm2020/src/lib/sub-group/sub-group.component.mjs +21 -0
  15. package/esm2020/src/lib/sub-group/sub-group.module.mjs +42 -0
  16. package/esm2020/tft-crispr-forms.mjs +2 -2
  17. package/esm2020/ui/autocomplete-chiplist-field/autocomplete-chiplist-field.component.mjs +127 -0
  18. package/esm2020/ui/autocomplete-chiplist-field/index.mjs +2 -0
  19. package/esm2020/ui/autocomplete-field/autocomplete-field.component.mjs +90 -0
  20. package/esm2020/ui/autocomplete-field/index.mjs +2 -0
  21. package/esm2020/ui/button/button.component.mjs +46 -0
  22. package/esm2020/ui/button/index.mjs +2 -0
  23. package/esm2020/ui/checkbox-field/checkbox-field.component.mjs +42 -0
  24. package/esm2020/ui/checkbox-field/index.mjs +2 -0
  25. package/esm2020/ui/datepicker-field/datepicker-field.component.mjs +60 -0
  26. package/esm2020/ui/datepicker-field/index.mjs +2 -0
  27. package/esm2020/ui/divider/divider.component.mjs +28 -0
  28. package/esm2020/ui/divider/index.mjs +2 -0
  29. package/esm2020/ui/field-container/field-container.component.mjs +58 -0
  30. package/esm2020/ui/field-container/public-api.mjs +2 -0
  31. package/esm2020/ui/field-container/tft-crispr-forms-ui-field-container.mjs +5 -0
  32. package/esm2020/ui/file-dropzone/file-dropzone.directive.mjs +40 -0
  33. package/esm2020/ui/file-dropzone/public-api.mjs +2 -0
  34. package/esm2020/ui/file-dropzone/tft-crispr-forms-ui-file-dropzone.mjs +5 -0
  35. package/esm2020/ui/file-upload/file-upload.component.mjs +108 -0
  36. package/esm2020/ui/file-upload/index.mjs +2 -0
  37. package/esm2020/ui/heading/heading.component.mjs +31 -0
  38. package/esm2020/ui/heading/public-api.mjs +2 -0
  39. package/esm2020/ui/heading/tft-crispr-forms-ui-heading.mjs +5 -0
  40. package/esm2020/ui/image-upload-field/image-upload-field.component.mjs +179 -0
  41. package/esm2020/ui/image-upload-field/public-api.mjs +2 -0
  42. package/esm2020/ui/image-upload-field/tft-crispr-forms-ui-image-upload-field.mjs +5 -0
  43. package/esm2020/ui/info/info.component.mjs +23 -0
  44. package/esm2020/ui/info/public-api.mjs +2 -0
  45. package/esm2020/ui/info/tft-crispr-forms-ui-info.mjs +5 -0
  46. package/esm2020/ui/input-field/index.mjs +2 -0
  47. package/esm2020/ui/input-field/input-field.component.mjs +38 -0
  48. package/esm2020/ui/option/index.mjs +2 -0
  49. package/esm2020/ui/option/option.component.mjs +19 -0
  50. package/esm2020/ui/public-api.mjs +21 -0
  51. package/esm2020/ui/radio-field/index.mjs +2 -0
  52. package/esm2020/ui/radio-field/radio-field.component.mjs +36 -0
  53. package/esm2020/ui/select-field/index.mjs +2 -0
  54. package/esm2020/ui/select-field/select-field.component.mjs +74 -0
  55. package/esm2020/ui/selected-file/public-api.mjs +2 -0
  56. package/esm2020/ui/selected-file/selected-file.component.mjs +26 -0
  57. package/esm2020/ui/selected-file/tft-crispr-forms-ui-selected-file.mjs +5 -0
  58. package/esm2020/ui/slider-field/index.mjs +2 -0
  59. package/esm2020/ui/slider-field/slider-field.component.mjs +41 -0
  60. package/esm2020/ui/textarea-field/index.mjs +2 -0
  61. package/esm2020/ui/textarea-field/textarea-field.component.mjs +39 -0
  62. package/esm2020/ui/tft-crispr-forms-ui.mjs +5 -0
  63. package/esm2020/ui/unit-conversion-field/index.mjs +2 -0
  64. package/esm2020/ui/unit-conversion-field/unit-conversion-field.component.mjs +81 -0
  65. package/esm2020/utils/abstracts/autocomplete-field.abstract.mjs +30 -0
  66. package/esm2020/utils/abstracts/crispr-control.mixin.mjs +27 -0
  67. package/esm2020/utils/abstracts/crispr-field.abstract.mjs +20 -0
  68. package/esm2020/utils/abstracts/index.mjs +4 -0
  69. package/esm2020/utils/functions/buildFormGroupFromConfig.mjs +28 -0
  70. package/esm2020/utils/functions/callOptionsIfFunction.mjs +4 -0
  71. package/esm2020/utils/functions/createControlForType.mjs +19 -0
  72. package/esm2020/utils/functions/filterOptionsByLabel.mjs +11 -0
  73. package/esm2020/utils/functions/image-compression.helpers.mjs +50 -0
  74. package/esm2020/utils/functions/index.mjs +8 -0
  75. package/esm2020/utils/functions/isControlConfig.mjs +7 -0
  76. package/esm2020/utils/functions/observablifyOptions.mjs +29 -0
  77. package/esm2020/utils/models/autocomplete-chiplist-field.config.mjs +2 -0
  78. package/esm2020/utils/models/autocomplete-field.config.mjs +2 -0
  79. package/esm2020/utils/models/button.config.mjs +2 -0
  80. package/esm2020/utils/models/checkbox-field.config.mjs +2 -0
  81. package/esm2020/utils/models/crispr-field.config.mjs +23 -0
  82. package/esm2020/utils/models/datepicker-field.config.mjs +2 -0
  83. package/esm2020/utils/models/divider.config.mjs +2 -0
  84. package/esm2020/utils/models/file-upload-field.config.mjs +2 -0
  85. package/esm2020/utils/models/form-group-list.config.mjs +2 -0
  86. package/esm2020/utils/models/heading.config.mjs +3 -0
  87. package/esm2020/utils/models/image-upload-field.config.mjs +2 -0
  88. package/esm2020/utils/models/index.mjs +18 -0
  89. package/esm2020/utils/models/input-field.config.mjs +2 -0
  90. package/esm2020/utils/models/radio-field.config.mjs +2 -0
  91. package/esm2020/utils/models/select-field.config.mjs +2 -0
  92. package/esm2020/utils/models/slider-field.config.mjs +2 -0
  93. package/esm2020/utils/models/textarea-field.config.mjs +2 -0
  94. package/esm2020/utils/models/unit-conversion-field.config.mjs +2 -0
  95. package/esm2020/utils/operators/form.operators.mjs +24 -0
  96. package/esm2020/utils/operators/index.mjs +2 -0
  97. package/esm2020/utils/public-api.mjs +5 -0
  98. package/esm2020/utils/tft-crispr-forms-utils.mjs +5 -0
  99. package/fesm2015/tft-crispr-forms-ui-field-container.mjs +64 -0
  100. package/fesm2015/tft-crispr-forms-ui-field-container.mjs.map +1 -0
  101. package/fesm2015/tft-crispr-forms-ui-file-dropzone.mjs +47 -0
  102. package/fesm2015/tft-crispr-forms-ui-file-dropzone.mjs.map +1 -0
  103. package/fesm2015/tft-crispr-forms-ui-heading.mjs +37 -0
  104. package/fesm2015/tft-crispr-forms-ui-heading.mjs.map +1 -0
  105. package/fesm2015/tft-crispr-forms-ui-image-upload-field.mjs +182 -0
  106. package/fesm2015/tft-crispr-forms-ui-image-upload-field.mjs.map +1 -0
  107. package/fesm2015/tft-crispr-forms-ui-info.mjs +30 -0
  108. package/fesm2015/tft-crispr-forms-ui-info.mjs.map +1 -0
  109. package/fesm2015/tft-crispr-forms-ui-selected-file.mjs +33 -0
  110. package/fesm2015/tft-crispr-forms-ui-selected-file.mjs.map +1 -0
  111. package/fesm2015/tft-crispr-forms-ui.mjs +684 -0
  112. package/fesm2015/tft-crispr-forms-ui.mjs.map +1 -0
  113. package/fesm2015/tft-crispr-forms-utils.mjs +270 -0
  114. package/fesm2015/tft-crispr-forms-utils.mjs.map +1 -0
  115. package/fesm2015/tft-crispr-forms.mjs +117 -1730
  116. package/fesm2015/tft-crispr-forms.mjs.map +1 -1
  117. package/fesm2020/tft-crispr-forms-ui-field-container.mjs +65 -0
  118. package/fesm2020/tft-crispr-forms-ui-field-container.mjs.map +1 -0
  119. package/fesm2020/tft-crispr-forms-ui-file-dropzone.mjs +47 -0
  120. package/fesm2020/tft-crispr-forms-ui-file-dropzone.mjs.map +1 -0
  121. package/fesm2020/tft-crispr-forms-ui-heading.mjs +37 -0
  122. package/fesm2020/tft-crispr-forms-ui-heading.mjs.map +1 -0
  123. package/fesm2020/tft-crispr-forms-ui-image-upload-field.mjs +185 -0
  124. package/fesm2020/tft-crispr-forms-ui-image-upload-field.mjs.map +1 -0
  125. package/fesm2020/tft-crispr-forms-ui-info.mjs +30 -0
  126. package/fesm2020/tft-crispr-forms-ui-info.mjs.map +1 -0
  127. package/fesm2020/tft-crispr-forms-ui-selected-file.mjs +33 -0
  128. package/fesm2020/tft-crispr-forms-ui-selected-file.mjs.map +1 -0
  129. package/fesm2020/tft-crispr-forms-ui.mjs +676 -0
  130. package/fesm2020/tft-crispr-forms-ui.mjs.map +1 -0
  131. package/fesm2020/tft-crispr-forms-utils.mjs +269 -0
  132. package/fesm2020/tft-crispr-forms-utils.mjs.map +1 -0
  133. package/fesm2020/tft-crispr-forms.mjs +117 -1723
  134. package/fesm2020/tft-crispr-forms.mjs.map +1 -1
  135. package/index.d.ts +5 -1
  136. package/package.json +77 -15
  137. package/public-api.d.ts +3 -0
  138. package/src/index.d.ts +1 -0
  139. package/src/lib/crispr-forms.module.d.ts +15 -0
  140. package/{lib → src/lib}/field-component-map.const.d.ts +7 -6
  141. package/{lib → src/lib}/field.directive.d.ts +4 -10
  142. package/{lib → src/lib}/form/form.component.d.ts +3 -3
  143. package/{lib → src/lib}/form-group-list/form-group-list.component.d.ts +12 -14
  144. package/{lib → src/lib}/form-group-list/index.d.ts +0 -1
  145. package/{lib → src/lib}/pipes/crispr-pipes.module.d.ts +0 -0
  146. package/{lib → src/lib}/pipes/initial-control-value.pipe.d.ts +2 -2
  147. package/src/lib/public_api.d.ts +2 -0
  148. package/{lib → src/lib}/sub-group/index.d.ts +0 -0
  149. package/src/lib/sub-group/sub-group.component.d.ts +22 -0
  150. package/{lib → src/lib}/sub-group/sub-group.module.d.ts +2 -2
  151. package/tft-crispr-forms-14.0.1-rc.2.tgz +0 -0
  152. package/ui/README.md +3 -0
  153. package/{lib/material → ui}/autocomplete-chiplist-field/autocomplete-chiplist-field.component.d.ts +2 -3
  154. package/ui/autocomplete-chiplist-field/index.d.ts +1 -0
  155. package/{lib/material → ui}/autocomplete-field/autocomplete-field.component.d.ts +2 -3
  156. package/ui/autocomplete-field/index.d.ts +1 -0
  157. package/{lib/material → ui}/button/button.component.d.ts +2 -3
  158. package/ui/button/index.d.ts +1 -0
  159. package/ui/checkbox-field/checkbox-field.component.d.ts +21 -0
  160. package/ui/checkbox-field/index.d.ts +1 -0
  161. package/{lib/material → ui}/datepicker-field/datepicker-field.component.d.ts +14 -17
  162. package/ui/datepicker-field/index.d.ts +1 -0
  163. package/{lib/material → ui}/divider/divider.component.d.ts +2 -3
  164. package/ui/divider/index.d.ts +1 -0
  165. package/{lib → ui}/field-container/field-container.component.d.ts +3 -10
  166. package/ui/field-container/index.d.ts +5 -0
  167. package/{lib/field-container/index.d.ts → ui/field-container/public-api.d.ts} +0 -0
  168. package/{lib/material/file-upload → ui/file-dropzone}/file-dropzone.directive.d.ts +1 -1
  169. package/ui/file-dropzone/index.d.ts +5 -0
  170. package/{lib/material/file-upload/index.d.ts → ui/file-dropzone/public-api.d.ts} +0 -1
  171. package/ui/file-upload/file-upload.component.d.ts +37 -0
  172. package/ui/file-upload/index.d.ts +1 -0
  173. package/ui/heading/heading.component.d.ts +8 -0
  174. package/ui/heading/index.d.ts +5 -0
  175. package/ui/heading/public-api.d.ts +1 -0
  176. package/ui/image-upload-field/image-upload-field.component.d.ts +48 -0
  177. package/ui/image-upload-field/index.d.ts +5 -0
  178. package/{lib/material/image-upload-field/index.d.ts → ui/image-upload-field/public-api.d.ts} +0 -0
  179. package/ui/index.d.ts +5 -0
  180. package/ui/info/index.d.ts +5 -0
  181. package/ui/info/info.component.d.ts +7 -0
  182. package/ui/info/public-api.d.ts +1 -0
  183. package/ui/input-field/index.d.ts +1 -0
  184. package/ui/input-field/input-field.component.d.ts +22 -0
  185. package/{lib/material → ui}/option/index.d.ts +0 -0
  186. package/{lib/material → ui}/option/option.component.d.ts +2 -2
  187. package/ui/public-api.d.ts +19 -0
  188. package/ui/radio-field/index.d.ts +1 -0
  189. package/ui/radio-field/radio-field.component.d.ts +23 -0
  190. package/ui/select-field/index.d.ts +1 -0
  191. package/{lib/material → ui}/select-field/select-field.component.d.ts +12 -14
  192. package/ui/selected-file/index.d.ts +5 -0
  193. package/ui/selected-file/public-api.d.ts +1 -0
  194. package/ui/selected-file/selected-file.component.d.ts +10 -0
  195. package/ui/slider-field/index.d.ts +1 -0
  196. package/ui/slider-field/slider-field.component.d.ts +25 -0
  197. package/ui/textarea-field/index.d.ts +1 -0
  198. package/ui/textarea-field/textarea-field.component.d.ts +21 -0
  199. package/ui/unit-conversion-field/index.d.ts +1 -0
  200. package/{lib/material → ui}/unit-conversion-field/unit-conversion-field.component.d.ts +14 -17
  201. package/utils/README.md +3 -0
  202. package/{lib → utils}/abstracts/autocomplete-field.abstract.d.ts +4 -4
  203. package/{lib → utils}/abstracts/crispr-control.mixin.d.ts +0 -0
  204. package/{lib → utils}/abstracts/crispr-field.abstract.d.ts +1 -1
  205. package/{lib → utils}/abstracts/index.d.ts +0 -0
  206. package/utils/functions/buildFormGroupFromConfig.d.ts +9 -0
  207. package/utils/functions/callOptionsIfFunction.d.ts +3 -0
  208. package/utils/functions/createControlForType.d.ts +9 -0
  209. package/utils/functions/filterOptionsByLabel.d.ts +7 -0
  210. package/utils/functions/image-compression.helpers.d.ts +5 -0
  211. package/utils/functions/index.d.ts +7 -0
  212. package/utils/functions/isControlConfig.d.ts +5 -0
  213. package/utils/functions/observablifyOptions.d.ts +12 -0
  214. package/utils/index.d.ts +5 -0
  215. package/{lib → utils}/models/autocomplete-chiplist-field.config.d.ts +2 -1
  216. package/{lib → utils}/models/autocomplete-field.config.d.ts +1 -2
  217. package/{lib → utils}/models/button.config.d.ts +0 -0
  218. package/{lib → utils}/models/checkbox-field.config.d.ts +1 -2
  219. package/{lib → utils}/models/crispr-field.config.d.ts +5 -7
  220. package/{lib → utils}/models/datepicker-field.config.d.ts +4 -6
  221. package/{lib → utils}/models/divider.config.d.ts +1 -1
  222. package/{lib → utils}/models/file-upload-field.config.d.ts +3 -4
  223. package/{lib → utils}/models/form-group-list.config.d.ts +1 -2
  224. package/{lib → utils}/models/heading.config.d.ts +1 -2
  225. package/{lib → utils}/models/image-upload-field.config.d.ts +2 -1
  226. package/{lib → utils}/models/index.d.ts +0 -0
  227. package/{lib → utils}/models/input-field.config.d.ts +1 -2
  228. package/{lib → utils}/models/radio-field.config.d.ts +0 -0
  229. package/{lib → utils}/models/select-field.config.d.ts +1 -2
  230. package/{lib → utils}/models/slider-field.config.d.ts +1 -2
  231. package/{lib → utils}/models/textarea-field.config.d.ts +1 -2
  232. package/{lib → utils}/models/unit-conversion-field.config.d.ts +1 -2
  233. package/{lib → utils/operators}/form.operators.d.ts +0 -0
  234. package/utils/operators/index.d.ts +1 -0
  235. package/utils/public-api.d.ts +4 -0
  236. package/esm2020/index.mjs +0 -2
  237. package/esm2020/lib/abstracts/autocomplete-field.abstract.mjs +0 -30
  238. package/esm2020/lib/abstracts/crispr-control.mixin.mjs +0 -27
  239. package/esm2020/lib/abstracts/crispr-field.abstract.mjs +0 -17
  240. package/esm2020/lib/abstracts/index.mjs +0 -4
  241. package/esm2020/lib/crispr-forms.module.mjs +0 -66
  242. package/esm2020/lib/field-component-map.const.mjs +0 -28
  243. package/esm2020/lib/field-container/field-container.component.mjs +0 -85
  244. package/esm2020/lib/field-container/index.mjs +0 -2
  245. package/esm2020/lib/field.directive.mjs +0 -90
  246. package/esm2020/lib/form/form.component.mjs +0 -53
  247. package/esm2020/lib/form-group-list/form-group-list.component.mjs +0 -77
  248. package/esm2020/lib/form-group-list/form-group-list.module.mjs +0 -54
  249. package/esm2020/lib/form-group-list/index.mjs +0 -3
  250. package/esm2020/lib/form.helpers.mjs +0 -190
  251. package/esm2020/lib/form.operators.mjs +0 -24
  252. package/esm2020/lib/material/autocomplete-chiplist-field/autocomplete-chiplist-field.component.mjs +0 -111
  253. package/esm2020/lib/material/autocomplete-field/autocomplete-field.component.mjs +0 -78
  254. package/esm2020/lib/material/button/button.component.mjs +0 -35
  255. package/esm2020/lib/material/checkbox-field/checkbox-field.component.mjs +0 -31
  256. package/esm2020/lib/material/datepicker-field/datepicker-field.component.mjs +0 -45
  257. package/esm2020/lib/material/divider/divider.component.mjs +0 -22
  258. package/esm2020/lib/material/file-upload/file-dropzone.directive.mjs +0 -39
  259. package/esm2020/lib/material/file-upload/file-upload.component.mjs +0 -145
  260. package/esm2020/lib/material/file-upload/index.mjs +0 -3
  261. package/esm2020/lib/material/heading/heading.component.mjs +0 -54
  262. package/esm2020/lib/material/image-upload-field/image-compression.helpers.mjs +0 -4
  263. package/esm2020/lib/material/image-upload-field/image-upload-field.component.mjs +0 -265
  264. package/esm2020/lib/material/image-upload-field/index.mjs +0 -2
  265. package/esm2020/lib/material/index.mjs +0 -18
  266. package/esm2020/lib/material/info/info.component.mjs +0 -46
  267. package/esm2020/lib/material/input-field/input-field.component.mjs +0 -27
  268. package/esm2020/lib/material/material.module.mjs +0 -200
  269. package/esm2020/lib/material/option/index.mjs +0 -2
  270. package/esm2020/lib/material/option/option.component.mjs +0 -15
  271. package/esm2020/lib/material/radio-field/radio-field.component.mjs +0 -29
  272. package/esm2020/lib/material/select-field/select-field.component.mjs +0 -58
  273. package/esm2020/lib/material/selected-file/selected-file.component.mjs +0 -47
  274. package/esm2020/lib/material/slider-field/slider-field.component.mjs +0 -30
  275. package/esm2020/lib/material/textarea-field/textarea-field.component.mjs +0 -28
  276. package/esm2020/lib/material/unit-conversion-field/unit-conversion-field.component.mjs +0 -69
  277. package/esm2020/lib/models/autocomplete-chiplist-field.config.mjs +0 -2
  278. package/esm2020/lib/models/autocomplete-field.config.mjs +0 -2
  279. package/esm2020/lib/models/button.config.mjs +0 -2
  280. package/esm2020/lib/models/checkbox-field.config.mjs +0 -2
  281. package/esm2020/lib/models/crispr-field.config.mjs +0 -23
  282. package/esm2020/lib/models/datepicker-field.config.mjs +0 -2
  283. package/esm2020/lib/models/divider.config.mjs +0 -2
  284. package/esm2020/lib/models/file-upload-field.config.mjs +0 -2
  285. package/esm2020/lib/models/form-group-list.config.mjs +0 -2
  286. package/esm2020/lib/models/heading.config.mjs +0 -3
  287. package/esm2020/lib/models/image-upload-field.config.mjs +0 -2
  288. package/esm2020/lib/models/index.mjs +0 -18
  289. package/esm2020/lib/models/input-field.config.mjs +0 -2
  290. package/esm2020/lib/models/radio-field.config.mjs +0 -2
  291. package/esm2020/lib/models/select-field.config.mjs +0 -2
  292. package/esm2020/lib/models/slider-field.config.mjs +0 -2
  293. package/esm2020/lib/models/textarea-field.config.mjs +0 -2
  294. package/esm2020/lib/models/unit-conversion-field.config.mjs +0 -2
  295. package/esm2020/lib/pipes/crispr-pipes.module.mjs +0 -26
  296. package/esm2020/lib/pipes/initial-control-value.pipe.mjs +0 -20
  297. package/esm2020/lib/public_api.mjs +0 -10
  298. package/esm2020/lib/sub-group/index.mjs +0 -3
  299. package/esm2020/lib/sub-group/sub-group.component.mjs +0 -20
  300. package/esm2020/lib/sub-group/sub-group.module.mjs +0 -45
  301. package/lib/crispr-forms.module.d.ts +0 -16
  302. package/lib/form-group-list/form-group-list.module.d.ts +0 -15
  303. package/lib/form.helpers.d.ts +0 -88
  304. package/lib/material/checkbox-field/checkbox-field.component.d.ts +0 -23
  305. package/lib/material/file-upload/file-upload.component.d.ts +0 -54
  306. package/lib/material/heading/heading.component.d.ts +0 -17
  307. package/lib/material/image-upload-field/image-compression.helpers.d.ts +0 -1
  308. package/lib/material/image-upload-field/image-upload-field.component.d.ts +0 -68
  309. package/lib/material/index.d.ts +0 -17
  310. package/lib/material/info/info.component.d.ts +0 -15
  311. package/lib/material/input-field/input-field.component.d.ts +0 -24
  312. package/lib/material/material.module.d.ts +0 -44
  313. package/lib/material/radio-field/radio-field.component.d.ts +0 -26
  314. package/lib/material/selected-file/selected-file.component.d.ts +0 -17
  315. package/lib/material/slider-field/slider-field.component.d.ts +0 -27
  316. package/lib/material/textarea-field/textarea-field.component.d.ts +0 -24
  317. package/lib/public_api.d.ts +0 -9
  318. package/lib/sub-group/sub-group.component.d.ts +0 -24
  319. package/tft-crispr-forms-13.0.23.tgz +0 -0
  320. package/tft-crispr-forms.d.ts +0 -5
@@ -1,1584 +1,40 @@
1
- import { of, combineLatest, from, isObservable, BehaviorSubject, Subject } from 'rxjs';
2
- import * as i4$1 from '@angular/forms';
3
- import { FormGroup, FormArray, FormControl, ReactiveFormsModule } from '@angular/forms';
4
- import { map, startWith, debounceTime, distinctUntilChanged, switchMap, shareReplay, tap } from 'rxjs/operators';
5
1
  import * as i0 from '@angular/core';
6
- import { Directive, Component, ChangeDetectionStrategy, Input, NgModule, ViewChild, EventEmitter, Output, HostListener, Optional, Self, Pipe } from '@angular/core';
7
- import * as i2 from '@angular/common';
2
+ import { Directive, Input, Pipe, NgModule, EventEmitter, Component, Output, ViewChild, ChangeDetectionStrategy } from '@angular/core';
3
+ import * as i1 from '@angular/common';
8
4
  import { CommonModule } from '@angular/common';
9
- import * as i2$1 from '@angular/material/form-field';
10
- import { MatFormFieldModule } from '@angular/material/form-field';
11
- import * as i4 from '@angular/material/icon';
12
- import { MatIconModule } from '@angular/material/icon';
13
- import * as i3 from '@angular/material/tooltip';
14
- import { MatTooltipModule } from '@angular/material/tooltip';
15
- import * as i5 from '@tft/form-validation-handler';
5
+ import * as i2 from '@angular/forms';
6
+ import { FormGroup, ReactiveFormsModule } from '@angular/forms';
7
+ import * as i3$1 from '@tft/form-validation-handler';
16
8
  import { FormValidationHandlerModule } from '@tft/form-validation-handler';
17
- import * as i7 from '@angular/material/input';
18
- import { MatInputModule } from '@angular/material/input';
19
- import * as i3$1 from '@angular/material/select';
20
- import { MatSelectModule } from '@angular/material/select';
21
- import * as i4$2 from '@angular/material/checkbox';
22
- import { MatCheckboxModule } from '@angular/material/checkbox';
23
- import * as i5$1 from '@angular/material/core';
24
- import * as i4$3 from '@angular/material/autocomplete';
25
- import { MatAutocompleteTrigger, MatAutocompleteModule } from '@angular/material/autocomplete';
26
- import { ENTER } from '@angular/cdk/keycodes';
27
- import * as i3$2 from '@angular/material/chips';
28
- import { MatChipsModule } from '@angular/material/chips';
29
- import * as i3$3 from '@angular/material/slider';
30
- import { MatSliderModule } from '@angular/material/slider';
31
- import * as i1 from '@angular/material/button';
9
+ import 'rxjs';
10
+ import { isControlConfig, ControlType, buildFormGroupFromConfig, crisprControlMixin, CrisprFieldComponent, createControlForType } from '@tft/crispr-forms/utils';
11
+ export * from '@tft/crispr-forms/utils';
12
+ import * as i2$1 from '@angular/material/button';
32
13
  import { MatButtonModule } from '@angular/material/button';
33
- import * as i8 from '@angular/cdk/portal';
34
- import { ComponentPortal, PortalModule } from '@angular/cdk/portal';
35
- import * as i3$4 from '@angular/material/datepicker';
36
- import { MatDatepickerModule } from '@angular/material/datepicker';
37
- import * as i1$1 from '@angular/material/divider';
38
- import { MatDividerModule } from '@angular/material/divider';
39
- import * as i2$2 from '@angular/material/radio';
40
- import { MatRadioModule } from '@angular/material/radio';
41
- import * as i2$3 from '@angular/platform-browser';
42
- import imageCompression from 'browser-image-compression';
43
- import * as i1$2 from '@angular/material/progress-bar';
44
- import { MatProgressBarModule } from '@angular/material/progress-bar';
45
- import { MatButtonToggleModule } from '@angular/material/button-toggle';
46
- import { MatSlideToggleModule } from '@angular/material/slide-toggle';
47
- import { MatMomentDateModule } from '@angular/material-moment-adapter';
48
-
49
- const DEFAULT_EMPTY_OPTIONS_MESSAGE = 'No Items';
50
-
51
- // export type ControlType = keyof typeof FIELD_COMPONENTS;
52
- var ControlType;
53
- (function (ControlType) {
54
- ControlType["AUTOCOMPLETE"] = "autocomplete";
55
- ControlType["AUTOCOMPLETE_CHIPLIST"] = "autocompleteChiplist";
56
- ControlType["BUTTON"] = "button";
57
- ControlType["CHECKBOX"] = "checkbox";
58
- ControlType["CUSTOM"] = "custom";
59
- ControlType["DATEPICKER"] = "datepicker";
60
- ControlType["DIVIDER"] = "divider";
61
- ControlType["FILE_UPLOAD"] = "fileUpload";
62
- ControlType["HEADING"] = "heading";
63
- ControlType["INPUT"] = "input";
64
- ControlType["IMAGE_UPLOAD"] = "imageUpload";
65
- ControlType["GROUP_LIST"] = "groupList";
66
- ControlType["RADIO"] = "radio";
67
- ControlType["SELECT"] = "select";
68
- ControlType["SLIDER"] = "slider";
69
- ControlType["SUB_GROUP"] = "subGroup";
70
- ControlType["TEXTAREA"] = "textarea";
71
- ControlType["UNIT_CONVERSION"] = "unitConversion";
72
- })(ControlType || (ControlType = {}));
73
-
74
- ;
75
-
76
- function valueIn(values) {
77
- return map((value) => {
78
- if (value) {
79
- return values.some(v => {
80
- if (isRegex(v)) {
81
- const trimmedStringForRegex = v.substr(1, v.length - 2);
82
- const regex = new RegExp(trimmedStringForRegex);
83
- return regex.test(value);
84
- }
85
- else {
86
- return v === value;
87
- }
88
- });
89
- }
90
- else {
91
- return false;
92
- }
93
- });
94
- }
95
- function isRegex(string) {
96
- return string.startsWith('/') && string.endsWith('/');
97
- }
98
-
99
- /**
100
- * Watches a single control for a list of values, returns true when field value matches any value in list
101
- * unless an evaluate method is found on config, in which case that method is run on the returned boolean value
102
- * @param group the direct parent of the field we want to watch
103
- * @param config
104
- */
105
- function checkControlForValues(group, config) {
106
- // check that all the pieces we need are available
107
- if (config && config.controlName && Array.isArray(config.values)) {
108
- return getValueChanges(group, config.controlName).pipe(
109
- // return a boolean, true if value is in the values being watch for, otherwise false
110
- valueIn(config.values), map((isValueInValues) => {
111
- // since we can only check if the value is in the list of watched values, the evaluate function gives us
112
- // a chance to make other decisions based on if the boolean returned, e.g. return true if value not in watched values
113
- if (config.evaluate && config.evaluate instanceof Function) {
114
- return config.evaluate(isValueInValues);
115
- }
116
- else {
117
- return isValueInValues;
118
- }
119
- }));
120
- }
121
- else {
122
- //
123
- return of(true);
124
- }
125
- }
126
- /**
127
- * Watches a list of fields for individual lists of values returning true when any field contains one
128
- * of the values being watched for, or optionally running a function on the array of resolved booleans
129
- * from the listed fields and returning a boolean
130
- * @param group the form group that has the fields to watch as direct descendants
131
- * @param config the configuration to use when calling the function
132
- */
133
- function checkControlsForValues(group, config) {
134
- // if no config is passed we just want to show the field, so we return an observable of true
135
- if (!config || !config.watchConfigs) {
136
- return of(true);
137
- }
138
- // we run checkControlForValues on every control in the list of WatchConfigs creating
139
- // an array of Observable watching fields for values
140
- const fieldTriggers = config.watchConfigs.map(watchConfig => {
141
- // resolves a boolean, true when field value matches a watched value, otherwise false
142
- return checkControlForValues(group, watchConfig);
143
- });
144
- return combineLatest(fieldTriggers).pipe(startWith([true]), map((booleans) => {
145
- // if the user passed an evaluate function use it
146
- if (config.evaluate && config.evaluate instanceof Function) {
147
- return config.evaluate(booleans);
148
- }
149
- else { // otherwise we return true if any of the watched fields resolve to true
150
- return booleans.some(bool => bool);
151
- }
152
- }));
153
- }
154
- /**
155
- * Watches values on an array of fields, computing their values as they change
156
- * @param group the group to get the fields from, for now it can only be the parent of the computed field
157
- * @param computeFieldsConfig the configuration that drives the computation, holds the names to watch and the
158
- * computation function that get called against the array of values
159
- */
160
- function computeValueFromFields(group, computeFieldsConfig) {
161
- // TODO: better checking
162
- const { controlNamesToWatch } = computeFieldsConfig;
163
- //creates an observable listener for each control in the controlNamesToWatch array
164
- return combineLatest(controlNamesToWatch.map(controlNameToWatch => getValueChanges(group, controlNameToWatch))).pipe(
165
- // each time a watched field values changes a new array of the latest field values is pipe through to the
166
- // compute callback. Which runs the users logic on the values to compute this fields value
167
- map(valuesArray => computeFieldsConfig.computeCallback(valuesArray)));
168
- }
169
- /**
170
- * A simple wrapper for doing error checking around getting the valueChanges observable from a control on a form group
171
- * @param group the form group we want to pull the observable from
172
- * @param controlName the name of the control who's value we want to subscribe to
173
- */
174
- function getValueChanges(group, controlName) {
175
- const control = group.get(controlName);
176
- if (!control) {
177
- throw new Error(`No control with controlName ${controlName}`);
178
- }
179
- return control.valueChanges;
180
- }
181
- /**
182
- * TODO: move to utils library after library is built
183
- * Allows developer to pass an array of operators into the pipe of an Observable.
184
- * Useful for creating function with a variable amount of operators to be run
185
- * @param observable the observable to pass the operators to
186
- * @param operators array of operators to pipe
187
- */
188
- function pipeOperatorsIntoObservable(observable, operators) {
189
- try {
190
- return operators.reduce((obs, op) => {
191
- return obs.pipe(op);
192
- }, observable);
193
- }
194
- catch {
195
- console.error('Unable to pipe operators into observable');
196
- return of(null);
197
- }
198
- }
199
- function callOptionsIfFunction(options, parentGroup, searchString) {
200
- return options instanceof Function ? options(parentGroup, searchString) : options;
201
- }
202
- /**
203
- * The user can give us select options as an array, a function that resolves to a promise,
204
- * or an observable. This functions consumes any of those and returns an observable that
205
- * resolves an array of options
206
- *
207
- * @param options the options passed in from the config
208
- * @param emptyMessageOption the message to display when the array is empty
209
- */
210
- function observablifyOptions(options, parentGroup, searchString) {
211
- const calledOptions = callOptionsIfFunction(options, parentGroup, searchString);
212
- // if options are a promise
213
- const observableOptions = calledOptions instanceof Promise
214
- // convert to observable
215
- ? from(calledOptions)
216
- // if array that isn't empty
217
- : Array.isArray(calledOptions) && calledOptions.length
218
- // convert to observable
219
- ? of(calledOptions)
220
- // if observable
221
- : isObservable(calledOptions)
222
- // return it
223
- ? calledOptions
224
- // else an empty array
225
- : of([]);
226
- return observableOptions;
227
- }
228
- /**
229
- * Determines if the field config is for a form control (not a divider, heading or other non-control field)
230
- * */
231
- function isControlConfig(fieldConfig) {
232
- return 'controlName' in fieldConfig;
233
- }
234
- /**
235
- * builds out form group based on config
236
- * @param config a configuration for a form group
237
- * @param value an object of initial values to pass in
238
- * @param group the form group to modify and build out
239
- */
240
- function buildFormGroupFromConfig(config, value = null, group = new FormGroup({})) {
241
- config.fields.forEach((controlConfig) => {
242
- if (isControlConfig(controlConfig)) {
243
- // then add a control to the group using the controlName from configuration
244
- const { controlName } = controlConfig;
245
- if (group.get(controlName)) {
246
- group.removeControl(controlName);
247
- }
248
- // if there's a value object and it has a non-null/undefined value for this field use it.
249
- // Otherwise, default to null
250
- const controlValue = (value && value[controlName]) ?? null;
251
- const control = createControlForType(controlConfig, controlValue);
252
- group.addControl(controlName, control);
253
- }
254
- });
255
- group.setValidators(config.validators);
256
- return group;
257
- }
258
- /**
259
- * Analyze the config and build a form control to spec. Notice we don't use FormBuilder here
260
- * as we want to keep this function pure.
261
- * @param controlConfig the configuration object for the control to build
262
- * @param value an initial value to use if passed in
263
- */
264
- function createControlForType(controlConfig, value = null) {
265
- // build form control out based on the control type
266
- const control = controlConfig.controlType === ControlType.SUB_GROUP
267
- ? buildFormGroupFromConfig(controlConfig, value)
268
- : controlConfig.controlType === ControlType.GROUP_LIST
269
- ? new FormArray([], controlConfig.validators)
270
- : new FormControl(value || null, controlConfig.validators);
271
- return control;
272
- }
273
- /**
274
- * A basic filter function that filters the search string against the label of the options object
275
- * @param options the array of options to filter
276
- * @param searchString the string from the input
277
- */
278
- function filterOptionsByLabel(options, searchString) {
279
- return options.filter(option => {
280
- return option.label && option.label.toLowerCase().includes(searchString.toLowerCase());
281
- });
282
- }
283
-
284
- function crisprControlMixin(BaseClass) {
285
- return class extends BaseClass {
286
- set value(value) {
287
- this.setControlValue(value);
288
- this._value = value;
289
- }
290
- get value() {
291
- return this._value;
292
- }
293
- ngOnInit() {
294
- super.ngOnInit();
295
- this.control = this.group.get(this.config.controlName);
296
- this.setControlValue(this.value);
297
- // setTimeouts are ugly but this seems to be the only way to get the computed field to compute initial values
298
- setTimeout(() => {
299
- this.control.updateValueAndValidity();
300
- });
301
- }
302
- setControlValue(value) {
303
- if (value && this.control && this.config.controlType !== ControlType.SUB_GROUP) {
304
- this.control.setValue(value);
305
- }
306
- }
307
- };
308
- }
309
-
310
- // eslint-disable-next-line @angular-eslint/directive-class-suffix
311
- class CrisprFieldComponent {
312
- ngOnInit() {
313
- this.applyDefaultConfig();
314
- }
315
- applyDefaultConfig() {
316
- this.config = this.defaultConfig ? { ...this.defaultConfig, ...this.config } : this.config;
317
- }
318
- }
319
- CrisprFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CrisprFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
320
- CrisprFieldComponent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.2.1", type: CrisprFieldComponent, ngImport: i0 });
321
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CrisprFieldComponent, decorators: [{
322
- type: Directive
323
- }] });
324
-
325
- const AbstractAutocompleteFieldMixin = crisprControlMixin(CrisprFieldComponent);
326
- // eslint-disable-next-line @angular-eslint/directive-class-suffix
327
- class AbstractAutocompleteComponent extends AbstractAutocompleteFieldMixin {
328
- constructor() {
329
- super(...arguments);
330
- // we need a separate control for the UI because of the way the material autocomplete chiplist works
331
- this.autocompleteInputControl = new FormControl('');
332
- }
333
- ngOnInit() {
334
- super.ngOnInit();
335
- this.group.addControl(this.config.controlName, new FormControl());
336
- // filter options by the search string using either the default filter function or one passed in through config
337
- this.options$ = this.autocompleteInputControl.valueChanges.pipe(
338
- // this is needed to have the options panel to open on focus
339
- startWith(''), debounceTime(this.config.typeDebounceTime), map((searchText) => typeof searchText === 'string' ? searchText?.trim() : ''), distinctUntilChanged(), switchMap((searchText) => observablifyOptions(this.config.options, this.group, searchText)), shareReplay(1));
340
- }
341
- }
342
- AbstractAutocompleteComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: AbstractAutocompleteComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive });
343
- AbstractAutocompleteComponent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.2.1", type: AbstractAutocompleteComponent, usesInheritance: true, ngImport: i0 });
344
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: AbstractAutocompleteComponent, decorators: [{
345
- type: Directive
346
- }] });
347
-
348
- class InfoComponent {
349
- }
350
- InfoComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: InfoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
351
- InfoComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: InfoComponent, selector: "crispr-info", inputs: { info: "info" }, ngImport: i0, template: "<mat-icon\n *ngIf=\"info\"\n [matTooltip]=\"info.content\"\n [matTooltipPosition]=\"info.tooltipPosition || 'below'\"\n matSuffix>\n info\n</mat-icon>\n", styles: [":host mat-icon{font-size:1.2em;width:1em;height:1em;opacity:.8;margin-right:0}\n"], components: [{ type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true });
352
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: InfoComponent, decorators: [{
353
- type: Component,
354
- args: [{ selector: 'crispr-info', changeDetection: ChangeDetectionStrategy.OnPush, template: "<mat-icon\n *ngIf=\"info\"\n [matTooltip]=\"info.content\"\n [matTooltipPosition]=\"info.tooltipPosition || 'below'\"\n matSuffix>\n info\n</mat-icon>\n", styles: [":host mat-icon{font-size:1.2em;width:1em;height:1em;opacity:.8;margin-right:0}\n"] }]
355
- }], propDecorators: { info: [{
356
- type: Input
357
- }] } });
358
- class InfoModule {
359
- }
360
- InfoModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: InfoModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
361
- InfoModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: InfoModule, declarations: [InfoComponent], imports: [CommonModule,
362
- MatIconModule,
363
- MatTooltipModule], exports: [InfoComponent] });
364
- InfoModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: InfoModule, imports: [[
365
- CommonModule,
366
- MatIconModule,
367
- MatTooltipModule
368
- ]] });
369
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: InfoModule, decorators: [{
370
- type: NgModule,
371
- args: [{
372
- imports: [
373
- CommonModule,
374
- MatIconModule,
375
- MatTooltipModule
376
- ],
377
- exports: [
378
- InfoComponent
379
- ],
380
- declarations: [
381
- InfoComponent
382
- ]
383
- }]
384
- }] });
385
-
386
- const defaultConfig$8 = {
387
- typographyClass: 'mat-h3'
388
- };
389
- class HeadingComponent extends CrisprFieldComponent {
390
- constructor() {
391
- super(...arguments);
392
- this.defaultConfig = defaultConfig$8;
393
- }
394
- }
395
- HeadingComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: HeadingComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
396
- HeadingComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: HeadingComponent, selector: "crispr-heading", inputs: { config: "config" }, usesInheritance: true, ngImport: i0, template: " <label\n *ngIf=\"!!config?.label\"\n [ngClass]=\"config.typographyClass\">\n {{ config.label }}\n <crispr-info\n *ngIf=\"config.info\"\n matSuffix\n [info]=\"config.info\">\n </crispr-info>\n </label>\n", styles: [":host{display:block}\n"], components: [{ type: InfoComponent, selector: "crispr-info", inputs: ["info"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2$1.MatSuffix, selector: "[matSuffix]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true });
397
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: HeadingComponent, decorators: [{
398
- type: Component,
399
- args: [{ selector: 'crispr-heading', changeDetection: ChangeDetectionStrategy.OnPush, template: " <label\n *ngIf=\"!!config?.label\"\n [ngClass]=\"config.typographyClass\">\n {{ config.label }}\n <crispr-info\n *ngIf=\"config.info\"\n matSuffix\n [info]=\"config.info\">\n </crispr-info>\n </label>\n", styles: [":host{display:block}\n"] }]
400
- }], propDecorators: { config: [{
401
- type: Input
402
- }] } });
403
- class HeadingModule {
404
- }
405
- HeadingModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: HeadingModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
406
- HeadingModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: HeadingModule, declarations: [HeadingComponent], imports: [CommonModule,
407
- MatFormFieldModule,
408
- InfoModule], exports: [HeadingComponent] });
409
- HeadingModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: HeadingModule, imports: [[
410
- CommonModule,
411
- MatFormFieldModule,
412
- InfoModule
413
- ]] });
414
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: HeadingModule, decorators: [{
415
- type: NgModule,
416
- args: [{
417
- imports: [
418
- CommonModule,
419
- MatFormFieldModule,
420
- InfoModule
421
- ],
422
- exports: [
423
- HeadingComponent
424
- ],
425
- declarations: [
426
- HeadingComponent
427
- ]
428
- }]
429
- }] });
430
-
431
- class FieldContainerComponent {
432
- constructor() {
433
- // boolean whether field-container is inline
434
- this.inlineField = false;
435
- this.subs = [];
436
- }
437
- ngOnInit() {
438
- this.disabled$ = this.connectDisabledCallback(this.group, this.config);
439
- // we tried moving this into afterViewChecked and afterContentChecked lifecycle hooks without any luck
440
- if (this.config.computeValue) {
441
- this.subs.push(this.config.computeValue(this.group).pipe(distinctUntilChanged(), tap(computedValue => this.group.get(this.config.controlName).setValue(computedValue))).subscribe());
442
- }
443
- else if (this.config.computeFieldConfig) {
444
- console.warn(`computeFieldConfig property is deprecated, please use computeValue. Example here: https://stackblitz.com/github/nayfin/tft-documentation?file=src%2Fapp%2Fcrispr-forms-demo%2Ffeatures%2Fcomputed-field%2Fcomputed-field.component.ts`);
445
- this.subs.push(computeValueFromFields(this.group, this.config.computeFieldConfig).pipe(distinctUntilChanged(), tap(computedValue => this.group.get(this.config.controlName).setValue(computedValue))).subscribe());
446
- }
447
- }
448
- ngOnDestroy() {
449
- this.subs.forEach(sub => sub.unsubscribe);
450
- }
451
- /**
452
- * Connects user defined disabledCallback function to the the view, so that the control is enabled/disabled
453
- * appropriately. It also keeps the form will hide disabled fields in the UI unless `hideDisabled` is set to
454
- * false in the controls config
455
- * @param group used to get valueChanges from control
456
- * @param config configuration object used to
457
- */
458
- connectDisabledCallback(group, config = null) {
459
- const control = group.get(config.controlName);
460
- // If the disabled$ function exists on the field config then call it with the disabledCallbackConfig
461
- // as a parameter otherwise return an observable of true.
462
- return config?.disabledCallback && config.disabledCallback instanceof Function
463
- ? config.disabledCallback(group, config.disabledCallbackConfig || null).pipe(
464
- // This enables/disables when callback conditions are met
465
- tap((shouldDisable) => shouldDisable ? control.disable() : control.enable()))
466
- : of(false);
467
- }
468
- }
469
- FieldContainerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: FieldContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
470
- FieldContainerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: FieldContainerComponent, selector: "crispr-field-container", inputs: { config: "config", group: "group", inlineField: "inlineField" }, ngImport: i0, template: "<div\n *ngIf=\"(disabled$ | async) ? !config.hideDisabled : true\"\n [ngClass]=\"config.classes\"\n [class.inline-field]=\"inlineField\"\n class=\"field-container\">\n\n <crispr-heading\n *ngIf=\"config.heading\"\n [config]=\"config.heading\">\n </crispr-heading>\n\n <ng-content>\n </ng-content>\n\n</div>\n", styles: ["::ng-deep mat-form-field.mat-form-field{display:block;padding:.25em 0}.inline-field{display:inline-block}\n"], components: [{ type: HeadingComponent, selector: "crispr-heading", inputs: ["config"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], pipes: { "async": i2.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true });
471
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: FieldContainerComponent, decorators: [{
472
- type: Component,
473
- args: [{ selector: 'crispr-field-container', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n *ngIf=\"(disabled$ | async) ? !config.hideDisabled : true\"\n [ngClass]=\"config.classes\"\n [class.inline-field]=\"inlineField\"\n class=\"field-container\">\n\n <crispr-heading\n *ngIf=\"config.heading\"\n [config]=\"config.heading\">\n </crispr-heading>\n\n <ng-content>\n </ng-content>\n\n</div>\n", styles: ["::ng-deep mat-form-field.mat-form-field{display:block;padding:.25em 0}.inline-field{display:inline-block}\n"] }]
474
- }], propDecorators: { config: [{
475
- type: Input
476
- }], group: [{
477
- type: Input
478
- }], inlineField: [{
479
- type: Input
480
- }] } });
481
- class FieldContainerModule {
482
- }
483
- FieldContainerModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: FieldContainerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
484
- FieldContainerModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: FieldContainerModule, declarations: [FieldContainerComponent], imports: [CommonModule,
485
- HeadingModule], exports: [FieldContainerComponent] });
486
- FieldContainerModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: FieldContainerModule, imports: [[
487
- CommonModule,
488
- HeadingModule,
489
- ]] });
490
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: FieldContainerModule, decorators: [{
491
- type: NgModule,
492
- args: [{
493
- imports: [
494
- CommonModule,
495
- HeadingModule,
496
- ],
497
- exports: [
498
- FieldContainerComponent
499
- ],
500
- declarations: [
501
- FieldContainerComponent
502
- ]
503
- }]
504
- }] });
505
-
506
- const InputFieldMixin = crisprControlMixin(CrisprFieldComponent);
507
- class InputFieldComponent extends InputFieldMixin {
508
- constructor() {
509
- super();
510
- this.defaultConfig = { inputType: 'text' };
511
- }
512
- ngOnInit() {
513
- super.ngOnInit();
514
- }
515
- }
516
- InputFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: InputFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
517
- InputFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: InputFieldComponent, selector: "crispr-input-field", usesInheritance: true, ngImport: i0, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n <mat-form-field\n [color]=\"config.color\"\n [appearance]=\"config.appearance\"\n [formGroup]=\"group\">\n <mat-label>\n {{config.label}}\n </mat-label>\n <input\n [type]=\"config.inputType\"\n matInput\n [placeholder]=\"config.placeholder\"\n [formControlName]=\"config.controlName\"\n [min]=\"config.min\"\n [max]=\"config.max\"\n [maxlength]=\"config.maxLength\"\n [step]=\"config.step\"\n [autofocus]=\"config.autofocus\"\n [pattern]=\"config.pattern\"\n [spellcheck]=\"config.spellcheck\"\n [autocomplete]=\"config.autoComplete\"\n [autocapitalize]=\"config.autoCapitalize\">\n <span *ngIf=\"config.fieldSuffix\" matSuffix>{{config.fieldSuffix}}</span>\n <crispr-info\n matSuffix\n *ngIf=\"config.info\"\n [info]=\"config.info\">\n </crispr-info>\n\n <mat-hint *ngIf=\"config.hint && (control.valid || !control.touched)\">{{config.hint}}</mat-hint>\n\n </mat-form-field>\n\n\n</crispr-field-container>\n", styles: [""], components: [{ type: FieldContainerComponent, selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }, { type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: InfoComponent, selector: "crispr-info", inputs: ["info"] }], directives: [{ type: i4$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i4$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5.ControlErrorContainerDirective, selector: "[controlErrorContainer], [formGroup]" }, { type: i2$1.MatLabel, selector: "mat-label" }, { type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i4$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i4$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i5.ControlErrorsDirective, selector: "[formControl], [formControlName]" }, { type: i4$1.MaxLengthValidator, selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]", inputs: ["maxlength"] }, { type: i4$1.PatternValidator, selector: "[pattern][formControlName],[pattern][formControl],[pattern][ngModel]", inputs: ["pattern"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2$1.MatSuffix, selector: "[matSuffix]" }, { type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true });
518
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: InputFieldComponent, decorators: [{
519
- type: Component,
520
- args: [{ selector: 'crispr-input-field', changeDetection: ChangeDetectionStrategy.OnPush, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n <mat-form-field\n [color]=\"config.color\"\n [appearance]=\"config.appearance\"\n [formGroup]=\"group\">\n <mat-label>\n {{config.label}}\n </mat-label>\n <input\n [type]=\"config.inputType\"\n matInput\n [placeholder]=\"config.placeholder\"\n [formControlName]=\"config.controlName\"\n [min]=\"config.min\"\n [max]=\"config.max\"\n [maxlength]=\"config.maxLength\"\n [step]=\"config.step\"\n [autofocus]=\"config.autofocus\"\n [pattern]=\"config.pattern\"\n [spellcheck]=\"config.spellcheck\"\n [autocomplete]=\"config.autoComplete\"\n [autocapitalize]=\"config.autoCapitalize\">\n <span *ngIf=\"config.fieldSuffix\" matSuffix>{{config.fieldSuffix}}</span>\n <crispr-info\n matSuffix\n *ngIf=\"config.info\"\n [info]=\"config.info\">\n </crispr-info>\n\n <mat-hint *ngIf=\"config.hint && (control.valid || !control.touched)\">{{config.hint}}</mat-hint>\n\n </mat-form-field>\n\n\n</crispr-field-container>\n", styles: [""] }]
521
- }], ctorParameters: function () { return []; } });
522
-
523
- class OptionComponent {
524
- }
525
- OptionComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: OptionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
526
- OptionComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: OptionComponent, selector: "crispr-option", inputs: { option: "option" }, ngImport: i0, template: "<div>\n <img\n *ngIf=\"option.imageUrl\"\n [src]=\"option.imageUrl\"\n alt=\"image of {{option.label}}\"\n style=\"vertical-align:middle;\"\n aria-hidden\n height=\"25\"/>\n {{option.label}}\n</div>\n\n<crispr-info *ngIf=\"option.info as info\" [info]=\"info\">\n\n</crispr-info>\n", styles: [":host{display:flex;justify-content:space-between}:host img{margin-right:4px}\n"], components: [{ type: InfoComponent, selector: "crispr-info", inputs: ["info"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true });
527
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: OptionComponent, decorators: [{
528
- type: Component,
529
- args: [{ selector: 'crispr-option', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div>\n <img\n *ngIf=\"option.imageUrl\"\n [src]=\"option.imageUrl\"\n alt=\"image of {{option.label}}\"\n style=\"vertical-align:middle;\"\n aria-hidden\n height=\"25\"/>\n {{option.label}}\n</div>\n\n<crispr-info *ngIf=\"option.info as info\" [info]=\"info\">\n\n</crispr-info>\n", styles: [":host{display:flex;justify-content:space-between}:host img{margin-right:4px}\n"] }]
530
- }], propDecorators: { option: [{
531
- type: Input
532
- }] } });
533
-
534
- const SelectFieldMixin = crisprControlMixin(CrisprFieldComponent);
535
- class SelectFieldComponent extends SelectFieldMixin {
536
- constructor() {
537
- super(...arguments);
538
- this.defaultConfig = {
539
- enableToggleAll: false,
540
- color: 'primary'
541
- };
542
- this.allSelected = false;
543
- }
544
- ngOnInit() {
545
- super.ngOnInit();
546
- // options$ can be passed as an array, promise that resolves array, or observable that resolves array
547
- // this functions accounts for all possibilities and converts to observable that resolves array
548
- this.options$ = observablifyOptions(this.config.options, this.group);
549
- }
550
- ngAfterViewInit() {
551
- if (this.config.multiple
552
- && this.config.enableToggleAll
553
- && this.selectField.options?.length === this.value?.length) {
554
- this.allSelected = true;
555
- }
556
- }
557
- toggleAll(isSelected) {
558
- if (isSelected) {
559
- this.selectField.options.forEach(option => option.deselect());
560
- }
561
- else {
562
- this.selectField.options.forEach(option => option.select());
563
- }
564
- this.allSelected = !this.allSelected;
565
- }
566
- }
567
- SelectFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: SelectFieldComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
568
- SelectFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: SelectFieldComponent, selector: "crispr-select-field", viewQueries: [{ propertyName: "selectField", first: true, predicate: ["selectField"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n\n <mat-form-field\n [color]=\"config.color\"\n [appearance]=\"config.appearance\"\n [formGroup]=\"group\">\n <mat-label *ngIf=\"config.label\">\n {{config.label}}\n </mat-label>\n <mat-select\n #selectField\n [formControlName]=\"config.controlName\"\n [placeholder]=\"config.placeholder\"\n [multiple]=\"config.multiple\">\n\n <mat-checkbox\n [color]=\"config.color\"\n [checked]=\"allSelected\"\n *ngIf=\"config?.multiple && config.enableToggleAll\"\n (click)=\"toggleAll(allSelected)\">\n Select All\n </mat-checkbox>\n <mat-option\n *ngFor=\"let option of options$ | async\"\n [value]=\"option.value\">\n <crispr-option [option]=\"option\">\n </crispr-option>\n </mat-option>\n\n </mat-select>\n\n <span *ngIf=\"config.fieldSuffix\" matSuffix>{{config.fieldSuffix}}</span>\n <crispr-info\n *ngIf=\"config.info\"\n matSuffix\n [info]=\"config.info\">\n </crispr-info>\n\n <mat-hint *ngIf=\"config.hint && (control.valid || !control.touched)\">{{config.hint}}</mat-hint>\n\n </mat-form-field>\n\n</crispr-field-container>\n", styles: ["mat-checkbox{display:block;padding:16px}\n"], components: [{ type: FieldContainerComponent, selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }, { type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i3$1.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i4$2.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex", "aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { type: i5$1.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { type: OptionComponent, selector: "crispr-option", inputs: ["option"] }, { type: InfoComponent, selector: "crispr-info", inputs: ["info"] }], directives: [{ type: i4$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i4$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5.ControlErrorContainerDirective, selector: "[controlErrorContainer], [formGroup]" }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2$1.MatLabel, selector: "mat-label" }, { type: i4$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i5.ControlErrorsDirective, selector: "[formControl], [formControlName]" }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2$1.MatSuffix, selector: "[matSuffix]" }, { type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }], pipes: { "async": i2.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true });
569
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: SelectFieldComponent, decorators: [{
570
- type: Component,
571
- args: [{ selector: 'crispr-select-field', changeDetection: ChangeDetectionStrategy.OnPush, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n\n <mat-form-field\n [color]=\"config.color\"\n [appearance]=\"config.appearance\"\n [formGroup]=\"group\">\n <mat-label *ngIf=\"config.label\">\n {{config.label}}\n </mat-label>\n <mat-select\n #selectField\n [formControlName]=\"config.controlName\"\n [placeholder]=\"config.placeholder\"\n [multiple]=\"config.multiple\">\n\n <mat-checkbox\n [color]=\"config.color\"\n [checked]=\"allSelected\"\n *ngIf=\"config?.multiple && config.enableToggleAll\"\n (click)=\"toggleAll(allSelected)\">\n Select All\n </mat-checkbox>\n <mat-option\n *ngFor=\"let option of options$ | async\"\n [value]=\"option.value\">\n <crispr-option [option]=\"option\">\n </crispr-option>\n </mat-option>\n\n </mat-select>\n\n <span *ngIf=\"config.fieldSuffix\" matSuffix>{{config.fieldSuffix}}</span>\n <crispr-info\n *ngIf=\"config.info\"\n matSuffix\n [info]=\"config.info\">\n </crispr-info>\n\n <mat-hint *ngIf=\"config.hint && (control.valid || !control.touched)\">{{config.hint}}</mat-hint>\n\n </mat-form-field>\n\n</crispr-field-container>\n", styles: ["mat-checkbox{display:block;padding:16px}\n"] }]
572
- }], propDecorators: { selectField: [{
573
- type: ViewChild,
574
- args: ['selectField']
575
- }] } });
576
-
577
- const defaultConfig$7 = {
578
- autoActiveFirstOption: true,
579
- typeDebounceTime: 500,
580
- emptyOptionsMessage: DEFAULT_EMPTY_OPTIONS_MESSAGE
581
- };
582
- class AutocompleteFieldComponent extends AbstractAutocompleteComponent {
583
- constructor() {
584
- super(...arguments);
585
- this.defaultConfig = defaultConfig$7;
586
- }
587
- ngOnInit() {
588
- super.ngOnInit();
589
- this.clearFieldSubscription = this.autocompleteInputControl.valueChanges.subscribe((text) => {
590
- if (typeof text === 'string' && text?.trim() === '') {
591
- this.control.setValue(null);
592
- }
593
- });
594
- }
595
- ngOnDestroy() {
596
- this.clearFieldSubscription.unsubscribe();
597
- }
598
- setControlValue(value) {
599
- if (this.control && value) {
600
- // sets the initial value on the control if one is passed
601
- this.control.setValue(value.value || '');
602
- this.autocompleteInputControl.setValue(value.label || '');
603
- }
604
- }
605
- /**
606
- * The material autocomplete defaults to displaying the options value instead of its label.
607
- * We only have the value from the selected option to work with, so we have to pass the options
608
- * through a function called in the template and return the function that the material displayWith
609
- * input is expecting.
610
- * @param options the array of options to search for option with corresponding value
611
- */
612
- displayLabel(options) {
613
- if (this.config.displayWith) {
614
- return this.config.displayWith(options);
615
- }
616
- return (value) => {
617
- const label = !!options && Array.isArray(options)
618
- ? options.find((option) => JSON.stringify(option.value) === JSON.stringify(value))?.label : value;
619
- return label;
620
- };
621
- }
622
- handleSelect(event) {
623
- this.control.setValue(event.option.value);
624
- this.autoInputRef.nativeElement.blur();
625
- }
626
- }
627
- AutocompleteFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: AutocompleteFieldComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
628
- AutocompleteFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: AutocompleteFieldComponent, selector: "crispr-autocomplete-field", viewQueries: [{ propertyName: "autoInput", first: true, predicate: ["autoInput"], descendants: true, read: MatAutocompleteTrigger }, { propertyName: "autoInputRef", first: true, predicate: ["autoInput"], descendants: true }], usesInheritance: true, ngImport: i0, template: "\n<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n\n <mat-form-field\n [color]=\"config.color\"\n [appearance]=\"config.appearance\"\n [formGroup]=\"group\">\n <mat-label *ngIf=\"config.label\">\n {{config.label}}\n </mat-label>\n\n <input class=\"hidden-error-directive-anchor\" [formControlName]=\"config.controlName\" type=\"text\"/>\n\n <input\n matInput\n [formControl]=\"autocompleteInputControl\"\n [placeholder]=\"config.placeholder\"\n [matAutocomplete]=\"auto\"\n role=\"textbox\"\n type=\"textbox\"\n autocapitalize=\"off\"\n autocorrect=\"off\"\n spellcheck=\"false\"\n #autoInput>\n\n <span *ngIf=\"config.fieldSuffix\" matSuffix>{{config.fieldSuffix}}</span>\n <crispr-info\n *ngIf=\"config.info\"\n matSuffix\n [info]=\"config.info \">\n </crispr-info>\n\n <mat-autocomplete\n #auto=\"matAutocomplete\"\n [autoActiveFirstOption]=\"config.autoActiveFirstOption\"\n (optionSelected)=\"handleSelect($event)\"\n [displayWith]=\"displayLabel(options$ | async)\">\n\n <ng-container *ngIf=\"options$ | async as options; else emptyOption\">\n <ng-container *ngIf=\"options.length > 0; else emptyOption\">\n <mat-option\n *ngFor=\"let option of options\"\n [value]=\"option.value\">\n <crispr-option [option]=\"option\"></crispr-option>\n </mat-option>\n </ng-container>\n\n </ng-container>\n <ng-template #emptyOption>\n <mat-option disabled=\"true\">\n {{config.emptyOptionsMessage}}\n </mat-option>\n </ng-template>\n\n </mat-autocomplete>\n\n <mat-hint *ngIf=\"config.hint && (control.valid || !control.touched)\">{{config.hint}}</mat-hint>\n\n </mat-form-field>\n</crispr-field-container>\n", styles: [".hidden-error-directive-anchor{display:none}\n"], components: [{ type: FieldContainerComponent, selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }, { type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: InfoComponent, selector: "crispr-info", inputs: ["info"] }, { type: i4$3.MatAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple"], exportAs: ["matAutocomplete"] }, { type: i5$1.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { type: OptionComponent, selector: "crispr-option", inputs: ["option"] }], directives: [{ type: i4$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i4$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5.ControlErrorContainerDirective, selector: "[controlErrorContainer], [formGroup]" }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2$1.MatLabel, selector: "mat-label" }, { type: i4$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i4$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i5.ControlErrorsDirective, selector: "[formControl], [formControlName]" }, { type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i4$3.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { type: i4$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { type: i2$1.MatSuffix, selector: "[matSuffix]" }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }], pipes: { "async": i2.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true });
629
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: AutocompleteFieldComponent, decorators: [{
630
- type: Component,
631
- args: [{ selector: 'crispr-autocomplete-field', changeDetection: ChangeDetectionStrategy.OnPush, template: "\n<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n\n <mat-form-field\n [color]=\"config.color\"\n [appearance]=\"config.appearance\"\n [formGroup]=\"group\">\n <mat-label *ngIf=\"config.label\">\n {{config.label}}\n </mat-label>\n\n <input class=\"hidden-error-directive-anchor\" [formControlName]=\"config.controlName\" type=\"text\"/>\n\n <input\n matInput\n [formControl]=\"autocompleteInputControl\"\n [placeholder]=\"config.placeholder\"\n [matAutocomplete]=\"auto\"\n role=\"textbox\"\n type=\"textbox\"\n autocapitalize=\"off\"\n autocorrect=\"off\"\n spellcheck=\"false\"\n #autoInput>\n\n <span *ngIf=\"config.fieldSuffix\" matSuffix>{{config.fieldSuffix}}</span>\n <crispr-info\n *ngIf=\"config.info\"\n matSuffix\n [info]=\"config.info \">\n </crispr-info>\n\n <mat-autocomplete\n #auto=\"matAutocomplete\"\n [autoActiveFirstOption]=\"config.autoActiveFirstOption\"\n (optionSelected)=\"handleSelect($event)\"\n [displayWith]=\"displayLabel(options$ | async)\">\n\n <ng-container *ngIf=\"options$ | async as options; else emptyOption\">\n <ng-container *ngIf=\"options.length > 0; else emptyOption\">\n <mat-option\n *ngFor=\"let option of options\"\n [value]=\"option.value\">\n <crispr-option [option]=\"option\"></crispr-option>\n </mat-option>\n </ng-container>\n\n </ng-container>\n <ng-template #emptyOption>\n <mat-option disabled=\"true\">\n {{config.emptyOptionsMessage}}\n </mat-option>\n </ng-template>\n\n </mat-autocomplete>\n\n <mat-hint *ngIf=\"config.hint && (control.valid || !control.touched)\">{{config.hint}}</mat-hint>\n\n </mat-form-field>\n</crispr-field-container>\n", styles: [".hidden-error-directive-anchor{display:none}\n"] }]
632
- }], propDecorators: { autoInput: [{
633
- type: ViewChild,
634
- args: ['autoInput', { read: MatAutocompleteTrigger }]
635
- }], autoInputRef: [{
636
- type: ViewChild,
637
- args: ['autoInput']
638
- }] } });
639
-
640
- const defaultConfig$6 = {
641
- chipsSelectable: true,
642
- areChipsRemovable: true,
643
- tabToSelect: true,
644
- autoActiveFirstOption: true,
645
- imageUrlParam: 'image',
646
- typeDebounceTime: 500,
647
- allowDuplicates: false,
648
- duplicateCompareFunction: (chip, option) => chip.value === option.value,
649
- separatorKeyCodes: [ENTER],
650
- emptyOptionsMessage: DEFAULT_EMPTY_OPTIONS_MESSAGE,
651
- };
652
- class AutocompleteChiplistFieldComponent extends AbstractAutocompleteComponent {
653
- constructor() {
654
- super(...arguments);
655
- this.defaultConfig = defaultConfig$6;
656
- this.chips$ = new BehaviorSubject([]);
657
- this.controlValue$ = this.chips$.pipe(tap(chips => {
658
- this.control.setValue(chips.map(chip => chip.value));
659
- }));
660
- }
661
- ngOnInit() {
662
- super.ngOnInit();
663
- this.remainingOptions$ = combineLatest([
664
- this.chips$,
665
- this.options$
666
- ]).pipe(map(([chips, options]) => {
667
- return this.config.allowDuplicates
668
- ? options
669
- : options?.filter(option => {
670
- return !chips.some(chip => this.config.duplicateCompareFunction(chip, option));
671
- });
672
- }));
673
- }
674
- setControlValue(value) {
675
- if (value) {
676
- this.chips$.next(value);
677
- }
678
- }
679
- // handles mat selecting
680
- handleSelect(event) {
681
- const selectedOption = event.option.value;
682
- this.chips$.next([...this.chips$.value, selectedOption]);
683
- this.chipInputRef.nativeElement.value = '';
684
- this.autocompleteInputControl.setValue('');
685
- // setTimeout needed because the panel thinks it's still open at this point
686
- setTimeout(() => this.chipInput.openPanel());
687
- }
688
- /**
689
- * To follow ARIA standards we want to select the active option on blur.
690
- * matChipInputAddOnBlur should do this but it causes buggy behaviour
691
- * @param event blur event that triggers the handle blur
692
- */
693
- handleTab(_event) {
694
- if (this.chipInput.activeOption && (this.config.tabToSelect || this.config.addChipOnBlur)) {
695
- const chip = this.chipInput.activeOption.value;
696
- this.chips$.next([...this.chips$.value, chip]);
697
- }
698
- }
699
- /**
700
- * Handles selection via key tokens passed through separatorKeyCodes propert
701
- * NOTE: If TAB is used focus does not move on to next component
702
- * @param event
703
- */
704
- handleTokenEnd(event) {
705
- if (this.chipInput.activeOption) {
706
- this.chipInput.activeOption.select();
707
- }
708
- event.chipInput?.clear();
709
- }
710
- mapToLabel(option) {
711
- return option ? option.label : '';
712
- }
713
- removeChip(removedChip) {
714
- const remainingChips = this.chips$.value.filter(chip => chip !== removedChip);
715
- this.chips$.next(remainingChips);
716
- }
717
- }
718
- AutocompleteChiplistFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: AutocompleteChiplistFieldComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
719
- AutocompleteChiplistFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: AutocompleteChiplistFieldComponent, selector: "crispr-autocomplete-chiplist-field", viewQueries: [{ propertyName: "chipInput", first: true, predicate: ["autoInput"], descendants: true, read: MatAutocompleteTrigger }, { propertyName: "chipInputRef", first: true, predicate: ["autoInput"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n\n <mat-form-field\n [color]=\"config.color\"\n [appearance]=\"config.appearance\"\n [formGroup]=\"group\">\n <mat-label *ngIf=\"config.label\">\n {{config.label}}\n </mat-label>\n\n <mat-chip-list\n #chipList>\n <mat-chip\n class=\"refinement-chip\"\n *ngFor=\"let chip of controlValue$ | async\"\n [selectable]=\"config.chipsSelectable\"\n [removable]=\"config.areChipsRemovable\"\n (removed)=\"removeChip(chip)\">\n <span *ngIf=\"chip.imageUrl as imageUrl\" class=\"image-container\">\n <img [src]=\"imageUrl\" alt=\"image of {{chip.label}}\">\n </span>\n {{chip.label}}\n <mat-icon\n matChipRemove\n *ngIf=\"config.areChipsRemovable\">\n cancel\n </mat-icon>\n </mat-chip>\n <input class=\"hidden-error-directive-anchor\" [formControlName]=\"config.controlName\" type=\"text\"/>\n\n <input\n matInput\n [formControl]=\"autocompleteInputControl\"\n [placeholder]=\"config.placeholder\"\n [matChipInputFor]=\"chipList\"\n [matAutocomplete]=\"auto\"\n (keydown.tab)=\"handleTab($event)\"\n [matChipInputSeparatorKeyCodes]=\"config.separatorKeyCodes\"\n (matChipInputTokenEnd)=\"handleTokenEnd($event)\"\n role=\"searchbox\"\n type=\"text\"\n autocapitalize=\"off\"\n autocorrect=\"off\"\n spellcheck=\"false\"\n #autoInput/>\n <span *ngIf=\"config.fieldSuffix\" matSuffix>{{config.fieldSuffix}}</span>\n <crispr-info\n *ngIf=\"config.info\"\n matSuffix\n [info]=\"config.info \">\n </crispr-info>\n\n </mat-chip-list>\n <mat-autocomplete\n #auto=\"matAutocomplete\"\n [autoActiveFirstOption]=\"this.config.autoActiveFirstOption\"\n (optionSelected)=\"handleSelect($event)\"\n [displayWith]=\"mapToLabel\">\n <ng-container *ngIf=\"remainingOptions$ | async as remainingOptions; else emptyOption\">\n <ng-container *ngIf=\"remainingOptions.length > 0; else emptyOption\">\n <mat-option\n *ngFor=\"let option of remainingOptions$ | async\"\n [value]=\"option\">\n <crispr-option [option]=\"option\"></crispr-option>\n </mat-option>\n </ng-container>\n\n </ng-container>\n <ng-template #emptyOption>\n <mat-option disabled=\"true\">\n {{config.emptyOptionsMessage}}\n </mat-option>\n </ng-template>\n </mat-autocomplete>\n\n <mat-hint *ngIf=\"config.hint && (control.valid || !control.touched)\">{{config.hint}}</mat-hint>\n\n </mat-form-field>\n</crispr-field-container>\n", styles: [".refinement-chip .image-container{width:26px;height:26px;border-radius:50%;overflow:hidden;margin:-2px 4px -2px -8px}.refinement-chip .image-container img{width:100%;height:100%;object-fit:cover}.hidden-error-directive-anchor{display:none}\n"], components: [{ type: FieldContainerComponent, selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }, { type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i3$2.MatChipList, selector: "mat-chip-list", inputs: ["errorStateMatcher", "multiple", "compareWith", "value", "required", "placeholder", "disabled", "aria-orientation", "selectable", "tabIndex"], outputs: ["change", "valueChange"], exportAs: ["matChipList"] }, { type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: InfoComponent, selector: "crispr-info", inputs: ["info"] }, { type: i4$3.MatAutocomplete, selector: "mat-autocomplete", inputs: ["disableRipple"], exportAs: ["matAutocomplete"] }, { type: i5$1.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { type: OptionComponent, selector: "crispr-option", inputs: ["option"] }], directives: [{ type: i4$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i4$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5.ControlErrorContainerDirective, selector: "[controlErrorContainer], [formGroup]" }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2$1.MatLabel, selector: "mat-label" }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3$2.MatChip, selector: "mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]", inputs: ["color", "disableRipple", "tabIndex", "selected", "value", "selectable", "disabled", "removable"], outputs: ["selectionChange", "destroyed", "removed"], exportAs: ["matChip"] }, { type: i3$2.MatChipRemove, selector: "[matChipRemove]" }, { type: i4$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i4$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i5.ControlErrorsDirective, selector: "[formControl], [formControlName]" }, { type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i3$2.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { type: i4$3.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", exportAs: ["matAutocompleteTrigger"] }, { type: i4$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { type: i2$1.MatSuffix, selector: "[matSuffix]" }, { type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }], pipes: { "async": i2.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true });
720
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: AutocompleteChiplistFieldComponent, decorators: [{
721
- type: Component,
722
- args: [{ selector: 'crispr-autocomplete-chiplist-field', changeDetection: ChangeDetectionStrategy.OnPush, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n\n <mat-form-field\n [color]=\"config.color\"\n [appearance]=\"config.appearance\"\n [formGroup]=\"group\">\n <mat-label *ngIf=\"config.label\">\n {{config.label}}\n </mat-label>\n\n <mat-chip-list\n #chipList>\n <mat-chip\n class=\"refinement-chip\"\n *ngFor=\"let chip of controlValue$ | async\"\n [selectable]=\"config.chipsSelectable\"\n [removable]=\"config.areChipsRemovable\"\n (removed)=\"removeChip(chip)\">\n <span *ngIf=\"chip.imageUrl as imageUrl\" class=\"image-container\">\n <img [src]=\"imageUrl\" alt=\"image of {{chip.label}}\">\n </span>\n {{chip.label}}\n <mat-icon\n matChipRemove\n *ngIf=\"config.areChipsRemovable\">\n cancel\n </mat-icon>\n </mat-chip>\n <input class=\"hidden-error-directive-anchor\" [formControlName]=\"config.controlName\" type=\"text\"/>\n\n <input\n matInput\n [formControl]=\"autocompleteInputControl\"\n [placeholder]=\"config.placeholder\"\n [matChipInputFor]=\"chipList\"\n [matAutocomplete]=\"auto\"\n (keydown.tab)=\"handleTab($event)\"\n [matChipInputSeparatorKeyCodes]=\"config.separatorKeyCodes\"\n (matChipInputTokenEnd)=\"handleTokenEnd($event)\"\n role=\"searchbox\"\n type=\"text\"\n autocapitalize=\"off\"\n autocorrect=\"off\"\n spellcheck=\"false\"\n #autoInput/>\n <span *ngIf=\"config.fieldSuffix\" matSuffix>{{config.fieldSuffix}}</span>\n <crispr-info\n *ngIf=\"config.info\"\n matSuffix\n [info]=\"config.info \">\n </crispr-info>\n\n </mat-chip-list>\n <mat-autocomplete\n #auto=\"matAutocomplete\"\n [autoActiveFirstOption]=\"this.config.autoActiveFirstOption\"\n (optionSelected)=\"handleSelect($event)\"\n [displayWith]=\"mapToLabel\">\n <ng-container *ngIf=\"remainingOptions$ | async as remainingOptions; else emptyOption\">\n <ng-container *ngIf=\"remainingOptions.length > 0; else emptyOption\">\n <mat-option\n *ngFor=\"let option of remainingOptions$ | async\"\n [value]=\"option\">\n <crispr-option [option]=\"option\"></crispr-option>\n </mat-option>\n </ng-container>\n\n </ng-container>\n <ng-template #emptyOption>\n <mat-option disabled=\"true\">\n {{config.emptyOptionsMessage}}\n </mat-option>\n </ng-template>\n </mat-autocomplete>\n\n <mat-hint *ngIf=\"config.hint && (control.valid || !control.touched)\">{{config.hint}}</mat-hint>\n\n </mat-form-field>\n</crispr-field-container>\n", styles: [".refinement-chip .image-container{width:26px;height:26px;border-radius:50%;overflow:hidden;margin:-2px 4px -2px -8px}.refinement-chip .image-container img{width:100%;height:100%;object-fit:cover}.hidden-error-directive-anchor{display:none}\n"] }]
723
- }], propDecorators: { chipInput: [{
724
- type: ViewChild,
725
- args: ['autoInput', { read: MatAutocompleteTrigger }]
726
- }], chipInputRef: [{
727
- type: ViewChild,
728
- args: ['autoInput']
729
- }] } });
730
-
731
- const defaultConfig$5 = {
732
- labelPosition: 'after',
733
- inline: false
734
- };
735
- const CheckboxFieldMixin = crisprControlMixin(CrisprFieldComponent);
736
- class CheckboxFieldComponent extends CheckboxFieldMixin {
737
- constructor() {
738
- super(...arguments);
739
- this.defaultConfig = defaultConfig$5;
740
- }
741
- ngOnInit() {
742
- super.ngOnInit();
743
- }
744
- }
745
- CheckboxFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CheckboxFieldComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
746
- CheckboxFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: CheckboxFieldComponent, selector: "crispr-checkbox-field", usesInheritance: true, ngImport: i0, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\"\n [inlineField]=\"config.inline\">\n <div\n [formGroup]=\"group\">\n <mat-checkbox\n [color]=\"config.color\"\n [labelPosition]=\"config.labelPosition\"\n [formControlName]=\"config.controlName\">\n {{config.label}}\n <crispr-info\n matSuffix *ngIf=\"config.info\"\n [info]=\"config.info\">\n </crispr-info>\n </mat-checkbox>\n </div>\n</crispr-field-container>\n", styles: ["mat-checkbox{height:42px}\n"], components: [{ type: FieldContainerComponent, selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }, { type: i4$2.MatCheckbox, selector: "mat-checkbox", inputs: ["disableRipple", "color", "tabIndex", "aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { type: InfoComponent, selector: "crispr-info", inputs: ["info"] }], directives: [{ type: i4$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i4$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5.ControlErrorContainerDirective, selector: "[controlErrorContainer], [formGroup]" }, { type: i4$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i5.ControlErrorsDirective, selector: "[formControl], [formControlName]" }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2$1.MatSuffix, selector: "[matSuffix]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true });
747
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CheckboxFieldComponent, decorators: [{
748
- type: Component,
749
- args: [{ selector: 'crispr-checkbox-field', changeDetection: ChangeDetectionStrategy.OnPush, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\"\n [inlineField]=\"config.inline\">\n <div\n [formGroup]=\"group\">\n <mat-checkbox\n [color]=\"config.color\"\n [labelPosition]=\"config.labelPosition\"\n [formControlName]=\"config.controlName\">\n {{config.label}}\n <crispr-info\n matSuffix *ngIf=\"config.info\"\n [info]=\"config.info\">\n </crispr-info>\n </mat-checkbox>\n </div>\n</crispr-field-container>\n", styles: ["mat-checkbox{height:42px}\n"] }]
750
- }] });
751
-
752
- const defaultConfig$4 = { rows: 5 };
753
- const TextareaFieldMixin = crisprControlMixin(CrisprFieldComponent);
754
- class TextareaFieldComponent extends TextareaFieldMixin {
755
- constructor() {
756
- super(...arguments);
757
- this.defaultConfig = defaultConfig$4;
758
- }
759
- ngOnInit() {
760
- super.ngOnInit();
761
- }
762
- }
763
- TextareaFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: TextareaFieldComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
764
- TextareaFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: TextareaFieldComponent, selector: "crispr-textarea-field", usesInheritance: true, ngImport: i0, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n <mat-form-field\n [color]=\"config.color\"\n [appearance]=\"config.appearance\"\n [formGroup]=\"group\">\n <mat-label *ngIf=\"config.label\">\n {{config.label}}\n </mat-label>\n <textarea\n [rows]=\"config.rows\"\n matInput\n [placeholder]=\"config.placeholder\"\n [formControlName]=\"config.controlName\">\n </textarea>\n <span *ngIf=\"config.fieldSuffix\" matSuffix>{{config.fieldSuffix}}</span>\n <crispr-info\n *ngIf=\"config.info\"\n matSuffix\n [info]=\"config.info\">\n </crispr-info>\n\n <mat-hint *ngIf=\"config.hint && control.valid\">{{config.hint}}</mat-hint>\n\n </mat-form-field>\n\n</crispr-field-container>\n", styles: [""], components: [{ type: FieldContainerComponent, selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }, { type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: InfoComponent, selector: "crispr-info", inputs: ["info"] }], directives: [{ type: i4$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i4$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5.ControlErrorContainerDirective, selector: "[controlErrorContainer], [formGroup]" }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2$1.MatLabel, selector: "mat-label" }, { type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i4$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i4$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i5.ControlErrorsDirective, selector: "[formControl], [formControlName]" }, { type: i2$1.MatSuffix, selector: "[matSuffix]" }, { type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true });
765
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: TextareaFieldComponent, decorators: [{
766
- type: Component,
767
- args: [{ selector: 'crispr-textarea-field', changeDetection: ChangeDetectionStrategy.OnPush, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n <mat-form-field\n [color]=\"config.color\"\n [appearance]=\"config.appearance\"\n [formGroup]=\"group\">\n <mat-label *ngIf=\"config.label\">\n {{config.label}}\n </mat-label>\n <textarea\n [rows]=\"config.rows\"\n matInput\n [placeholder]=\"config.placeholder\"\n [formControlName]=\"config.controlName\">\n </textarea>\n <span *ngIf=\"config.fieldSuffix\" matSuffix>{{config.fieldSuffix}}</span>\n <crispr-info\n *ngIf=\"config.info\"\n matSuffix\n [info]=\"config.info\">\n </crispr-info>\n\n <mat-hint *ngIf=\"config.hint && control.valid\">{{config.hint}}</mat-hint>\n\n </mat-form-field>\n\n</crispr-field-container>\n", styles: [""] }]
768
- }] });
769
-
770
- const defaultConfig$3 = { displayLimits: true };
771
- const SliderFieldMixin = crisprControlMixin(CrisprFieldComponent);
772
- class SliderFieldComponent extends SliderFieldMixin {
773
- constructor() {
774
- super();
775
- this.defaultConfig = defaultConfig$3;
776
- }
777
- get flexDirection() {
778
- return this.config.vertical ? 'column' : 'row';
779
- }
780
- ngOnInit() {
781
- super.ngOnInit();
782
- }
783
- }
784
- SliderFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: SliderFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
785
- SliderFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: SliderFieldComponent, selector: "crispr-slider-field", usesInheritance: true, ngImport: i0, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n <div\n [formGroup]=\"group\">\n <label *ngIf=\"config.label\">\n {{config.label}}\n <crispr-info\n *ngIf=\"config.info\"\n [info]=\"config.info\">\n </crispr-info>\n </label>\n <div class=\"slider-container\"\n [ngStyle]=\"{'flex-direction': flexDirection}\">\n <span *ngIf=\"config.displayLimits\">\n {{config.min}}\n </span>\n <mat-slider\n class=\"example-margin\"\n [formControlName]=\"config.controlName\"\n [invert]=\"config.invert\"\n [max]=\"config.max\"\n [min]=\"config.min\"\n [step]=\"config.step\"\n [thumbLabel]=\"config.thumbLabel\"\n [tickInterval]=\"config.tickInterval\"\n [vertical]=\"config.vertical\">\n </mat-slider>\n <span *ngIf=\"config.displayLimits\">\n {{config.max}}\n </span>\n </div>\n\n </div>\n</crispr-field-container>\n\n", styles: [".slider-container{display:flex;align-items:center}.slider-container .mat-slider-horizontal{width:100%}\n"], components: [{ type: FieldContainerComponent, selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }, { type: InfoComponent, selector: "crispr-info", inputs: ["info"] }, { type: i3$3.MatSlider, selector: "mat-slider", inputs: ["disabled", "color", "tabIndex", "invert", "max", "min", "step", "thumbLabel", "tickInterval", "value", "displayWith", "valueText", "vertical"], outputs: ["change", "input", "valueChange"], exportAs: ["matSlider"] }], directives: [{ type: i4$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i4$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5.ControlErrorContainerDirective, selector: "[controlErrorContainer], [formGroup]" }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i4$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i5.ControlErrorsDirective, selector: "[formControl], [formControlName]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true });
786
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: SliderFieldComponent, decorators: [{
787
- type: Component,
788
- args: [{ selector: 'crispr-slider-field', changeDetection: ChangeDetectionStrategy.OnPush, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n <div\n [formGroup]=\"group\">\n <label *ngIf=\"config.label\">\n {{config.label}}\n <crispr-info\n *ngIf=\"config.info\"\n [info]=\"config.info\">\n </crispr-info>\n </label>\n <div class=\"slider-container\"\n [ngStyle]=\"{'flex-direction': flexDirection}\">\n <span *ngIf=\"config.displayLimits\">\n {{config.min}}\n </span>\n <mat-slider\n class=\"example-margin\"\n [formControlName]=\"config.controlName\"\n [invert]=\"config.invert\"\n [max]=\"config.max\"\n [min]=\"config.min\"\n [step]=\"config.step\"\n [thumbLabel]=\"config.thumbLabel\"\n [tickInterval]=\"config.tickInterval\"\n [vertical]=\"config.vertical\">\n </mat-slider>\n <span *ngIf=\"config.displayLimits\">\n {{config.max}}\n </span>\n </div>\n\n </div>\n</crispr-field-container>\n\n", styles: [".slider-container{display:flex;align-items:center}.slider-container .mat-slider-horizontal{width:100%}\n"] }]
789
- }], ctorParameters: function () { return []; } });
790
-
791
- class ButtonComponent extends CrisprFieldComponent {
792
- constructor() {
793
- super(...arguments);
794
- this.defaultConfig = { buttonType: 'raised', type: 'submit' };
795
- }
796
- get matButtonClass() {
797
- return this.config.buttonType ? `mat-${this.config.buttonType}-button` : '';
798
- }
799
- ngOnInit() {
800
- super.ngOnInit();
801
- this.formValid$ = this.group.statusChanges.pipe(map(status => status === 'VALID'), startWith(this.group.valid));
802
- }
803
- handleClick(group, event) {
804
- if (this.config.callback) {
805
- this.config.callback(group, event);
806
- }
807
- }
808
- }
809
- ButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: ButtonComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
810
- ButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: ButtonComponent, selector: "crispr-button", usesInheritance: true, ngImport: i0, template: "<button\n [formGroup]=\"group\"\n mat-button\n [ngClass]=\"matButtonClass\"\n [color]=\"config.color\"\n [disabled]=\"config.disabledOnInvalidForm && !(formValid$ | async)\"\n [type]=\"config.type\"\n (click)=\"handleClick(group, $event)\"\n [matTooltip]=\"config.info?.content\"\n [matTooltipPosition]=\"config.info?.tooltipPosition || 'below'\">\n {{ config.label }}\n <mat-icon *ngIf=\"config.icon\">\n {{ config.icon}}\n </mat-icon>\n</button>\n\n", styles: [""], components: [{ type: i1.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i4$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i4$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5.ControlErrorContainerDirective, selector: "[controlErrorContainer], [formGroup]" }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i3.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], pipes: { "async": i2.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true });
811
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: ButtonComponent, decorators: [{
812
- type: Component,
813
- args: [{ selector: 'crispr-button', changeDetection: ChangeDetectionStrategy.OnPush, template: "<button\n [formGroup]=\"group\"\n mat-button\n [ngClass]=\"matButtonClass\"\n [color]=\"config.color\"\n [disabled]=\"config.disabledOnInvalidForm && !(formValid$ | async)\"\n [type]=\"config.type\"\n (click)=\"handleClick(group, $event)\"\n [matTooltip]=\"config.info?.content\"\n [matTooltipPosition]=\"config.info?.tooltipPosition || 'below'\">\n {{ config.label }}\n <mat-icon *ngIf=\"config.icon\">\n {{ config.icon}}\n </mat-icon>\n</button>\n\n", styles: [""] }]
814
- }] });
815
-
816
- const defaultConfig$2 = {
817
- startView: 'month',
818
- };
819
- const DatepickerFieldMixin = crisprControlMixin(CrisprFieldComponent);
820
- class DatepickerFieldComponent extends DatepickerFieldMixin {
821
- constructor() {
822
- super(...arguments);
823
- this.defaultConfig = defaultConfig$2;
824
- }
825
- ngOnInit() {
826
- super.ngOnInit();
827
- this.startAt$ = this.config.startAt instanceof Date
828
- ? of(this.config.startAt)
829
- : this.config.startAt instanceof Function
830
- ? this.config.startAt(this.group)
831
- : of(null);
832
- this.dateClass = this.config?.cellClassFunction || null;
833
- this.dateClass$ = this.config.dateClass ? this.config?.dateClass(this.group) : of(() => '');
834
- }
835
- ngAfterContentInit() {
836
- if (this.config.datepickerActions) {
837
- this.calendarFooterPortal = new ComponentPortal(this.config.datepickerActions);
838
- }
839
- }
840
- }
841
- DatepickerFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: DatepickerFieldComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
842
- DatepickerFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: DatepickerFieldComponent, selector: "crispr-datepicker-field", usesInheritance: true, ngImport: i0, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n <mat-form-field\n [color]=\"config.color\"\n [appearance]=\"config.appearance\"\n [formGroup]=\"group\">\n <mat-label *ngIf=\"config.label\">\n {{config.label}}\n </mat-label>\n <input\n matInput\n [formControlName]=\"config.controlName\"\n [min]=\"config.min\"\n [max]=\"config.max\"\n [matDatepicker]=\"picker\"\n [matDatepickerFilter]=\"config.datepickerFilter\">\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker\n [touchUi]=\"config.touchUi\"\n [startView]=\"config.startView\"\n [startAt]=\"startAt$ | async\"\n [dateClass]=\"dateClass || (dateClass$ | async)\"\n #picker>\n <mat-datepicker-actions *ngIf=\"calendarFooterPortal\">\n <ng-template [cdkPortalOutlet]=\"calendarFooterPortal\"></ng-template>\n </mat-datepicker-actions>\n </mat-datepicker>\n\n <mat-hint *ngIf=\"config.hint && (control.valid || !control.touched)\">{{config.hint}}</mat-hint>\n\n </mat-form-field>\n</crispr-field-container>\n\n", styles: [""], components: [{ type: FieldContainerComponent, selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }, { type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i3$4.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { type: i3$4.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { type: i3$4.MatDatepickerActions, selector: "mat-datepicker-actions, mat-date-range-picker-actions" }], directives: [{ type: i4$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i4$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5.ControlErrorContainerDirective, selector: "[controlErrorContainer], [formGroup]" }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2$1.MatLabel, selector: "mat-label" }, { type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i4$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i3$4.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { type: i4$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i5.ControlErrorsDirective, selector: "[formControl], [formControlName]" }, { type: i2$1.MatSuffix, selector: "[matSuffix]" }, { type: i8.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }, { type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }], pipes: { "async": i2.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true });
843
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: DatepickerFieldComponent, decorators: [{
844
- type: Component,
845
- args: [{ selector: 'crispr-datepicker-field', changeDetection: ChangeDetectionStrategy.OnPush, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n <mat-form-field\n [color]=\"config.color\"\n [appearance]=\"config.appearance\"\n [formGroup]=\"group\">\n <mat-label *ngIf=\"config.label\">\n {{config.label}}\n </mat-label>\n <input\n matInput\n [formControlName]=\"config.controlName\"\n [min]=\"config.min\"\n [max]=\"config.max\"\n [matDatepicker]=\"picker\"\n [matDatepickerFilter]=\"config.datepickerFilter\">\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker\n [touchUi]=\"config.touchUi\"\n [startView]=\"config.startView\"\n [startAt]=\"startAt$ | async\"\n [dateClass]=\"dateClass || (dateClass$ | async)\"\n #picker>\n <mat-datepicker-actions *ngIf=\"calendarFooterPortal\">\n <ng-template [cdkPortalOutlet]=\"calendarFooterPortal\"></ng-template>\n </mat-datepicker-actions>\n </mat-datepicker>\n\n <mat-hint *ngIf=\"config.hint && (control.valid || !control.touched)\">{{config.hint}}</mat-hint>\n\n </mat-form-field>\n</crispr-field-container>\n\n", styles: [""] }]
846
- }] });
847
-
848
- class DividerComponent extends CrisprFieldComponent {
849
- constructor() {
850
- super(...arguments);
851
- // TODO: pull in type after configs are better organized
852
- this.defaultConfig = {};
853
- }
854
- ngOnInit() {
855
- super.ngOnInit();
856
- }
857
- }
858
- DividerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: DividerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
859
- DividerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: DividerComponent, selector: "crispr-divider", usesInheritance: true, ngImport: i0, template: "<mat-divider [ngClass]=\"config.classes\"></mat-divider>", styles: [":host{display:block;padding:1em 0}::ng-deep .mat-divider.mat-divider-horizontal{position:relative}\n"], components: [{ type: i1$1.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }], directives: [{ type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], preserveWhitespaces: true });
860
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: DividerComponent, decorators: [{
861
- type: Component,
862
- args: [{ selector: 'crispr-divider', template: "<mat-divider [ngClass]=\"config.classes\"></mat-divider>", styles: [":host{display:block;padding:1em 0}::ng-deep .mat-divider.mat-divider-horizontal{position:relative}\n"] }]
863
- }] });
864
-
865
- const RadioFieldMixin = crisprControlMixin(CrisprFieldComponent);
866
- class RadioFieldComponent extends RadioFieldMixin {
867
- constructor() {
868
- super(...arguments);
869
- this.defaultConfig = {};
870
- }
871
- ngOnInit() {
872
- super.ngOnInit();
873
- // options$ can be passed as an array, promise that resolves array, or observable that resolves array
874
- // this functions accounts for all possibilities and converts to observable that resolves array
875
- this.options$ = observablifyOptions(this.config.options, this.group);
876
- }
877
- }
878
- RadioFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: RadioFieldComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
879
- RadioFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: RadioFieldComponent, selector: "crispr-radio-field", usesInheritance: true, ngImport: i0, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n\n <mat-radio-group\n [formControl]=\"control\"\n [color]=\"config.color\">\n <mat-radio-button class=\"example-radio-button\" *ngFor=\"let option of options$ | async\" [value]=\"option.value\">\n {{option.label}}\n </mat-radio-button>\n </mat-radio-group>\n</crispr-field-container>\n", styles: ["mat-radio-button{padding:12px}\n"], components: [{ type: FieldContainerComponent, selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }, { type: i2$2.MatRadioButton, selector: "mat-radio-button", inputs: ["disableRipple", "tabIndex"], exportAs: ["matRadioButton"] }], directives: [{ type: i2$2.MatRadioGroup, selector: "mat-radio-group", exportAs: ["matRadioGroup"] }, { type: i4$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { type: i5.ControlErrorsDirective, selector: "[formControl], [formControlName]" }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "async": i2.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true });
880
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: RadioFieldComponent, decorators: [{
881
- type: Component,
882
- args: [{ selector: 'crispr-radio-field', changeDetection: ChangeDetectionStrategy.OnPush, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n\n <mat-radio-group\n [formControl]=\"control\"\n [color]=\"config.color\">\n <mat-radio-button class=\"example-radio-button\" *ngFor=\"let option of options$ | async\" [value]=\"option.value\">\n {{option.label}}\n </mat-radio-button>\n </mat-radio-group>\n</crispr-field-container>\n", styles: ["mat-radio-button{padding:12px}\n"] }]
883
- }] });
884
-
885
- const defaultConfig$1 = {};
886
- const UnitConversionFieldMixin = crisprControlMixin(CrisprFieldComponent);
887
- class UnitConversionFieldComponent extends UnitConversionFieldMixin {
888
- constructor() {
889
- super(...arguments);
890
- this.defaultConfig = defaultConfig$1;
891
- this.displayValueControl = new FormControl();
892
- this.unitSelectControl = new FormControl();
893
- }
894
- ngOnInit() {
895
- super.ngOnInit();
896
- // TODO: Validators need work. validation is tricky because the input needs to be validated against but the validator will compare against the controls value
897
- // this.displayValueControl.setValidators(this.config.validators);
898
- const controlValuePipeline = [
899
- this.displayValueControl.valueChanges.pipe(startWith(this.displayValueControl.value))
900
- ];
901
- // setup all required pieces when showing a field for selecting units
902
- if (this.config.showUnitSelect) {
903
- this.unitOptions$ = observablifyOptions(this.config.selectableUnits, this.group);
904
- controlValuePipeline.push(this.unitSelectControl.valueChanges.pipe(startWith(this.config?.initialDisplayUnit || null)));
905
- this.unitSelectControl.setValue(this.config?.initialDisplayUnit || null);
906
- }
907
- this.transformationSubscription = combineLatest(controlValuePipeline).subscribe(([displayValue, unitValue]) => {
908
- const computedValue = this.config.storedValueConversion(displayValue, unitValue);
909
- this.control.setValue(computedValue);
910
- });
911
- }
912
- ngOnDestroy() {
913
- this.transformationSubscription.unsubscribe();
914
- }
915
- setInitialDisplayValue(storedValue, unit) {
916
- const initialDisplayValue = this.config.initialDisplayValueConversion(storedValue || null, unit);
917
- this.displayValueControl.setValue(initialDisplayValue);
918
- }
919
- /**
920
- * We override the 'setControlValue' we inherited from crisprControlMixin and add our custom logic,
921
- * This function gets called onInit because were object oriented. it's so great, so great that I'm
922
- * typing a paragraph to explain what the hell is going on...
923
- * @param value the initial value for the control passed down from the form components input
924
- */
925
- setControlValue(value) {
926
- const initialUnitValue = this.config.showUnitSelect ? this.config?.initialDisplayUnit : null;
927
- this.setInitialDisplayValue(value, initialUnitValue);
928
- }
929
- }
930
- UnitConversionFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: UnitConversionFieldComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
931
- UnitConversionFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: UnitConversionFieldComponent, selector: "crispr-unit-conversion-field", usesInheritance: true, ngImport: i0, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n <mat-form-field\n [style.width.%]=\"config.showUnitSelect ? 60 : 100\"\n class=\"number-field\"\n [color]=\"config.color\"\n [appearance]=\"config.appearance\">\n <mat-label *ngIf=\"config.label\">\n {{config.label}}\n </mat-label>\n <input\n type=\"number\"\n matInput\n [formControl]=\"displayValueControl\"\n [placeholder]=\"config.placeholder\"\n [min]=\"config.min\"\n [max]=\"config.max\"\n [step]=\"config.step\"\n [autofocus]=\"config.autofocus\">\n <span *ngIf=\"config.fieldSuffix\" matSuffix>{{config.fieldSuffix}}</span>\n <crispr-info\n matSuffix\n *ngIf=\"config.info\"\n [info]=\"config.info\">\n </crispr-info>\n </mat-form-field>\n\n <mat-form-field\n *ngIf=\"config.showUnitSelect\"\n [color]=\"config.color\"\n [appearance]=\"config.appearance\"\n [formGroup]=\"group\"\n class=\"unit-field\">\n <mat-label *ngIf=\"config.label\">\n {{config.label}}\n </mat-label>\n <mat-select\n #selectField\n [formControl]=\"unitSelectControl\">\n\n <mat-option\n *ngFor=\"let option of unitOptions$ | async\"\n [value]=\"option.value\">\n <crispr-option [option]=\"option\">\n </crispr-option>\n </mat-option>\n\n </mat-select>\n\n <mat-hint *ngIf=\"config.hint && (control.valid || !control.touched)\">{{config.hint}}</mat-hint>\n\n </mat-form-field>\n\n</crispr-field-container>\n", styles: [".unit-field{width:40%;margin-left:16px}:host ::ng-deep .field-container{display:flex}\n"], components: [{ type: FieldContainerComponent, selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }, { type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: InfoComponent, selector: "crispr-info", inputs: ["info"] }, { type: i3$1.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i5$1.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { type: OptionComponent, selector: "crispr-option", inputs: ["option"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2$1.MatLabel, selector: "mat-label" }, { type: i4$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { type: i4$1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { type: i4$1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i4$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i4$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { type: i5.ControlErrorsDirective, selector: "[formControl], [formControlName]" }, { type: i2$1.MatSuffix, selector: "[matSuffix]" }, { type: i4$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i4$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5.ControlErrorContainerDirective, selector: "[controlErrorContainer], [formGroup]" }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }], pipes: { "async": i2.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true });
932
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: UnitConversionFieldComponent, decorators: [{
933
- type: Component,
934
- args: [{ selector: 'crispr-unit-conversion-field', changeDetection: ChangeDetectionStrategy.OnPush, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n <mat-form-field\n [style.width.%]=\"config.showUnitSelect ? 60 : 100\"\n class=\"number-field\"\n [color]=\"config.color\"\n [appearance]=\"config.appearance\">\n <mat-label *ngIf=\"config.label\">\n {{config.label}}\n </mat-label>\n <input\n type=\"number\"\n matInput\n [formControl]=\"displayValueControl\"\n [placeholder]=\"config.placeholder\"\n [min]=\"config.min\"\n [max]=\"config.max\"\n [step]=\"config.step\"\n [autofocus]=\"config.autofocus\">\n <span *ngIf=\"config.fieldSuffix\" matSuffix>{{config.fieldSuffix}}</span>\n <crispr-info\n matSuffix\n *ngIf=\"config.info\"\n [info]=\"config.info\">\n </crispr-info>\n </mat-form-field>\n\n <mat-form-field\n *ngIf=\"config.showUnitSelect\"\n [color]=\"config.color\"\n [appearance]=\"config.appearance\"\n [formGroup]=\"group\"\n class=\"unit-field\">\n <mat-label *ngIf=\"config.label\">\n {{config.label}}\n </mat-label>\n <mat-select\n #selectField\n [formControl]=\"unitSelectControl\">\n\n <mat-option\n *ngFor=\"let option of unitOptions$ | async\"\n [value]=\"option.value\">\n <crispr-option [option]=\"option\">\n </crispr-option>\n </mat-option>\n\n </mat-select>\n\n <mat-hint *ngIf=\"config.hint && (control.valid || !control.touched)\">{{config.hint}}</mat-hint>\n\n </mat-form-field>\n\n</crispr-field-container>\n", styles: [".unit-field{width:40%;margin-left:16px}:host ::ng-deep .field-container{display:flex}\n"] }]
935
- }] });
936
-
937
- class FileDropzoneDirective {
938
- constructor() {
939
- this.fileDrop = new EventEmitter();
940
- this.crisprFileDropzone = true;
941
- }
942
- onDrop($event) {
943
- if (this.crisprFileDropzone) {
944
- $event.preventDefault();
945
- this.fileDrop.emit($event.dataTransfer.files);
946
- }
947
- }
948
- // Prevents DOM from trying to open file in browser
949
- onDragOver($event) {
950
- if (this.crisprFileDropzone) {
951
- $event.preventDefault();
952
- }
953
- }
954
- }
955
- FileDropzoneDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: FileDropzoneDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
956
- FileDropzoneDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.2.1", type: FileDropzoneDirective, selector: "[crisprFileDropzone]", inputs: { crisprFileDropzone: "crisprFileDropzone" }, outputs: { fileDrop: "fileDrop" }, host: { listeners: { "drop": "onDrop($event)", "dragover": "onDragOver($event)" } }, ngImport: i0 });
957
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: FileDropzoneDirective, decorators: [{
958
- type: Directive,
959
- args: [{
960
- selector: '[crisprFileDropzone]'
961
- }]
962
- }], propDecorators: { fileDrop: [{
963
- type: Output
964
- }], crisprFileDropzone: [{
965
- type: Input
966
- }], onDrop: [{
967
- type: HostListener,
968
- args: ['drop', ['$event']]
969
- }], onDragOver: [{
970
- type: HostListener,
971
- args: ['dragover', ['$event']]
972
- }] } });
973
-
974
- class SelectedFileComponent {
975
- }
976
- SelectedFileComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: SelectedFileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
977
- SelectedFileComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: SelectedFileComponent, selector: "crispr-selected-file", inputs: { fileName: "fileName", progress: "progress", showProgress: "showProgress", color: "color" }, ngImport: i0, template: "<h3 class=\"mat-h3\">{{ fileName }}</h3>\n<mat-progress-bar\n *ngIf=\"showProgress\"\n mode=\"determinate\"\n [color]=\"color\"\n [value]=\"progress\">\n</mat-progress-bar>\n", styles: ["mat-progress-bar{margin-bottom:8px}\n"], components: [{ type: i1$2.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], preserveWhitespaces: true });
978
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: SelectedFileComponent, decorators: [{
979
- type: Component,
980
- args: [{ selector: 'crispr-selected-file', template: "<h3 class=\"mat-h3\">{{ fileName }}</h3>\n<mat-progress-bar\n *ngIf=\"showProgress\"\n mode=\"determinate\"\n [color]=\"color\"\n [value]=\"progress\">\n</mat-progress-bar>\n", styles: ["mat-progress-bar{margin-bottom:8px}\n"] }]
981
- }], propDecorators: { fileName: [{
982
- type: Input
983
- }], progress: [{
984
- type: Input
985
- }], showProgress: [{
986
- type: Input
987
- }], color: [{
988
- type: Input
989
- }] } });
990
- class SelectedFileModule {
991
- }
992
- SelectedFileModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: SelectedFileModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
993
- SelectedFileModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: SelectedFileModule, declarations: [SelectedFileComponent], imports: [CommonModule,
994
- MatProgressBarModule], exports: [SelectedFileComponent] });
995
- SelectedFileModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: SelectedFileModule, imports: [[
996
- CommonModule,
997
- MatProgressBarModule
998
- ]] });
999
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: SelectedFileModule, decorators: [{
1000
- type: NgModule,
1001
- args: [{
1002
- imports: [
1003
- CommonModule,
1004
- MatProgressBarModule
1005
- ],
1006
- exports: [
1007
- SelectedFileComponent
1008
- ],
1009
- declarations: [
1010
- SelectedFileComponent
1011
- ]
1012
- }]
1013
- }] });
1014
-
1015
- const FileUploadFieldMixin = crisprControlMixin(CrisprFieldComponent);
1016
- class FileUploadFieldComponent extends FileUploadFieldMixin {
1017
- // ngControl: NgControl = null;
1018
- constructor(ngControl) {
1019
- super();
1020
- this.ngControl = ngControl;
1021
- this.defaultConfig = {
1022
- allowMultipleFiles: false,
1023
- acceptedTypes: '*.*',
1024
- dropZoneText: 'DROP FILE HERE',
1025
- selectFilesButtonType: 'button',
1026
- selectButtonText: 'SELECT',
1027
- showClearFilesButton: true,
1028
- clearFilesButtonText: 'CLEAR',
1029
- uploadButtonText: 'UPLOAD',
1030
- uploadButtonType: 'button',
1031
- showUploadProgress: false,
1032
- disableOnUpload: true
1033
- };
1034
- this.isUploaded = false;
1035
- this.fileProgress = [];
1036
- if (this.ngControl != null) {
1037
- // Setting the value accessor directly (instead of using
1038
- // the providers) to avoid running into a circular import.
1039
- ngControl.valueAccessor = this;
1040
- }
1041
- }
1042
- ngOnInit() {
1043
- super.ngOnInit();
1044
- this.disabled$ = this.config.disabledCallback
1045
- ? this.config.disabledCallback(this.group, this.config)
1046
- : of(false);
1047
- }
1048
- filesChanged(files) {
1049
- if (files && files.length > 0) {
1050
- this.selectedFiles = files;
1051
- this.control.patchValue(files);
1052
- }
1053
- }
1054
- uploadFiles() {
1055
- if (this.selectedFiles && this.config.uploadFiles) {
1056
- this.isUploaded = true;
1057
- this.config.uploadFiles(this.group, this.selectedFiles, this);
1058
- }
1059
- }
1060
- resetFileInput() {
1061
- this.fileInputRef.nativeElement.value = '';
1062
- this.control.patchValue(null);
1063
- this.isUploaded = false;
1064
- }
1065
- writeValue(value) {
1066
- // clear file input
1067
- // this.host.nativeElement.value = '';
1068
- // this.file = null;
1069
- }
1070
- registerOnChange(fn) {
1071
- this.onChange = fn;
1072
- }
1073
- registerOnTouched(fn) {
1074
- }
1075
- }
1076
- FileUploadFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: FileUploadFieldComponent, deps: [{ token: i4$1.NgControl, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Component });
1077
- FileUploadFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: FileUploadFieldComponent, selector: "crispr-file-upload-field", viewQueries: [{ propertyName: "fileInputRef", first: true, predicate: ["fileInput"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n <mat-form-field floatLabel=\"always\"\n [color]=\"config.color\"\n appearance=\"outline\"\n [crisprFileDropzone]=\"!(disabled$ | async) && !(config.disableOnUpload && isUploaded)\"\n [formGroup]=\"group\"\n (fileDrop)=\"filesChanged($event)\">\n\n <input [formControlName]=\"config.controlName\" matInput type=\"text\"/>\n <input\n #fileInput\n type=\"file\"\n style=\"display: none\"\n [accept]=\"config.acceptedTypes\"\n [multiple]=\"config.allowMultipleFiles\"\n (change)=\"filesChanged($event.target.files)\"/>\n <mat-label>{{config.label}}</mat-label>\n\n <div *ngIf=\"!(selectedFiles?.length > 0); else selectedFileList\" class=\"drop-info\">\n <mat-icon class=\"drop-icon\" inline=\"true\">cloud_upload</mat-icon>\n <h2 class=\"mat-h2\">{{config.dropZoneText}}</h2>\n or\n <button\n mat-raised-button\n type=\"button\"\n color=\"primary\"\n [disabled]=\"(disabled$ | async) || config.disableOnUpload && isUploaded\"\n (click)=\"fileInput.click()\"\n [attr.aria-label]=\"config.controlName\">\n {{config.selectButtonText}}\n </button>\n </div>\n <ng-template #selectedFileList>\n <div class=\"selected-files-container\">\n <div class=\"selected-files-list\">\n <crispr-selected-file\n *ngFor=\"let file of selectedFiles; let i = index;\"\n [color]=\"config.color === 'primary' ? 'accent' : 'primary'\"\n [fileName]=\"file.name\"\n [showProgress]=\"config.showUploadProgress\"\n [progress]=\"fileProgress && (fileProgress[i] | async)\">\n </crispr-selected-file>\n </div>\n\n </div>\n </ng-template>\n <mat-hint *ngIf=\"config.hint && (control.valid || !control.touched)\">{{config.hint}}</mat-hint>\n </mat-form-field>\n <div class=\"button-container\" *ngIf=\"selectedFiles?.length > 0\">\n\n <button\n mat-button\n (click)=\"resetFileInput()\"\n type=\"button\"\n [disabled]=\"(disabled$ | async) || (config.disableOnUpload && isUploaded)\"\n aria-label=\"Remove Selected File(s)\">\n {{config.clearFilesButtonText}}\n <mat-icon>delete</mat-icon>\n </button>\n\n <button\n *ngIf=\"!!config.uploadFiles\"\n mat-raised-button\n type=\"button\"\n color=\"accent\"\n class=\"file-input-button\"\n [disabled]=\"(disabled$ | async) || (config.disableOnUpload && isUploaded)\"\n (click)=\"uploadFiles()\"\n [attr.aria-label]=\"config.uploadButtonText\">\n {{ config.uploadButtonText }}\n </button>\n\n </div>\n</crispr-field-container>\n", styles: [":host ::ng-deep .mat-form-field .mat-form-field-infix{padding-top:0;display:flex;justify-content:center}:host .drop-info{display:flex;flex-direction:column;align-items:center}:host .drop-info .drop-icon{font-size:36px}:host .drop-info .mat-h2{margin:0}:host .button-container{display:flex;justify-content:flex-end;margin-top:-16px}:host .button-container button{margin-left:8px}:host .selected-files-container{width:100%}:host [matInput]{position:absolute;max-height:0;visibility:hidden}\n"], components: [{ type: i0.forwardRef(function () { return FieldContainerComponent; }), selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }, { type: i0.forwardRef(function () { return i2$1.MatFormField; }), selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: i0.forwardRef(function () { return i4.MatIcon; }), selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i0.forwardRef(function () { return i1.MatButton; }), selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i0.forwardRef(function () { return SelectedFileComponent; }), selector: "crispr-selected-file", inputs: ["fileName", "progress", "showProgress", "color"] }], directives: [{ type: i0.forwardRef(function () { return FileDropzoneDirective; }), selector: "[crisprFileDropzone]", inputs: ["crisprFileDropzone"], outputs: ["fileDrop"] }, { type: i0.forwardRef(function () { return i4$1.NgControlStatusGroup; }), selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i0.forwardRef(function () { return i4$1.FormGroupDirective; }), selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i0.forwardRef(function () { return i5.ControlErrorContainerDirective; }), selector: "[controlErrorContainer], [formGroup]" }, { type: i0.forwardRef(function () { return i7.MatInput; }), selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i0.forwardRef(function () { return i4$1.DefaultValueAccessor; }), selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i0.forwardRef(function () { return i4$1.NgControlStatus; }), selector: "[formControlName],[ngModel],[formControl]" }, { type: i0.forwardRef(function () { return i4$1.FormControlName; }), selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i0.forwardRef(function () { return i5.ControlErrorsDirective; }), selector: "[formControl], [formControlName]" }, { type: i0.forwardRef(function () { return i2$1.MatLabel; }), selector: "mat-label" }, { type: i0.forwardRef(function () { return i2.NgIf; }), selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i0.forwardRef(function () { return i2.NgForOf; }), selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i0.forwardRef(function () { return i2$1.MatHint; }), selector: "mat-hint", inputs: ["align", "id"] }], pipes: { "async": i0.forwardRef(function () { return i2.AsyncPipe; }) }, changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true });
1078
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: FileUploadFieldComponent, decorators: [{
1079
- type: Component,
1080
- args: [{ selector: 'crispr-file-upload-field', changeDetection: ChangeDetectionStrategy.OnPush, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n <mat-form-field floatLabel=\"always\"\n [color]=\"config.color\"\n appearance=\"outline\"\n [crisprFileDropzone]=\"!(disabled$ | async) && !(config.disableOnUpload && isUploaded)\"\n [formGroup]=\"group\"\n (fileDrop)=\"filesChanged($event)\">\n\n <input [formControlName]=\"config.controlName\" matInput type=\"text\"/>\n <input\n #fileInput\n type=\"file\"\n style=\"display: none\"\n [accept]=\"config.acceptedTypes\"\n [multiple]=\"config.allowMultipleFiles\"\n (change)=\"filesChanged($event.target.files)\"/>\n <mat-label>{{config.label}}</mat-label>\n\n <div *ngIf=\"!(selectedFiles?.length > 0); else selectedFileList\" class=\"drop-info\">\n <mat-icon class=\"drop-icon\" inline=\"true\">cloud_upload</mat-icon>\n <h2 class=\"mat-h2\">{{config.dropZoneText}}</h2>\n or\n <button\n mat-raised-button\n type=\"button\"\n color=\"primary\"\n [disabled]=\"(disabled$ | async) || config.disableOnUpload && isUploaded\"\n (click)=\"fileInput.click()\"\n [attr.aria-label]=\"config.controlName\">\n {{config.selectButtonText}}\n </button>\n </div>\n <ng-template #selectedFileList>\n <div class=\"selected-files-container\">\n <div class=\"selected-files-list\">\n <crispr-selected-file\n *ngFor=\"let file of selectedFiles; let i = index;\"\n [color]=\"config.color === 'primary' ? 'accent' : 'primary'\"\n [fileName]=\"file.name\"\n [showProgress]=\"config.showUploadProgress\"\n [progress]=\"fileProgress && (fileProgress[i] | async)\">\n </crispr-selected-file>\n </div>\n\n </div>\n </ng-template>\n <mat-hint *ngIf=\"config.hint && (control.valid || !control.touched)\">{{config.hint}}</mat-hint>\n </mat-form-field>\n <div class=\"button-container\" *ngIf=\"selectedFiles?.length > 0\">\n\n <button\n mat-button\n (click)=\"resetFileInput()\"\n type=\"button\"\n [disabled]=\"(disabled$ | async) || (config.disableOnUpload && isUploaded)\"\n aria-label=\"Remove Selected File(s)\">\n {{config.clearFilesButtonText}}\n <mat-icon>delete</mat-icon>\n </button>\n\n <button\n *ngIf=\"!!config.uploadFiles\"\n mat-raised-button\n type=\"button\"\n color=\"accent\"\n class=\"file-input-button\"\n [disabled]=\"(disabled$ | async) || (config.disableOnUpload && isUploaded)\"\n (click)=\"uploadFiles()\"\n [attr.aria-label]=\"config.uploadButtonText\">\n {{ config.uploadButtonText }}\n </button>\n\n </div>\n</crispr-field-container>\n", styles: [":host ::ng-deep .mat-form-field .mat-form-field-infix{padding-top:0;display:flex;justify-content:center}:host .drop-info{display:flex;flex-direction:column;align-items:center}:host .drop-info .drop-icon{font-size:36px}:host .drop-info .mat-h2{margin:0}:host .button-container{display:flex;justify-content:flex-end;margin-top:-16px}:host .button-container button{margin-left:8px}:host .selected-files-container{width:100%}:host [matInput]{position:absolute;max-height:0;visibility:hidden}\n"] }]
1081
- }], ctorParameters: function () { return [{ type: i4$1.NgControl, decorators: [{
1082
- type: Optional
1083
- }, {
1084
- type: Self
1085
- }] }]; }, propDecorators: { fileInputRef: [{
1086
- type: ViewChild,
1087
- args: ['fileInput']
1088
- }] } });
1089
- class FileUploadFieldModule {
1090
- }
1091
- FileUploadFieldModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: FileUploadFieldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1092
- FileUploadFieldModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: FileUploadFieldModule, declarations: [FileUploadFieldComponent, FileDropzoneDirective], imports: [CommonModule,
1093
- FieldContainerModule,
1094
- ReactiveFormsModule,
1095
- MatIconModule,
1096
- MatButtonModule,
1097
- MatFormFieldModule,
1098
- MatInputModule,
1099
- SelectedFileModule,
1100
- FormValidationHandlerModule], exports: [FileUploadFieldComponent, FileDropzoneDirective] });
1101
- FileUploadFieldModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: FileUploadFieldModule, imports: [[
1102
- CommonModule,
1103
- FieldContainerModule,
1104
- ReactiveFormsModule,
1105
- MatIconModule,
1106
- MatButtonModule,
1107
- MatFormFieldModule,
1108
- MatInputModule,
1109
- SelectedFileModule,
1110
- FormValidationHandlerModule,
1111
- ]] });
1112
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: FileUploadFieldModule, decorators: [{
1113
- type: NgModule,
1114
- args: [{
1115
- imports: [
1116
- CommonModule,
1117
- FieldContainerModule,
1118
- ReactiveFormsModule,
1119
- MatIconModule,
1120
- MatButtonModule,
1121
- MatFormFieldModule,
1122
- MatInputModule,
1123
- SelectedFileModule,
1124
- FormValidationHandlerModule,
1125
- ],
1126
- exports: [
1127
- FileUploadFieldComponent,
1128
- FileDropzoneDirective
1129
- ],
1130
- declarations: [
1131
- FileUploadFieldComponent,
1132
- FileDropzoneDirective
1133
- ]
1134
- }]
1135
- }] });
1136
-
1137
- function convertBytesToMb(bytes) {
1138
- return bytes / 1048576;
1139
- }
1140
-
1141
- const ImageUploadFieldMixin = crisprControlMixin(CrisprFieldComponent);
1142
- class ImageUploadFieldComponent extends ImageUploadFieldMixin {
1143
- constructor(ngControl, domSanitizer, cdr) {
1144
- super();
1145
- this.ngControl = ngControl;
1146
- this.domSanitizer = domSanitizer;
1147
- this.cdr = cdr;
1148
- this.defaultConfig = {
1149
- // allowMultipleFiles: false,
1150
- acceptedTypes: 'image/*',
1151
- dropZoneText: 'DROP FILE HERE',
1152
- selectFilesButtonType: 'button',
1153
- selectButtonText: 'SELECT',
1154
- showClearFilesButton: true,
1155
- clearFilesButtonText: 'CLEAR',
1156
- resetFilesButtonText: 'RESET',
1157
- imagePreviewHeight: '250px',
1158
- compressImage: false,
1159
- targetCompressedImageFileSizeMb: .4,
1160
- minCompressionThresholdMb: .6,
1161
- useWebWorker: true,
1162
- };
1163
- this.inputImageFileSubject = new Subject();
1164
- this.inputImageFile$ = this.inputImageFileSubject.asObservable().pipe(shareReplay(1));
1165
- this.compressedFile$ = this.inputImageFile$.pipe(switchMap(async (file) => {
1166
- if (!file || !(file instanceof File))
1167
- return null;
1168
- const { compressImage, targetCompressedImageFileSizeMb, minCompressionThresholdMb, maxWidthOrHeight, useWebWorker } = this.config;
1169
- const fileSizeMb = convertBytesToMb(file.size);
1170
- const shouldCompress = compressImage
1171
- && targetCompressedImageFileSizeMb < fileSizeMb
1172
- && minCompressionThresholdMb < fileSizeMb;
1173
- if (shouldCompress) {
1174
- const options = {
1175
- // Use maxWidthOrHeight if it was provided, else use target compressed size
1176
- ...(maxWidthOrHeight ? { maxWidthOrHeight } : { maxSizeMB: targetCompressedImageFileSizeMb }),
1177
- useWebWorker,
1178
- maxIterations: 30,
1179
- onProgress: (progress) => {
1180
- this.progress = progress;
1181
- this.cdr.detectChanges();
1182
- }
1183
- };
1184
- return await imageCompression(file, options);
1185
- }
1186
- else
1187
- return file;
1188
- }), map((compressedFile) => {
1189
- if (!compressedFile)
1190
- return compressedFile;
1191
- const { type, name, lastModified } = compressedFile;
1192
- return new File([compressedFile], this.config.fileName || name, {
1193
- type,
1194
- lastModified
1195
- });
1196
- }), tap(file => {
1197
- // only set the value if there is a file because resetToInitialValue sets the control value
1198
- // to initial value and clears the compressed image, so setting it to null here would undo that
1199
- if (file) {
1200
- this.control.setValue(file);
1201
- }
1202
- if (file || this.value) {
1203
- this.control.markAsTouched();
1204
- setTimeout(() => {
1205
- this.cdr.detectChanges();
1206
- }, 100);
1207
- }
1208
- }), shareReplay(1));
1209
- this.compressedImageUrlString$ = this.compressedFile$.pipe(switchMap(async (file) => {
1210
- if (!file)
1211
- return null;
1212
- const compressedStringImage = await imageCompression.getDataUrlFromFile(file);
1213
- return this.domSanitizer.bypassSecurityTrustResourceUrl(compressedStringImage);
1214
- }), shareReplay(1));
1215
- this.isUploaded = false;
1216
- if (this.ngControl != null) {
1217
- // Setting the value accessor directly (instead of using
1218
- // the providers) to avoid running into a circular import.
1219
- ngControl.valueAccessor = this;
1220
- }
1221
- }
1222
- ngOnInit() {
1223
- super.ngOnInit();
1224
- this.imageSrcUrl$ = combineLatest([
1225
- this.compressedImageUrlString$.pipe(startWith(null)),
1226
- this.control.valueChanges.pipe(startWith(this.value), map((controlValue) => {
1227
- if (!controlValue)
1228
- return null;
1229
- if (controlValue instanceof File)
1230
- return null;
1231
- return this.config.mapInputValueToUrl?.(controlValue) || controlValue;
1232
- }))
1233
- ]).pipe(map(([compressedImageUrlString, controlUrl]) => {
1234
- return compressedImageUrlString || controlUrl || null;
1235
- }));
1236
- this.disabled$ = this.config.disabledCallback
1237
- ? this.config.disabledCallback(this.group, this.config)
1238
- : of(false);
1239
- }
1240
- filesChanged(files) {
1241
- if (files && files.length > 0) {
1242
- const imageFile = files[0];
1243
- // We clear the control here so that it is invalid while compressing
1244
- // the input pipeline will take care of resetting it
1245
- this.control.patchValue(null);
1246
- // this.control.setErrors({compressing: {loadingMessage: 'Please wait while file compresses'}});
1247
- this.control.markAsTouched();
1248
- this.inputImageFileSubject.next(imageFile);
1249
- }
1250
- }
1251
- clearFileInput() {
1252
- this.inputImageFileSubject.next(null);
1253
- this.fileInputRef.nativeElement.value = '';
1254
- this.control.patchValue(null);
1255
- this.control.markAsTouched();
1256
- this.isUploaded = false;
1257
- }
1258
- resetToInitialValue(initialValue) {
1259
- this.inputImageFileSubject.next(null);
1260
- this.control.patchValue(initialValue);
1261
- this.isUploaded = false;
1262
- }
1263
- writeValue(value) { }
1264
- registerOnChange(fn) {
1265
- this.onChange = fn;
1266
- }
1267
- registerOnTouched(fn) { }
1268
- }
1269
- ImageUploadFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: ImageUploadFieldComponent, deps: [{ token: i4$1.NgControl, optional: true, self: true }, { token: i2$3.DomSanitizer }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1270
- ImageUploadFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: ImageUploadFieldComponent, selector: "crispr-image-upload-field", viewQueries: [{ propertyName: "fileInputRef", first: true, predicate: ["fileInput"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n\n <mat-form-field floatLabel=\"always\"\n [color]=\"config.color\"\n [appearance]=\"config.appearance\"\n [formGroup]=\"group\">\n <mat-label>{{config.label}}</mat-label>\n <input [formControlName]=\"config.controlName\" matInput type=\"text\"/>\n <input\n #fileInput\n type=\"file\"\n [accept]=\"config.acceptedTypes\"\n (change)=\"filesChanged($event.target.files)\"/>\n <div class=\"ui-container\">\n\n <div class=\"image-preview\" [style.height]=\"config.imagePreviewHeight\">\n <crispr-selected-file\n *ngIf=\"(progress < 100) && inputImageFile$ | async as file; else dropzoneOrPreview\"\n [color]=\"config.color === 'primary' ? 'accent' : 'primary'\"\n [fileName]=\"'Compressing: ' + file.name\"\n [showProgress]=\"true\"\n [progress]=\"progress\">\n </crispr-selected-file>\n\n <ng-template #dropzoneOrPreview>\n <!-- <img *ngIf=\"(initialUrlString$ | async) as initialUrlString;\" [src]=\"initialUrlString\" alt=\"\"> -->\n <img *ngIf=\"imageSrcUrl$ | async as srcUrl; else noImage\" [src]=\"srcUrl\" alt=\"\">\n <ng-template #noImage>\n <div class=\"drop-container\"\n [crisprFileDropzone]=\"!(disabled$ | async)\"\n (fileDrop)=\"filesChanged($event)\">\n <mat-icon class=\"drop-icon\" inline=\"true\">cloud_upload</mat-icon>\n <h2 class=\"mat-h2\">{{config.dropZoneText}}</h2>\n </div>\n </ng-template>\n\n </ng-template>\n </div>\n\n\n\n <!-- </ng-template> -->\n <div class=\"button-container\" *ngIf=\"true\">\n\n <button\n mat-button\n (click)=\"clearFileInput()\"\n type=\"button\"\n [disabled]=\"(disabled$ | async)\"\n aria-label=\"Remove Selected File(s)\">\n <mat-icon>delete</mat-icon>\n {{config.clearFilesButtonText}}\n </button>\n\n <button\n *ngIf=\"value\"\n mat-button\n (click)=\"resetToInitialValue(value)\"\n type=\"button\"\n [disabled]=\"(disabled$ | async)\"\n aria-label=\"Remove Selected File(s)\">\n <mat-icon>replay</mat-icon>\n {{config.resetFilesButtonText}}\n </button>\n\n <button\n mat-button\n type=\"button\"\n color=\"primary\"\n [disabled]=\"(disabled$ | async)\"\n (click)=\"fileInput.click()\"\n [attr.aria-label]=\"config.controlName\">\n <mat-icon>\n camera\n </mat-icon>\n SELECT\n </button>\n </div>\n </div>\n\n <mat-hint *ngIf=\"config.hint && (control.valid || !control.touched)\">{{config.hint}}</mat-hint>\n\n </mat-form-field>\n\n</crispr-field-container>\n", styles: [":host ::ng-deep .mat-form-field .mat-form-field-infix{padding-top:0}:host ::ng-deep .mat-form-field .mat-button-wrapper{display:flex;flex-direction:column;align-items:center;padding-top:8px}:host .ui-container{display:flex;flex-direction:column}:host .ui-container .image-preview{display:flex;flex-direction:column;align-content:space-between;justify-content:center;align-items:center;margin:8px 0;flex-grow:1}:host .ui-container .image-preview crispr-selected-file{width:100%}:host .ui-container .image-preview .drop-container{display:flex;box-sizing:border-box;flex-direction:column;align-items:center;border:3px dashed gray;height:100%;width:100%;align-content:center;justify-content:center;border-radius:8px}:host .ui-container .image-preview .drop-container .drop-icon{height:32px;width:32px;font-size:36px}:host .ui-container .image-preview .drop-container .mat-h2{margin:0}:host .ui-container .image-preview img{height:inherit;max-width:100%}:host .ui-container .button-container{display:flex;flex-direction:var(--image-upload-button-container-direction);justify-content:flex-end}:host .ui-container .button-container button{margin-left:8px}:host input{position:absolute;max-height:0;visibility:hidden}\n"], components: [{ type: FieldContainerComponent, selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }, { type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["color", "appearance", "hideRequiredMarker", "hintLabel", "floatLabel"], exportAs: ["matFormField"] }, { type: SelectedFileComponent, selector: "crispr-selected-file", inputs: ["fileName", "progress", "showProgress", "color"] }, { type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i1.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }], directives: [{ type: i4$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i4$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5.ControlErrorContainerDirective, selector: "[controlErrorContainer], [formGroup]" }, { type: i2$1.MatLabel, selector: "mat-label" }, { type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { type: i4$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i4$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i5.ControlErrorsDirective, selector: "[formControl], [formControlName]" }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: FileDropzoneDirective, selector: "[crisprFileDropzone]", inputs: ["crisprFileDropzone"], outputs: ["fileDrop"] }, { type: i2$1.MatHint, selector: "mat-hint", inputs: ["align", "id"] }], pipes: { "async": i2.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true });
1271
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: ImageUploadFieldComponent, decorators: [{
1272
- type: Component,
1273
- args: [{ selector: 'crispr-image-upload-field', changeDetection: ChangeDetectionStrategy.OnPush, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n\n <mat-form-field floatLabel=\"always\"\n [color]=\"config.color\"\n [appearance]=\"config.appearance\"\n [formGroup]=\"group\">\n <mat-label>{{config.label}}</mat-label>\n <input [formControlName]=\"config.controlName\" matInput type=\"text\"/>\n <input\n #fileInput\n type=\"file\"\n [accept]=\"config.acceptedTypes\"\n (change)=\"filesChanged($event.target.files)\"/>\n <div class=\"ui-container\">\n\n <div class=\"image-preview\" [style.height]=\"config.imagePreviewHeight\">\n <crispr-selected-file\n *ngIf=\"(progress < 100) && inputImageFile$ | async as file; else dropzoneOrPreview\"\n [color]=\"config.color === 'primary' ? 'accent' : 'primary'\"\n [fileName]=\"'Compressing: ' + file.name\"\n [showProgress]=\"true\"\n [progress]=\"progress\">\n </crispr-selected-file>\n\n <ng-template #dropzoneOrPreview>\n <!-- <img *ngIf=\"(initialUrlString$ | async) as initialUrlString;\" [src]=\"initialUrlString\" alt=\"\"> -->\n <img *ngIf=\"imageSrcUrl$ | async as srcUrl; else noImage\" [src]=\"srcUrl\" alt=\"\">\n <ng-template #noImage>\n <div class=\"drop-container\"\n [crisprFileDropzone]=\"!(disabled$ | async)\"\n (fileDrop)=\"filesChanged($event)\">\n <mat-icon class=\"drop-icon\" inline=\"true\">cloud_upload</mat-icon>\n <h2 class=\"mat-h2\">{{config.dropZoneText}}</h2>\n </div>\n </ng-template>\n\n </ng-template>\n </div>\n\n\n\n <!-- </ng-template> -->\n <div class=\"button-container\" *ngIf=\"true\">\n\n <button\n mat-button\n (click)=\"clearFileInput()\"\n type=\"button\"\n [disabled]=\"(disabled$ | async)\"\n aria-label=\"Remove Selected File(s)\">\n <mat-icon>delete</mat-icon>\n {{config.clearFilesButtonText}}\n </button>\n\n <button\n *ngIf=\"value\"\n mat-button\n (click)=\"resetToInitialValue(value)\"\n type=\"button\"\n [disabled]=\"(disabled$ | async)\"\n aria-label=\"Remove Selected File(s)\">\n <mat-icon>replay</mat-icon>\n {{config.resetFilesButtonText}}\n </button>\n\n <button\n mat-button\n type=\"button\"\n color=\"primary\"\n [disabled]=\"(disabled$ | async)\"\n (click)=\"fileInput.click()\"\n [attr.aria-label]=\"config.controlName\">\n <mat-icon>\n camera\n </mat-icon>\n SELECT\n </button>\n </div>\n </div>\n\n <mat-hint *ngIf=\"config.hint && (control.valid || !control.touched)\">{{config.hint}}</mat-hint>\n\n </mat-form-field>\n\n</crispr-field-container>\n", styles: [":host ::ng-deep .mat-form-field .mat-form-field-infix{padding-top:0}:host ::ng-deep .mat-form-field .mat-button-wrapper{display:flex;flex-direction:column;align-items:center;padding-top:8px}:host .ui-container{display:flex;flex-direction:column}:host .ui-container .image-preview{display:flex;flex-direction:column;align-content:space-between;justify-content:center;align-items:center;margin:8px 0;flex-grow:1}:host .ui-container .image-preview crispr-selected-file{width:100%}:host .ui-container .image-preview .drop-container{display:flex;box-sizing:border-box;flex-direction:column;align-items:center;border:3px dashed gray;height:100%;width:100%;align-content:center;justify-content:center;border-radius:8px}:host .ui-container .image-preview .drop-container .drop-icon{height:32px;width:32px;font-size:36px}:host .ui-container .image-preview .drop-container .mat-h2{margin:0}:host .ui-container .image-preview img{height:inherit;max-width:100%}:host .ui-container .button-container{display:flex;flex-direction:var(--image-upload-button-container-direction);justify-content:flex-end}:host .ui-container .button-container button{margin-left:8px}:host input{position:absolute;max-height:0;visibility:hidden}\n"] }]
1274
- }], ctorParameters: function () { return [{ type: i4$1.NgControl, decorators: [{
1275
- type: Optional
1276
- }, {
1277
- type: Self
1278
- }] }, { type: i2$3.DomSanitizer }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { fileInputRef: [{
1279
- type: ViewChild,
1280
- args: ['fileInput']
1281
- }] } });
1282
- class ImageUploadFieldModule {
1283
- }
1284
- ImageUploadFieldModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: ImageUploadFieldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1285
- ImageUploadFieldModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: ImageUploadFieldModule, declarations: [ImageUploadFieldComponent], imports: [CommonModule,
1286
- FieldContainerModule,
1287
- ReactiveFormsModule,
1288
- MatIconModule,
1289
- MatButtonModule,
1290
- MatFormFieldModule,
1291
- MatInputModule,
1292
- SelectedFileModule,
1293
- FileUploadFieldModule,
1294
- FormValidationHandlerModule], exports: [ImageUploadFieldComponent] });
1295
- ImageUploadFieldModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: ImageUploadFieldModule, imports: [[
1296
- CommonModule,
1297
- FieldContainerModule,
1298
- ReactiveFormsModule,
1299
- MatIconModule,
1300
- MatButtonModule,
1301
- MatFormFieldModule,
1302
- MatInputModule,
1303
- SelectedFileModule,
1304
- FileUploadFieldModule,
1305
- FormValidationHandlerModule
1306
- ]] });
1307
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: ImageUploadFieldModule, decorators: [{
1308
- type: NgModule,
1309
- args: [{
1310
- imports: [
1311
- CommonModule,
1312
- FieldContainerModule,
1313
- ReactiveFormsModule,
1314
- MatIconModule,
1315
- MatButtonModule,
1316
- MatFormFieldModule,
1317
- MatInputModule,
1318
- SelectedFileModule,
1319
- FileUploadFieldModule,
1320
- FormValidationHandlerModule
1321
- ],
1322
- exports: [
1323
- ImageUploadFieldComponent
1324
- ],
1325
- declarations: [
1326
- ImageUploadFieldComponent
1327
- ]
1328
- }]
1329
- }] });
1330
- function maxFileSizeValidator(maxFileSize) {
1331
- return (control) => {
1332
- const controlValue = control.value;
1333
- if (!(controlValue instanceof File)) {
1334
- return null;
1335
- }
1336
- const actualFileSize = +convertBytesToMb(controlValue.size).toPrecision(3);
1337
- if (maxFileSize > actualFileSize)
1338
- return null;
1339
- return { maxFileSize: { maxFileSize, actualFileSize } };
1340
- };
1341
- }
1342
- function allowedFileExtValidator(allowedFileExtensions, onlyAllowFiles = true) {
1343
- return (control) => {
1344
- const controlValue = control.value;
1345
- const isFile = controlValue instanceof File;
1346
- if (!onlyAllowFiles && !isFile)
1347
- return null;
1348
- const actualExtension = isFile ? controlValue.name.split('.').pop().toLocaleLowerCase() : 'Not a file';
1349
- const isAllowedExtension = allowedFileExtensions.includes(actualExtension);
1350
- if (isAllowedExtension) {
1351
- return null;
1352
- }
1353
- return { allowedExtension: { allowedFileExtensions, actualExtension } };
1354
- };
1355
- }
1356
- function allowedFileType(matchExp) {
1357
- return (formControl) => {
1358
- const value = formControl.value;
1359
- if (!(value instanceof File))
1360
- return null;
1361
- const type = value.type;
1362
- const matches = type.match(matchExp);
1363
- if (!type || !matches?.length) {
1364
- return {
1365
- allowedFileType: {
1366
- actualType: type,
1367
- allowedTypeExp: matchExp
1368
- }
1369
- };
1370
- }
1371
- else {
1372
- return null;
1373
- }
1374
- };
1375
- }
1376
-
1377
- // TODO: Should we import UI library?
1378
- // Will the tree shaker shake the unused modules?
1379
- const MAT_DESIGN_MODULES = [
1380
- MatIconModule,
1381
- MatAutocompleteModule,
1382
- MatDatepickerModule,
1383
- MatInputModule,
1384
- MatRadioModule,
1385
- MatSelectModule,
1386
- MatCheckboxModule,
1387
- MatChipsModule,
1388
- MatSliderModule,
1389
- MatSlideToggleModule,
1390
- MatButtonModule,
1391
- MatButtonToggleModule,
1392
- MatChipsModule,
1393
- MatTooltipModule,
1394
- MatFormFieldModule,
1395
- MatMomentDateModule,
1396
- MatDividerModule,
1397
- MatProgressBarModule,
1398
- PortalModule
1399
- ];
1400
- const CRISPR_FIELDS = [
1401
- InputFieldComponent,
1402
- SelectFieldComponent,
1403
- RadioFieldComponent,
1404
- AutocompleteFieldComponent,
1405
- AutocompleteChiplistFieldComponent,
1406
- CheckboxFieldComponent,
1407
- TextareaFieldComponent,
1408
- DatepickerFieldComponent,
1409
- SliderFieldComponent,
1410
- ButtonComponent,
1411
- DividerComponent,
1412
- UnitConversionFieldComponent,
1413
- OptionComponent,
1414
- ];
1415
- class MaterialModule {
1416
- }
1417
- MaterialModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: MaterialModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1418
- MaterialModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: MaterialModule, declarations: [InputFieldComponent,
1419
- SelectFieldComponent,
1420
- RadioFieldComponent,
1421
- AutocompleteFieldComponent,
1422
- AutocompleteChiplistFieldComponent,
1423
- CheckboxFieldComponent,
1424
- TextareaFieldComponent,
1425
- DatepickerFieldComponent,
1426
- SliderFieldComponent,
1427
- ButtonComponent,
1428
- DividerComponent,
1429
- UnitConversionFieldComponent,
1430
- OptionComponent], imports: [CommonModule,
1431
- ReactiveFormsModule,
1432
- FormValidationHandlerModule,
1433
- InfoModule,
1434
- FileUploadFieldModule,
1435
- HeadingModule,
1436
- FieldContainerModule, MatIconModule,
1437
- MatAutocompleteModule,
1438
- MatDatepickerModule,
1439
- MatInputModule,
1440
- MatRadioModule,
1441
- MatSelectModule,
1442
- MatCheckboxModule,
1443
- MatChipsModule,
1444
- MatSliderModule,
1445
- MatSlideToggleModule,
1446
- MatButtonModule,
1447
- MatButtonToggleModule,
1448
- MatChipsModule,
1449
- MatTooltipModule,
1450
- MatFormFieldModule,
1451
- MatMomentDateModule,
1452
- MatDividerModule,
1453
- MatProgressBarModule,
1454
- PortalModule], exports: [MatIconModule,
1455
- MatAutocompleteModule,
1456
- MatDatepickerModule,
1457
- MatInputModule,
1458
- MatRadioModule,
1459
- MatSelectModule,
1460
- MatCheckboxModule,
1461
- MatChipsModule,
1462
- MatSliderModule,
1463
- MatSlideToggleModule,
1464
- MatButtonModule,
1465
- MatButtonToggleModule,
1466
- MatChipsModule,
1467
- MatTooltipModule,
1468
- MatFormFieldModule,
1469
- MatMomentDateModule,
1470
- MatDividerModule,
1471
- MatProgressBarModule,
1472
- PortalModule, InputFieldComponent,
1473
- SelectFieldComponent,
1474
- RadioFieldComponent,
1475
- AutocompleteFieldComponent,
1476
- AutocompleteChiplistFieldComponent,
1477
- CheckboxFieldComponent,
1478
- TextareaFieldComponent,
1479
- DatepickerFieldComponent,
1480
- SliderFieldComponent,
1481
- ButtonComponent,
1482
- DividerComponent,
1483
- UnitConversionFieldComponent,
1484
- OptionComponent] });
1485
- MaterialModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: MaterialModule, imports: [[
1486
- CommonModule,
1487
- ReactiveFormsModule,
1488
- FormValidationHandlerModule,
1489
- InfoModule,
1490
- FileUploadFieldModule,
1491
- HeadingModule,
1492
- FieldContainerModule,
1493
- ...MAT_DESIGN_MODULES,
1494
- ], MatIconModule,
1495
- MatAutocompleteModule,
1496
- MatDatepickerModule,
1497
- MatInputModule,
1498
- MatRadioModule,
1499
- MatSelectModule,
1500
- MatCheckboxModule,
1501
- MatChipsModule,
1502
- MatSliderModule,
1503
- MatSlideToggleModule,
1504
- MatButtonModule,
1505
- MatButtonToggleModule,
1506
- MatChipsModule,
1507
- MatTooltipModule,
1508
- MatFormFieldModule,
1509
- MatMomentDateModule,
1510
- MatDividerModule,
1511
- MatProgressBarModule,
1512
- PortalModule] });
1513
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: MaterialModule, decorators: [{
1514
- type: NgModule,
1515
- args: [{
1516
- imports: [
1517
- CommonModule,
1518
- ReactiveFormsModule,
1519
- FormValidationHandlerModule,
1520
- InfoModule,
1521
- FileUploadFieldModule,
1522
- HeadingModule,
1523
- FieldContainerModule,
1524
- ...MAT_DESIGN_MODULES,
1525
- ],
1526
- exports: [
1527
- ...MAT_DESIGN_MODULES,
1528
- ...CRISPR_FIELDS
1529
- ],
1530
- declarations: [
1531
- ...CRISPR_FIELDS,
1532
- ]
1533
- }]
1534
- }] });
1535
-
1536
- var index$2 = /*#__PURE__*/Object.freeze({
1537
- __proto__: null,
1538
- InputFieldComponent: InputFieldComponent,
1539
- SelectFieldComponent: SelectFieldComponent,
1540
- AutocompleteFieldComponent: AutocompleteFieldComponent,
1541
- AutocompleteChiplistFieldComponent: AutocompleteChiplistFieldComponent,
1542
- CheckboxFieldComponent: CheckboxFieldComponent,
1543
- TextareaFieldComponent: TextareaFieldComponent,
1544
- SliderFieldComponent: SliderFieldComponent,
1545
- ButtonComponent: ButtonComponent,
1546
- DatepickerFieldComponent: DatepickerFieldComponent,
1547
- HeadingComponent: HeadingComponent,
1548
- HeadingModule: HeadingModule,
1549
- DividerComponent: DividerComponent,
1550
- RadioFieldComponent: RadioFieldComponent,
1551
- UnitConversionFieldComponent: UnitConversionFieldComponent,
1552
- ImageUploadFieldComponent: ImageUploadFieldComponent,
1553
- ImageUploadFieldModule: ImageUploadFieldModule,
1554
- maxFileSizeValidator: maxFileSizeValidator,
1555
- allowedFileExtValidator: allowedFileExtValidator,
1556
- allowedFileType: allowedFileType,
1557
- FileDropzoneDirective: FileDropzoneDirective,
1558
- FileUploadFieldComponent: FileUploadFieldComponent,
1559
- FileUploadFieldModule: FileUploadFieldModule,
1560
- MaterialModule: MaterialModule,
1561
- OptionComponent: OptionComponent
1562
- });
14
+ import * as i3$2 from '@angular/material/icon';
15
+ import { MatIconModule } from '@angular/material/icon';
16
+ import * as i3 from '@tft/crispr-forms/ui';
17
+ import { FieldContainerComponent } from '@tft/crispr-forms/ui';
18
+ export * from '@tft/crispr-forms/ui';
1563
19
 
1564
20
  const FIELD_COMPONENTS = {
1565
21
  groupList: Promise.resolve().then(function () { return index$1; }).then(({ FormGroupListComponent }) => FormGroupListComponent),
1566
22
  subGroup: Promise.resolve().then(function () { return index; }).then(({ SubGroupComponent }) => SubGroupComponent),
1567
- button: Promise.resolve().then(function () { return index$2; }).then(({ ButtonComponent }) => ButtonComponent),
1568
- input: Promise.resolve().then(function () { return index$2; }).then(({ InputFieldComponent }) => InputFieldComponent),
1569
- select: Promise.resolve().then(function () { return index$2; }).then(({ SelectFieldComponent }) => SelectFieldComponent),
1570
- radio: Promise.resolve().then(function () { return index$2; }).then(({ RadioFieldComponent }) => RadioFieldComponent),
1571
- autocomplete: Promise.resolve().then(function () { return index$2; }).then(({ AutocompleteFieldComponent }) => AutocompleteFieldComponent),
1572
- autocompleteChiplist: Promise.resolve().then(function () { return index$2; }).then(({ AutocompleteChiplistFieldComponent }) => AutocompleteChiplistFieldComponent),
1573
- textarea: Promise.resolve().then(function () { return index$2; }).then(({ TextareaFieldComponent }) => TextareaFieldComponent),
1574
- checkbox: Promise.resolve().then(function () { return index$2; }).then(({ CheckboxFieldComponent }) => CheckboxFieldComponent),
1575
- slider: Promise.resolve().then(function () { return index$2; }).then(({ SliderFieldComponent }) => SliderFieldComponent),
1576
- datepicker: Promise.resolve().then(function () { return index$2; }).then(({ DatepickerFieldComponent }) => DatepickerFieldComponent),
1577
- fileUpload: Promise.resolve().then(function () { return index$2; }).then(({ FileUploadFieldComponent }) => FileUploadFieldComponent),
1578
- imageUpload: Promise.resolve().then(function () { return index$2; }).then(({ ImageUploadFieldComponent }) => ImageUploadFieldComponent),
1579
- heading: Promise.resolve().then(function () { return index$2; }).then(({ HeadingComponent }) => HeadingComponent),
1580
- divider: Promise.resolve().then(function () { return index$2; }).then(({ DividerComponent }) => DividerComponent),
1581
- unitConversion: Promise.resolve().then(function () { return index$2; }).then(({ UnitConversionFieldComponent }) => UnitConversionFieldComponent)
23
+ button: import('@tft/crispr-forms/ui').then(({ ButtonComponent }) => ButtonComponent),
24
+ input: import('@tft/crispr-forms/ui').then(({ InputFieldComponent }) => InputFieldComponent),
25
+ select: import('@tft/crispr-forms/ui').then(({ SelectFieldComponent }) => SelectFieldComponent),
26
+ radio: import('@tft/crispr-forms/ui').then(({ RadioFieldComponent }) => RadioFieldComponent),
27
+ autocomplete: import('@tft/crispr-forms/ui').then(({ AutocompleteFieldComponent }) => AutocompleteFieldComponent),
28
+ autocompleteChiplist: import('@tft/crispr-forms/ui').then(({ AutocompleteChiplistFieldComponent }) => AutocompleteChiplistFieldComponent),
29
+ textarea: import('@tft/crispr-forms/ui').then(({ TextareaFieldComponent }) => TextareaFieldComponent),
30
+ checkbox: import('@tft/crispr-forms/ui').then(({ CheckboxFieldComponent }) => CheckboxFieldComponent),
31
+ slider: import('@tft/crispr-forms/ui').then(({ SliderFieldComponent }) => SliderFieldComponent),
32
+ datepicker: import('@tft/crispr-forms/ui').then(({ DatepickerFieldComponent }) => DatepickerFieldComponent),
33
+ fileUpload: import('@tft/crispr-forms/ui').then(({ FileUploadFieldComponent }) => FileUploadFieldComponent),
34
+ imageUpload: import('@tft/crispr-forms/ui/image-upload-field').then(({ ImageUploadFieldComponent }) => ImageUploadFieldComponent),
35
+ heading: import('@tft/crispr-forms/ui').then(({ HeadingComponent }) => HeadingComponent),
36
+ divider: import('@tft/crispr-forms/ui').then(({ DividerComponent }) => DividerComponent),
37
+ unitConversion: import('@tft/crispr-forms/ui').then(({ UnitConversionFieldComponent }) => UnitConversionFieldComponent)
1582
38
  };
1583
39
  function isControlComponent(component) {
1584
40
  return component && isControlConfig(component.config) && 'value' in component; // || component.config.controlType === ControlType.BUTTON;
@@ -1636,12 +92,13 @@ class CrisprFieldDirective {
1636
92
  }
1637
93
  }
1638
94
  }
1639
- CrisprFieldDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CrisprFieldDirective, deps: [{ token: i0.ViewContainerRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
1640
- CrisprFieldDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.2.1", type: CrisprFieldDirective, selector: "[crisprField]", inputs: { config: "config", group: "group", value: "value" }, ngImport: i0 });
1641
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CrisprFieldDirective, decorators: [{
95
+ CrisprFieldDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: CrisprFieldDirective, deps: [{ token: i0.ViewContainerRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
96
+ CrisprFieldDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.0.1", type: CrisprFieldDirective, isStandalone: true, selector: "[crisprField]", inputs: { config: "config", group: "group", value: "value" }, ngImport: i0 });
97
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: CrisprFieldDirective, decorators: [{
1642
98
  type: Directive,
1643
99
  args: [{
1644
- selector: '[crisprField]'
100
+ selector: '[crisprField]',
101
+ standalone: true
1645
102
  }]
1646
103
  }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { config: [{
1647
104
  type: Input
@@ -1649,28 +106,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImpor
1649
106
  type: Input
1650
107
  }], value: [{
1651
108
  type: Input
1652
- }] } });
1653
- class CrisprFieldModule {
1654
- }
1655
- CrisprFieldModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CrisprFieldModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1656
- CrisprFieldModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CrisprFieldModule, declarations: [CrisprFieldDirective], imports: [CommonModule], exports: [CrisprFieldDirective] });
1657
- CrisprFieldModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CrisprFieldModule, imports: [[
1658
- CommonModule,
1659
- ]] });
1660
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CrisprFieldModule, decorators: [{
1661
- type: NgModule,
1662
- args: [{
1663
- imports: [
1664
- CommonModule,
1665
- ],
1666
- exports: [
1667
- CrisprFieldDirective
1668
- ],
1669
- declarations: [
1670
- CrisprFieldDirective
1671
- ]
1672
- }]
1673
- }] });
109
+ }] } });
1674
110
 
1675
111
  class InitialControlValuePipe {
1676
112
  // TODO: does changing any to unknown break anything?
@@ -1680,15 +116,35 @@ class InitialControlValuePipe {
1680
116
  : null;
1681
117
  }
1682
118
  }
1683
- InitialControlValuePipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: InitialControlValuePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
1684
- InitialControlValuePipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: InitialControlValuePipe, name: "initialControlValue" });
1685
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: InitialControlValuePipe, decorators: [{
119
+ InitialControlValuePipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: InitialControlValuePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
120
+ InitialControlValuePipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.0.1", ngImport: i0, type: InitialControlValuePipe, name: "initialControlValue" });
121
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: InitialControlValuePipe, decorators: [{
1686
122
  type: Pipe,
1687
123
  args: [{
1688
124
  name: 'initialControlValue'
1689
125
  }]
1690
126
  }] });
1691
127
 
128
+ class CrisprPipesModule {
129
+ }
130
+ CrisprPipesModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: CrisprPipesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
131
+ CrisprPipesModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.0.1", ngImport: i0, type: CrisprPipesModule, declarations: [InitialControlValuePipe], imports: [CommonModule], exports: [InitialControlValuePipe] });
132
+ CrisprPipesModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: CrisprPipesModule, imports: [CommonModule] });
133
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: CrisprPipesModule, decorators: [{
134
+ type: NgModule,
135
+ args: [{
136
+ imports: [
137
+ CommonModule
138
+ ],
139
+ exports: [
140
+ InitialControlValuePipe
141
+ ],
142
+ declarations: [
143
+ InitialControlValuePipe
144
+ ]
145
+ }]
146
+ }] });
147
+
1692
148
  class CrisprFormComponent {
1693
149
  constructor() {
1694
150
  this.form = new FormGroup({});
@@ -1710,11 +166,17 @@ class CrisprFormComponent {
1710
166
  this.submitTrigger.nativeElement.click();
1711
167
  }
1712
168
  }
1713
- CrisprFormComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CrisprFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1714
- CrisprFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: CrisprFormComponent, selector: "crispr-form", inputs: { config: "config", form: "form", value: "value" }, outputs: { submitted: "submitted", valueChanges: "valueChanges", statusChanges: "statusChanges" }, viewQueries: [{ propertyName: "submitTrigger", first: true, predicate: ["submitTrigger"], descendants: true }], ngImport: i0, template: "<form\n class=\"crispr-form\"\n [ngClass]=\"config.classes\"\n [formGroup]=\"form\"\n (ngSubmit)=\"handleSubmit()\"\n [autocomplete]=\"config.autocomplete || 'off'\"\n [errorDictionary]=\"config.errorDictionary\"\n #ngFormElement=\"ngForm\">\n\n <ng-container\n *ngFor=\"let field of config.fields;\"\n crisprField\n [value]=\"value | initialControlValue : field\"\n [config]=\"field\"\n [group]=\"form\">\n </ng-container>\n <!-- Hidden button, programmatically clicked when crispr form triggerSubmit function called.\n Uses a hidden button with type=\"submit\" because it will trigger both native form submit event\n (which the error handler has to listen for) and ngSubmit event -->\n <button #submitTrigger class=\"submit-trigger\" type=\"submit\">\n </button>\n</form>\n", styles: [".submit-trigger{display:none}\n"], directives: [{ type: i4$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i4$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i5.ControlErrorsFormDirective, selector: "form", inputs: ["errorDictionary"] }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i4$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5.ControlErrorContainerDirective, selector: "[controlErrorContainer], [formGroup]" }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: CrisprFieldDirective, selector: "[crisprField]", inputs: ["config", "group", "value"] }], pipes: { "initialControlValue": InitialControlValuePipe }, preserveWhitespaces: true });
1715
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CrisprFormComponent, decorators: [{
169
+ CrisprFormComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: CrisprFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
170
+ CrisprFormComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.1", type: CrisprFormComponent, isStandalone: true, selector: "crispr-form", inputs: { config: "config", form: "form", value: "value" }, outputs: { submitted: "submitted", valueChanges: "valueChanges", statusChanges: "statusChanges" }, viewQueries: [{ propertyName: "submitTrigger", first: true, predicate: ["submitTrigger"], descendants: true }], ngImport: i0, template: "<form\n class=\"crispr-form\"\n [ngClass]=\"config.classes\"\n [formGroup]=\"form\"\n (ngSubmit)=\"handleSubmit()\"\n [autocomplete]=\"config.autocomplete || 'off'\"\n [errorDictionary]=\"config.errorDictionary\"\n #ngFormElement=\"ngForm\">\n\n <ng-container\n *ngFor=\"let field of config.fields;\"\n crisprField\n [value]=\"value | initialControlValue : field\"\n [config]=\"field\"\n [group]=\"form\">\n </ng-container>\n <!-- Hidden button, programmatically clicked when crispr form triggerSubmit function called.\n Uses a hidden button with type=\"submit\" because it will trigger both native form submit event\n (which the error handler has to listen for) and ngSubmit event -->\n <button #submitTrigger class=\"submit-trigger\" type=\"submit\">\n </button>\n</form>\n", styles: [".submit-trigger{display:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: CrisprFieldDirective, selector: "[crisprField]", inputs: ["config", "group", "value"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FormValidationHandlerModule }, { kind: "directive", type: i3$1.ControlErrorsFormDirective, selector: "form", inputs: ["errorDictionary"] }, { kind: "directive", type: i3$1.ControlErrorContainerDirective, selector: "[controlErrorContainer], [formGroup]" }, { kind: "ngmodule", type: CrisprPipesModule }, { kind: "pipe", type: InitialControlValuePipe, name: "initialControlValue" }], preserveWhitespaces: true });
171
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: CrisprFormComponent, decorators: [{
1716
172
  type: Component,
1717
- args: [{ selector: 'crispr-form', template: "<form\n class=\"crispr-form\"\n [ngClass]=\"config.classes\"\n [formGroup]=\"form\"\n (ngSubmit)=\"handleSubmit()\"\n [autocomplete]=\"config.autocomplete || 'off'\"\n [errorDictionary]=\"config.errorDictionary\"\n #ngFormElement=\"ngForm\">\n\n <ng-container\n *ngFor=\"let field of config.fields;\"\n crisprField\n [value]=\"value | initialControlValue : field\"\n [config]=\"field\"\n [group]=\"form\">\n </ng-container>\n <!-- Hidden button, programmatically clicked when crispr form triggerSubmit function called.\n Uses a hidden button with type=\"submit\" because it will trigger both native form submit event\n (which the error handler has to listen for) and ngSubmit event -->\n <button #submitTrigger class=\"submit-trigger\" type=\"submit\">\n </button>\n</form>\n", styles: [".submit-trigger{display:none}\n"] }]
173
+ args: [{ selector: 'crispr-form', standalone: true, imports: [
174
+ CommonModule,
175
+ CrisprFieldDirective,
176
+ ReactiveFormsModule,
177
+ FormValidationHandlerModule,
178
+ CrisprPipesModule
179
+ ], template: "<form\n class=\"crispr-form\"\n [ngClass]=\"config.classes\"\n [formGroup]=\"form\"\n (ngSubmit)=\"handleSubmit()\"\n [autocomplete]=\"config.autocomplete || 'off'\"\n [errorDictionary]=\"config.errorDictionary\"\n #ngFormElement=\"ngForm\">\n\n <ng-container\n *ngFor=\"let field of config.fields;\"\n crisprField\n [value]=\"value | initialControlValue : field\"\n [config]=\"field\"\n [group]=\"form\">\n </ng-container>\n <!-- Hidden button, programmatically clicked when crispr form triggerSubmit function called.\n Uses a hidden button with type=\"submit\" because it will trigger both native form submit event\n (which the error handler has to listen for) and ngSubmit event -->\n <button #submitTrigger class=\"submit-trigger\" type=\"submit\">\n </button>\n</form>\n", styles: [".submit-trigger{display:none}\n"] }]
1718
180
  }], propDecorators: { config: [{
1719
181
  type: Input
1720
182
  }], form: [{
@@ -1790,82 +252,25 @@ class FormGroupListComponent extends FormGroupListMixin {
1790
252
  this.control.removeAt(index);
1791
253
  }
1792
254
  }
1793
- FormGroupListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: FormGroupListComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1794
- FormGroupListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: FormGroupListComponent, selector: "crispr-form-group-list", usesInheritance: true, ngImport: i0, template: "\n<crispr-field-container\n [config]=\"config\"\n [group]=\"group\"\n [formGroup]=\"group\">\n\n <div [formArrayName]=\"config.controlName\">\n <!-- Don't add trackBy function, it confuses the state of the array -->\n <div *ngFor=\"let con of control?.controls; let i = index;\">\n <!-- TODO: use content projection to allow custom item label component -->\n <div class=\"item-header\">\n <span class=\"mat-h2\"> {{ config.itemLabelBuilder ? config.itemLabelBuilder(i) : 'Item ' + (i + 1) }} </span>\n <button\n mat-icon-button\n type=\"button\"\n *ngIf=\"i + 1 > config.minListLength\">\n <mat-icon (click)=\"clickDelete(i)\">delete</mat-icon>\n </button>\n </div>\n <div\n [formGroup]=\"con\">\n <!-- TODO: if chiplists didn't need to have labels mixed in with their values we could use [value]=\"control.value\" below -->\n <ng-container\n *ngFor=\"let field of config.itemConfig.fields;\"\n crisprField\n [value]=\"blockValue ? null : value && value[i] | initialControlValue : field\"\n [config]=\"field\"\n [group]=\"con\">\n </ng-container>\n </div>\n </div>\n </div>\n <div class=\"group-footer\">\n <button\n type=\"button\"\n class=\"add\"\n mat-raised-button\n [color]=\"config.addButtonColor\"\n (click)=\"clickAdd()\">\n {{config.addItemLabel || config.addButtonLabel}}\n </button>\n </div>\n\n</crispr-field-container>\n", styles: [".item-header{display:flex;justify-content:space-between}.group-footer{display:flex;justify-content:flex-end}.group-footer button.add{margin-bottom:16px}\n"], components: [{ type: FieldContainerComponent, selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }, { type: i1.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i4$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i4$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5.ControlErrorContainerDirective, selector: "[controlErrorContainer], [formGroup]" }, { type: i4$1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: CrisprFieldDirective, selector: "[crisprField]", inputs: ["config", "group", "value"] }], pipes: { "initialControlValue": InitialControlValuePipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true });
1795
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: FormGroupListComponent, decorators: [{
255
+ FormGroupListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: FormGroupListComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
256
+ FormGroupListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.1", type: FormGroupListComponent, isStandalone: true, selector: "crispr-form-group-list", usesInheritance: true, ngImport: i0, template: "\n<crispr-field-container\n [config]=\"config\"\n [group]=\"group\"\n [formGroup]=\"group\">\n\n <div [formArrayName]=\"config.controlName\">\n <!-- Don't add trackBy function, it confuses the state of the array -->\n <div *ngFor=\"let con of control?.controls; let i = index;\">\n <!-- TODO: use content projection to allow custom item label component -->\n <div class=\"item-header\">\n <span class=\"mat-h2\"> {{ config.itemLabelBuilder ? config.itemLabelBuilder(i) : 'Item ' + (i + 1) }} </span>\n <button\n mat-icon-button\n type=\"button\"\n *ngIf=\"i + 1 > config.minListLength\">\n <mat-icon (click)=\"clickDelete(i)\">delete</mat-icon>\n </button>\n </div>\n <div\n [formGroup]=\"con\">\n <!-- TODO: if chiplists didn't need to have labels mixed in with their values we could use [value]=\"control.value\" below -->\n <ng-container\n *ngFor=\"let field of config.itemConfig.fields;\"\n crisprField\n [value]=\"blockValue ? null : value && value[i] | initialControlValue : field\"\n [config]=\"field\"\n [group]=\"con\">\n </ng-container>\n </div>\n </div>\n </div>\n <div class=\"group-footer\">\n <button\n type=\"button\"\n class=\"add\"\n mat-raised-button\n [color]=\"config.addButtonColor\"\n (click)=\"clickAdd()\">\n {{config.addItemLabel || config.addButtonLabel}}\n </button>\n </div>\n\n</crispr-field-container>\n", styles: [".item-header{display:flex;justify-content:space-between}.group-footer{display:flex;justify-content:flex-end}.group-footer button.add{margin-bottom:16px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i3$2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: FieldContainerComponent, selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "directive", type: CrisprFieldDirective, selector: "[crisprField]", inputs: ["config", "group", "value"] }, { kind: "ngmodule", type: CrisprPipesModule }, { kind: "pipe", type: InitialControlValuePipe, name: "initialControlValue" }, { kind: "ngmodule", type: FormValidationHandlerModule }, { kind: "directive", type: i3$1.ControlErrorContainerDirective, selector: "[controlErrorContainer], [formGroup]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, preserveWhitespaces: true });
257
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: FormGroupListComponent, decorators: [{
1796
258
  type: Component,
1797
- args: [{ selector: 'crispr-form-group-list', changeDetection: ChangeDetectionStrategy.OnPush, template: "\n<crispr-field-container\n [config]=\"config\"\n [group]=\"group\"\n [formGroup]=\"group\">\n\n <div [formArrayName]=\"config.controlName\">\n <!-- Don't add trackBy function, it confuses the state of the array -->\n <div *ngFor=\"let con of control?.controls; let i = index;\">\n <!-- TODO: use content projection to allow custom item label component -->\n <div class=\"item-header\">\n <span class=\"mat-h2\"> {{ config.itemLabelBuilder ? config.itemLabelBuilder(i) : 'Item ' + (i + 1) }} </span>\n <button\n mat-icon-button\n type=\"button\"\n *ngIf=\"i + 1 > config.minListLength\">\n <mat-icon (click)=\"clickDelete(i)\">delete</mat-icon>\n </button>\n </div>\n <div\n [formGroup]=\"con\">\n <!-- TODO: if chiplists didn't need to have labels mixed in with their values we could use [value]=\"control.value\" below -->\n <ng-container\n *ngFor=\"let field of config.itemConfig.fields;\"\n crisprField\n [value]=\"blockValue ? null : value && value[i] | initialControlValue : field\"\n [config]=\"field\"\n [group]=\"con\">\n </ng-container>\n </div>\n </div>\n </div>\n <div class=\"group-footer\">\n <button\n type=\"button\"\n class=\"add\"\n mat-raised-button\n [color]=\"config.addButtonColor\"\n (click)=\"clickAdd()\">\n {{config.addItemLabel || config.addButtonLabel}}\n </button>\n </div>\n\n</crispr-field-container>\n", styles: [".item-header{display:flex;justify-content:space-between}.group-footer{display:flex;justify-content:flex-end}.group-footer button.add{margin-bottom:16px}\n"] }]
1798
- }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; } });
1799
-
1800
- class CrisprPipesModule {
1801
- }
1802
- CrisprPipesModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CrisprPipesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1803
- CrisprPipesModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CrisprPipesModule, declarations: [InitialControlValuePipe], imports: [CommonModule], exports: [InitialControlValuePipe] });
1804
- CrisprPipesModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CrisprPipesModule, imports: [[
1805
- CommonModule
1806
- ]] });
1807
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CrisprPipesModule, decorators: [{
1808
- type: NgModule,
1809
- args: [{
1810
- imports: [
1811
- CommonModule
1812
- ],
1813
- exports: [
1814
- InitialControlValuePipe
1815
- ],
1816
- declarations: [
1817
- InitialControlValuePipe
1818
- ]
1819
- }]
1820
- }] });
1821
-
1822
- class FormGroupListModule {
1823
- }
1824
- FormGroupListModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: FormGroupListModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1825
- FormGroupListModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: FormGroupListModule, declarations: [FormGroupListComponent], imports: [CommonModule,
1826
- MatButtonModule,
1827
- MatIconModule,
1828
- FieldContainerModule,
1829
- ReactiveFormsModule,
1830
- CrisprFieldModule,
1831
- CrisprPipesModule,
1832
- FormValidationHandlerModule], exports: [FormGroupListComponent] });
1833
- FormGroupListModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: FormGroupListModule, imports: [[
1834
- CommonModule,
1835
- MatButtonModule,
1836
- MatIconModule,
1837
- FieldContainerModule,
1838
- ReactiveFormsModule,
1839
- CrisprFieldModule,
1840
- CrisprPipesModule,
1841
- FormValidationHandlerModule
1842
- ]] });
1843
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: FormGroupListModule, decorators: [{
1844
- type: NgModule,
1845
- args: [{
1846
- imports: [
259
+ args: [{ selector: 'crispr-form-group-list', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
1847
260
  CommonModule,
1848
261
  MatButtonModule,
1849
262
  MatIconModule,
1850
- FieldContainerModule,
263
+ FieldContainerComponent,
1851
264
  ReactiveFormsModule,
1852
- CrisprFieldModule,
265
+ CrisprFieldDirective,
1853
266
  CrisprPipesModule,
1854
267
  FormValidationHandlerModule
1855
- ],
1856
- exports: [
1857
- FormGroupListComponent
1858
- ],
1859
- declarations: [
1860
- FormGroupListComponent
1861
- ]
1862
- }]
1863
- }] });
268
+ ], template: "\n<crispr-field-container\n [config]=\"config\"\n [group]=\"group\"\n [formGroup]=\"group\">\n\n <div [formArrayName]=\"config.controlName\">\n <!-- Don't add trackBy function, it confuses the state of the array -->\n <div *ngFor=\"let con of control?.controls; let i = index;\">\n <!-- TODO: use content projection to allow custom item label component -->\n <div class=\"item-header\">\n <span class=\"mat-h2\"> {{ config.itemLabelBuilder ? config.itemLabelBuilder(i) : 'Item ' + (i + 1) }} </span>\n <button\n mat-icon-button\n type=\"button\"\n *ngIf=\"i + 1 > config.minListLength\">\n <mat-icon (click)=\"clickDelete(i)\">delete</mat-icon>\n </button>\n </div>\n <div\n [formGroup]=\"con\">\n <!-- TODO: if chiplists didn't need to have labels mixed in with their values we could use [value]=\"control.value\" below -->\n <ng-container\n *ngFor=\"let field of config.itemConfig.fields;\"\n crisprField\n [value]=\"blockValue ? null : value && value[i] | initialControlValue : field\"\n [config]=\"field\"\n [group]=\"con\">\n </ng-container>\n </div>\n </div>\n </div>\n <div class=\"group-footer\">\n <button\n type=\"button\"\n class=\"add\"\n mat-raised-button\n [color]=\"config.addButtonColor\"\n (click)=\"clickAdd()\">\n {{config.addItemLabel || config.addButtonLabel}}\n </button>\n </div>\n\n</crispr-field-container>\n", styles: [".item-header{display:flex;justify-content:space-between}.group-footer{display:flex;justify-content:flex-end}.group-footer button.add{margin-bottom:16px}\n"] }]
269
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; } });
1864
270
 
1865
271
  var index$1 = /*#__PURE__*/Object.freeze({
1866
272
  __proto__: null,
1867
- FormGroupListComponent: FormGroupListComponent,
1868
- FormGroupListModule: FormGroupListModule
273
+ FormGroupListComponent: FormGroupListComponent
1869
274
  });
1870
275
 
1871
276
  const FormGroupMixin = crisprControlMixin(CrisprFieldComponent);
@@ -1874,37 +279,34 @@ class SubGroupComponent extends FormGroupMixin {
1874
279
  super.ngOnInit();
1875
280
  }
1876
281
  }
1877
- SubGroupComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: SubGroupComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1878
- SubGroupComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: SubGroupComponent, selector: "crispr-sub-group", usesInheritance: true, ngImport: i0, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n <ng-container\n *ngFor=\"let fieldConfig of config.fields;\"\n crisprField\n [value]=\"value | initialControlValue : fieldConfig\"\n [config]=\"fieldConfig\"\n [group]=\"control\">\n </ng-container>\n</crispr-field-container>\n\n", styles: [""], components: [{ type: FieldContainerComponent, selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }], directives: [{ type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: CrisprFieldDirective, selector: "[crisprField]", inputs: ["config", "group", "value"] }], pipes: { "initialControlValue": InitialControlValuePipe }, preserveWhitespaces: true });
1879
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: SubGroupComponent, decorators: [{
282
+ SubGroupComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: SubGroupComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
283
+ SubGroupComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.1", type: SubGroupComponent, selector: "crispr-sub-group", usesInheritance: true, ngImport: i0, template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n <ng-container\n *ngFor=\"let fieldConfig of config.fields;\"\n crisprField\n [value]=\"value | initialControlValue : fieldConfig\"\n [config]=\"fieldConfig\"\n [group]=\"control\">\n </ng-container>\n</crispr-field-container>\n\n", styles: [""], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: CrisprFieldDirective, selector: "[crisprField]", inputs: ["config", "group", "value"] }, { kind: "component", type: i3.FieldContainerComponent, selector: "crispr-field-container", inputs: ["config", "group", "inlineField"] }, { kind: "pipe", type: InitialControlValuePipe, name: "initialControlValue" }], preserveWhitespaces: true });
284
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: SubGroupComponent, decorators: [{
1880
285
  type: Component,
1881
- args: [{ selector: 'crispr-sub-group', template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n <ng-container\n *ngFor=\"let fieldConfig of config.fields;\"\n crisprField\n [value]=\"value | initialControlValue : fieldConfig\"\n [config]=\"fieldConfig\"\n [group]=\"control\">\n </ng-container>\n</crispr-field-container>\n\n", styles: [""] }]
286
+ args: [{ selector: 'crispr-sub-group', template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n <ng-container\n *ngFor=\"let fieldConfig of config.fields;\"\n crisprField\n [value]=\"value | initialControlValue : fieldConfig\"\n [config]=\"fieldConfig\"\n [group]=\"control\">\n </ng-container>\n</crispr-field-container>\n\n" }]
1882
287
  }] });
1883
288
 
1884
289
  class SubGroupModule {
1885
290
  }
1886
- SubGroupModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: SubGroupModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1887
- SubGroupModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: SubGroupModule, declarations: [SubGroupComponent], imports: [CommonModule,
1888
- CrisprFieldModule,
1889
- FieldContainerModule,
291
+ SubGroupModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: SubGroupModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
292
+ SubGroupModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.0.1", ngImport: i0, type: SubGroupModule, declarations: [SubGroupComponent], imports: [CommonModule,
293
+ CrisprFieldDirective,
294
+ FieldContainerComponent,
1890
295
  CrisprPipesModule,
1891
296
  // TODO: Does this need to be here?
1892
297
  FormValidationHandlerModule], exports: [SubGroupComponent] });
1893
- SubGroupModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: SubGroupModule, imports: [[
1894
- CommonModule,
1895
- CrisprFieldModule,
1896
- FieldContainerModule,
1897
- CrisprPipesModule,
1898
- // TODO: Does this need to be here?
1899
- FormValidationHandlerModule
1900
- ]] });
1901
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: SubGroupModule, decorators: [{
298
+ SubGroupModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: SubGroupModule, imports: [CommonModule,
299
+ FieldContainerComponent,
300
+ CrisprPipesModule,
301
+ // TODO: Does this need to be here?
302
+ FormValidationHandlerModule] });
303
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: SubGroupModule, decorators: [{
1902
304
  type: NgModule,
1903
305
  args: [{
1904
306
  imports: [
1905
307
  CommonModule,
1906
- CrisprFieldModule,
1907
- FieldContainerModule,
308
+ CrisprFieldDirective,
309
+ FieldContainerComponent,
1908
310
  CrisprPipesModule,
1909
311
  // TODO: Does this need to be here?
1910
312
  FormValidationHandlerModule
@@ -1926,51 +328,43 @@ var index = /*#__PURE__*/Object.freeze({
1926
328
 
1927
329
  class CrisprFormsModule {
1928
330
  }
1929
- CrisprFormsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CrisprFormsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1930
- CrisprFormsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CrisprFormsModule, declarations: [CrisprFormComponent], imports: [CommonModule,
331
+ CrisprFormsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: CrisprFormsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
332
+ CrisprFormsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.0.1", ngImport: i0, type: CrisprFormsModule, imports: [CommonModule,
1931
333
  ReactiveFormsModule,
1932
334
  FormValidationHandlerModule,
1933
- FormGroupListModule,
1934
- FieldContainerModule,
1935
- CrisprFieldModule,
335
+ FormGroupListComponent,
336
+ FieldContainerComponent,
337
+ CrisprFieldDirective,
1936
338
  SubGroupModule,
1937
- MaterialModule,
1938
- CrisprPipesModule], exports: [CrisprFormComponent,
1939
- FieldContainerModule,
1940
- MaterialModule] });
1941
- CrisprFormsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CrisprFormsModule, imports: [[
1942
- CommonModule,
1943
- ReactiveFormsModule,
1944
- FormValidationHandlerModule,
1945
- FormGroupListModule,
1946
- FieldContainerModule,
1947
- CrisprFieldModule,
1948
- SubGroupModule,
1949
- MaterialModule,
1950
- CrisprPipesModule,
1951
- ], FieldContainerModule,
1952
- MaterialModule] });
1953
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CrisprFormsModule, decorators: [{
339
+ CrisprPipesModule,
340
+ CrisprFormComponent], exports: [CrisprFormComponent,
341
+ FieldContainerComponent] });
342
+ CrisprFormsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: CrisprFormsModule, imports: [CommonModule,
343
+ ReactiveFormsModule,
344
+ FormValidationHandlerModule,
345
+ FormGroupListComponent,
346
+ FieldContainerComponent,
347
+ SubGroupModule,
348
+ CrisprPipesModule,
349
+ CrisprFormComponent] });
350
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: CrisprFormsModule, decorators: [{
1954
351
  type: NgModule,
1955
352
  args: [{
1956
353
  imports: [
1957
354
  CommonModule,
1958
355
  ReactiveFormsModule,
1959
356
  FormValidationHandlerModule,
1960
- FormGroupListModule,
1961
- FieldContainerModule,
1962
- CrisprFieldModule,
357
+ FormGroupListComponent,
358
+ FieldContainerComponent,
359
+ CrisprFieldDirective,
1963
360
  SubGroupModule,
1964
- MaterialModule,
1965
361
  CrisprPipesModule,
1966
- ],
1967
- declarations: [
1968
- CrisprFormComponent,
362
+ CrisprFormComponent
1969
363
  ],
1970
364
  exports: [
1971
365
  CrisprFormComponent,
1972
- FieldContainerModule,
1973
- MaterialModule
366
+ FieldContainerComponent,
367
+ // MaterialModule
1974
368
  ]
1975
369
  }]
1976
370
  }] });
@@ -1979,5 +373,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImpor
1979
373
  * Generated bundle index. Do not edit.
1980
374
  */
1981
375
 
1982
- export { AbstractAutocompleteComponent, AutocompleteChiplistFieldComponent, AutocompleteFieldComponent, ButtonComponent, CheckboxFieldComponent, ControlType, CrisprFieldComponent, CrisprFormComponent, CrisprFormsModule, DEFAULT_EMPTY_OPTIONS_MESSAGE, DatepickerFieldComponent, DividerComponent, FieldContainerComponent, FieldContainerModule, FileDropzoneDirective, FileUploadFieldComponent, FileUploadFieldModule, HeadingComponent, HeadingModule, ImageUploadFieldComponent, ImageUploadFieldModule, InputFieldComponent, MaterialModule, OptionComponent, RadioFieldComponent, SelectFieldComponent, SliderFieldComponent, TextareaFieldComponent, UnitConversionFieldComponent, allowedFileExtValidator, allowedFileType, buildFormGroupFromConfig, callOptionsIfFunction, checkControlForValues, checkControlsForValues, computeValueFromFields, createControlForType, crisprControlMixin, filterOptionsByLabel, isControlConfig, maxFileSizeValidator, observablifyOptions };
376
+ export { CrisprFormComponent, CrisprFormsModule };
1983
377
  //# sourceMappingURL=tft-crispr-forms.mjs.map