@tft/crispr-forms 14.0.1-rc.0 → 14.0.1

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