@siemens/element-ng 47.2.0 → 47.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (339) hide show
  1. package/README.md +18 -6
  2. package/autocomplete/index.d.ts +8 -0
  3. package/autocomplete/package.json +3 -0
  4. package/autocomplete/si-autocomplete-listbox.directive.d.ts +31 -0
  5. package/autocomplete/si-autocomplete-option.directive.d.ts +31 -0
  6. package/autocomplete/si-autocomplete.directive.d.ts +14 -0
  7. package/autocomplete/si-autocomplete.model.d.ts +7 -0
  8. package/autocomplete/si-autocomplete.module.d.ts +9 -0
  9. package/badge/index.d.ts +5 -0
  10. package/badge/package.json +3 -0
  11. package/badge/si-badge.component.d.ts +17 -0
  12. package/breadcrumb/breadcrumb-item.model.d.ts +36 -0
  13. package/breadcrumb/index.d.ts +7 -0
  14. package/breadcrumb/package.json +3 -0
  15. package/breadcrumb/si-breadcrumb-item-template.directive.d.ts +10 -0
  16. package/breadcrumb/si-breadcrumb.component.d.ts +46 -0
  17. package/breadcrumb/si-breadcrumb.module.d.ts +7 -0
  18. package/card/index.d.ts +6 -0
  19. package/card/package.json +3 -0
  20. package/card/si-card.component.d.ts +79 -0
  21. package/card/si-card.module.d.ts +7 -0
  22. package/circle-status/index.d.ts +6 -0
  23. package/circle-status/package.json +3 -0
  24. package/circle-status/si-circle-status.component.d.ts +66 -0
  25. package/circle-status/si-circle-status.module.d.ts +7 -0
  26. package/column-selection-dialog/column-selection-editor/si-column-selection-editor.component.d.ts +23 -0
  27. package/column-selection-dialog/index.d.ts +6 -0
  28. package/column-selection-dialog/package.json +3 -0
  29. package/column-selection-dialog/si-column-selection-dialog.component.d.ts +114 -0
  30. package/column-selection-dialog/si-column-selection-dialog.service.d.ts +20 -0
  31. package/column-selection-dialog/si-column-selection-dialog.types.d.ts +68 -0
  32. package/common/models/status-type.model.d.ts +2 -2
  33. package/content-action-bar/index.d.ts +7 -0
  34. package/content-action-bar/package.json +3 -0
  35. package/content-action-bar/si-content-action-bar-toggle.component.d.ts +6 -0
  36. package/content-action-bar/si-content-action-bar.component.d.ts +72 -0
  37. package/content-action-bar/si-content-action-bar.model.d.ts +9 -0
  38. package/content-action-bar/si-content-action-bar.module.d.ts +7 -0
  39. package/date-range-filter/index.d.ts +8 -0
  40. package/date-range-filter/package.json +3 -0
  41. package/date-range-filter/si-date-range-calculation.service.d.ts +33 -0
  42. package/date-range-filter/si-date-range-filter.component.d.ts +248 -0
  43. package/date-range-filter/si-date-range-filter.module.d.ts +7 -0
  44. package/date-range-filter/si-date-range-filter.types.d.ts +40 -0
  45. package/date-range-filter/si-relative-date.component.d.ts +31 -0
  46. package/datepicker/components/si-calendar-body.component.d.ts +137 -0
  47. package/datepicker/components/si-calendar-date-cell.directive.d.ts +16 -0
  48. package/datepicker/components/si-calendar-direction-button.component.d.ts +18 -0
  49. package/datepicker/components/si-compare-adapter.d.ts +37 -0
  50. package/datepicker/components/si-day-selection.component.d.ts +76 -0
  51. package/datepicker/components/si-initial-focus.component.d.ts +74 -0
  52. package/datepicker/components/si-month-selection.component.d.ts +62 -0
  53. package/datepicker/components/si-year-selection.component.d.ts +65 -0
  54. package/datepicker/date-time-helper.d.ts +302 -0
  55. package/datepicker/index.d.ts +15 -0
  56. package/datepicker/package.json +3 -0
  57. package/datepicker/si-calendar-button.component.d.ts +49 -0
  58. package/datepicker/si-date-input.directive.d.ts +114 -0
  59. package/datepicker/si-date-range.component.d.ts +150 -0
  60. package/datepicker/si-datepicker-overlay.component.d.ts +82 -0
  61. package/datepicker/si-datepicker-overlay.directive.d.ts +104 -0
  62. package/datepicker/si-datepicker.component.d.ts +228 -0
  63. package/datepicker/si-datepicker.directive.d.ts +62 -0
  64. package/datepicker/si-datepicker.model.d.ts +129 -0
  65. package/datepicker/si-datepicker.module.d.ts +12 -0
  66. package/datepicker/si-timepicker.component.d.ts +214 -0
  67. package/electron-titlebar/electron.helpers.d.ts +5 -0
  68. package/electron-titlebar/index.d.ts +7 -0
  69. package/electron-titlebar/package.json +3 -0
  70. package/electron-titlebar/si-electron-titlebar.component.d.ts +72 -0
  71. package/electron-titlebar/si-electron-titlebar.module.d.ts +7 -0
  72. package/fesm2022/siemens-element-ng-application-header.mjs +2 -2
  73. package/fesm2022/siemens-element-ng-application-header.mjs.map +1 -1
  74. package/fesm2022/siemens-element-ng-autocomplete.mjs +235 -0
  75. package/fesm2022/siemens-element-ng-autocomplete.mjs.map +1 -0
  76. package/fesm2022/siemens-element-ng-badge.mjs +59 -0
  77. package/fesm2022/siemens-element-ng-badge.mjs.map +1 -0
  78. package/fesm2022/siemens-element-ng-breadcrumb.mjs +302 -0
  79. package/fesm2022/siemens-element-ng-breadcrumb.mjs.map +1 -0
  80. package/fesm2022/siemens-element-ng-card.mjs +122 -0
  81. package/fesm2022/siemens-element-ng-card.mjs.map +1 -0
  82. package/fesm2022/siemens-element-ng-circle-status.mjs +146 -0
  83. package/fesm2022/siemens-element-ng-circle-status.mjs.map +1 -0
  84. package/fesm2022/siemens-element-ng-column-selection-dialog.mjs +369 -0
  85. package/fesm2022/siemens-element-ng-column-selection-dialog.mjs.map +1 -0
  86. package/fesm2022/siemens-element-ng-common.mjs +1 -1
  87. package/fesm2022/siemens-element-ng-common.mjs.map +1 -1
  88. package/fesm2022/siemens-element-ng-content-action-bar.mjs +200 -0
  89. package/fesm2022/siemens-element-ng-content-action-bar.mjs.map +1 -0
  90. package/fesm2022/siemens-element-ng-date-range-filter.mjs +649 -0
  91. package/fesm2022/siemens-element-ng-date-range-filter.mjs.map +1 -0
  92. package/fesm2022/siemens-element-ng-datepicker.mjs +4231 -0
  93. package/fesm2022/siemens-element-ng-datepicker.mjs.map +1 -0
  94. package/fesm2022/siemens-element-ng-electron-titlebar.mjs +142 -0
  95. package/fesm2022/siemens-element-ng-electron-titlebar.mjs.map +1 -0
  96. package/fesm2022/siemens-element-ng-file-uploader.mjs +751 -0
  97. package/fesm2022/siemens-element-ng-file-uploader.mjs.map +1 -0
  98. package/fesm2022/siemens-element-ng-filter-bar.mjs +153 -0
  99. package/fesm2022/siemens-element-ng-filter-bar.mjs.map +1 -0
  100. package/fesm2022/siemens-element-ng-form.mjs +827 -0
  101. package/fesm2022/siemens-element-ng-form.mjs.map +1 -0
  102. package/fesm2022/siemens-element-ng-icon-status.mjs +65 -0
  103. package/fesm2022/siemens-element-ng-icon-status.mjs.map +1 -0
  104. package/fesm2022/siemens-element-ng-icon.mjs +22 -2
  105. package/fesm2022/siemens-element-ng-icon.mjs.map +1 -1
  106. package/fesm2022/siemens-element-ng-info-page.mjs +63 -0
  107. package/fesm2022/siemens-element-ng-info-page.mjs.map +1 -0
  108. package/fesm2022/siemens-element-ng-inline-notification.mjs +4 -6
  109. package/fesm2022/siemens-element-ng-inline-notification.mjs.map +1 -1
  110. package/fesm2022/siemens-element-ng-ip-input.mjs +451 -0
  111. package/fesm2022/siemens-element-ng-ip-input.mjs.map +1 -0
  112. package/fesm2022/siemens-element-ng-language-switcher.mjs +90 -0
  113. package/fesm2022/siemens-element-ng-language-switcher.mjs.map +1 -0
  114. package/fesm2022/siemens-element-ng-localization.mjs +306 -0
  115. package/fesm2022/siemens-element-ng-localization.mjs.map +1 -0
  116. package/fesm2022/siemens-element-ng-number-input.mjs +267 -0
  117. package/fesm2022/siemens-element-ng-number-input.mjs.map +1 -0
  118. package/fesm2022/siemens-element-ng-password-strength.mjs +177 -0
  119. package/fesm2022/siemens-element-ng-password-strength.mjs.map +1 -0
  120. package/fesm2022/siemens-element-ng-photo-upload.mjs +480 -0
  121. package/fesm2022/siemens-element-ng-photo-upload.mjs.map +1 -0
  122. package/fesm2022/siemens-element-ng-pills-input.mjs +397 -0
  123. package/fesm2022/siemens-element-ng-pills-input.mjs.map +1 -0
  124. package/fesm2022/siemens-element-ng-popover-next.mjs +259 -0
  125. package/fesm2022/siemens-element-ng-popover-next.mjs.map +1 -0
  126. package/fesm2022/siemens-element-ng-popover.mjs +256 -0
  127. package/fesm2022/siemens-element-ng-popover.mjs.map +1 -0
  128. package/fesm2022/siemens-element-ng-progressbar.mjs +83 -0
  129. package/fesm2022/siemens-element-ng-progressbar.mjs.map +1 -0
  130. package/fesm2022/siemens-element-ng-search-bar.mjs +193 -0
  131. package/fesm2022/siemens-element-ng-search-bar.mjs.map +1 -0
  132. package/fesm2022/siemens-element-ng-select.mjs +1166 -0
  133. package/fesm2022/siemens-element-ng-select.mjs.map +1 -0
  134. package/fesm2022/siemens-element-ng-skip-links.mjs +117 -0
  135. package/fesm2022/siemens-element-ng-skip-links.mjs.map +1 -0
  136. package/fesm2022/siemens-element-ng-slider.mjs +313 -0
  137. package/fesm2022/siemens-element-ng-slider.mjs.map +1 -0
  138. package/fesm2022/siemens-element-ng-sort-bar.mjs +89 -0
  139. package/fesm2022/siemens-element-ng-sort-bar.mjs.map +1 -0
  140. package/fesm2022/siemens-element-ng-split.mjs +575 -0
  141. package/fesm2022/siemens-element-ng-split.mjs.map +1 -0
  142. package/fesm2022/siemens-element-ng-status-toggle.mjs +196 -0
  143. package/fesm2022/siemens-element-ng-status-toggle.mjs.map +1 -0
  144. package/fesm2022/siemens-element-ng-summary-widget.mjs +77 -0
  145. package/fesm2022/siemens-element-ng-summary-widget.mjs.map +1 -0
  146. package/fesm2022/siemens-element-ng-system-banner.mjs +47 -0
  147. package/fesm2022/siemens-element-ng-system-banner.mjs.map +1 -0
  148. package/fesm2022/siemens-element-ng-tabs.mjs +395 -0
  149. package/fesm2022/siemens-element-ng-tabs.mjs.map +1 -0
  150. package/fesm2022/siemens-element-ng-toast-notification.mjs +227 -0
  151. package/fesm2022/siemens-element-ng-toast-notification.mjs.map +1 -0
  152. package/fesm2022/siemens-element-ng-translate.mjs.map +1 -1
  153. package/fesm2022/siemens-element-ng-typeahead.mjs +746 -0
  154. package/fesm2022/siemens-element-ng-typeahead.mjs.map +1 -0
  155. package/fesm2022/siemens-element-ng-unauthorized-page.mjs +76 -0
  156. package/fesm2022/siemens-element-ng-unauthorized-page.mjs.map +1 -0
  157. package/fesm2022/siemens-element-ng-wizard.mjs +465 -0
  158. package/fesm2022/siemens-element-ng-wizard.mjs.map +1 -0
  159. package/file-uploader/index.d.ts +8 -0
  160. package/file-uploader/package.json +3 -0
  161. package/file-uploader/si-file-dropzone.component.d.ts +106 -0
  162. package/file-uploader/si-file-uploader.component.d.ts +296 -0
  163. package/file-uploader/si-file-uploader.model.d.ts +12 -0
  164. package/file-uploader/si-file-uploader.module.d.ts +8 -0
  165. package/filter-bar/filter.d.ts +26 -0
  166. package/filter-bar/index.d.ts +8 -0
  167. package/filter-bar/package.json +3 -0
  168. package/filter-bar/si-filter-bar.component.d.ts +65 -0
  169. package/filter-bar/si-filter-bar.module.d.ts +7 -0
  170. package/filter-bar/si-filter-pill.component.d.ts +20 -0
  171. package/form/form-fieldset/si-form-fieldset.component.d.ts +40 -0
  172. package/form/index.d.ts +14 -0
  173. package/form/package.json +3 -0
  174. package/form/si-form-container/si-form-container.component.d.ts +155 -0
  175. package/form/si-form-item/si-form-field-native.control.d.ts +22 -0
  176. package/form/si-form-item/si-form-item.component.d.ts +90 -0
  177. package/form/si-form-item-control-input.directive.d.ts +18 -0
  178. package/form/si-form-item.control.d.ts +35 -0
  179. package/form/si-form-validation-error.model.d.ts +55 -0
  180. package/form/si-form-validation-error.provider.d.ts +11 -0
  181. package/form/si-form-validation-error.service.d.ts +42 -0
  182. package/form/si-form-validation-tooltip/si-form-validation-tooltip.component.d.ts +13 -0
  183. package/form/si-form-validation-tooltip/si-form-validation-tooltip.directive.d.ts +42 -0
  184. package/form/si-form.module.d.ts +25 -0
  185. package/icon/element-icons.d.ts +20 -0
  186. package/icon-status/index.d.ts +6 -0
  187. package/icon-status/package.json +3 -0
  188. package/icon-status/si-icon-status.component.d.ts +24 -0
  189. package/icon-status/si-icon-status.module.d.ts +7 -0
  190. package/info-page/index.d.ts +5 -0
  191. package/info-page/package.json +3 -0
  192. package/info-page/si-info-page.component.d.ts +38 -0
  193. package/inline-notification/si-inline-notification.component.d.ts +0 -2
  194. package/ip-input/address-utils.d.ts +28 -0
  195. package/ip-input/address-validators.d.ts +21 -0
  196. package/ip-input/index.d.ts +7 -0
  197. package/ip-input/package.json +3 -0
  198. package/ip-input/si-ip-input.directive.d.ts +53 -0
  199. package/ip-input/si-ip4-input.directive.d.ts +9 -0
  200. package/ip-input/si-ip6-input.directive.d.ts +10 -0
  201. package/language-switcher/index.d.ts +7 -0
  202. package/language-switcher/iso-language-value.d.ts +14 -0
  203. package/language-switcher/package.json +3 -0
  204. package/language-switcher/si-language-switcher.component.d.ts +32 -0
  205. package/language-switcher/si-language-switcher.module.d.ts +7 -0
  206. package/localization/index.d.ts +8 -0
  207. package/localization/package.json +3 -0
  208. package/localization/si-directionality.d.ts +41 -0
  209. package/localization/si-locale-id.d.ts +22 -0
  210. package/localization/si-locale-store.d.ts +16 -0
  211. package/localization/si-locale.service.d.ts +73 -0
  212. package/number-input/index.d.ts +6 -0
  213. package/number-input/package.json +3 -0
  214. package/number-input/si-number-input.component.d.ts +106 -0
  215. package/number-input/si-number-input.module.d.ts +7 -0
  216. package/package.json +163 -3
  217. package/password-strength/index.d.ts +7 -0
  218. package/password-strength/package.json +3 -0
  219. package/password-strength/si-password-strength.component.d.ts +25 -0
  220. package/password-strength/si-password-strength.directive.d.ts +54 -0
  221. package/password-strength/si-password-strength.module.d.ts +8 -0
  222. package/photo-upload/index.d.ts +6 -0
  223. package/photo-upload/package.json +3 -0
  224. package/photo-upload/si-image-cropper-style.component.d.ts +5 -0
  225. package/photo-upload/si-photo-upload.component.d.ts +298 -0
  226. package/pills-input/index.d.ts +9 -0
  227. package/pills-input/package.json +3 -0
  228. package/pills-input/si-input-pill.component.d.ts +9 -0
  229. package/pills-input/si-pills-input-csv.directive.d.ts +8 -0
  230. package/pills-input/si-pills-input-email.directive.d.ts +10 -0
  231. package/pills-input/si-pills-input-pattern-base.d.ts +19 -0
  232. package/pills-input/si-pills-input-value-handler.d.ts +12 -0
  233. package/pills-input/si-pills-input.component.d.ts +87 -0
  234. package/pills-input/si-pills-input.module.d.ts +9 -0
  235. package/popover/index.d.ts +6 -0
  236. package/popover/package.json +3 -0
  237. package/popover/si-popover.component.d.ts +26 -0
  238. package/popover/si-popover.directive.d.ts +89 -0
  239. package/popover/si-popover.module.d.ts +7 -0
  240. package/popover-next/index.d.ts +7 -0
  241. package/popover-next/package.json +3 -0
  242. package/popover-next/si-popover-description.directive.d.ts +7 -0
  243. package/popover-next/si-popover-next.directive.d.ts +61 -0
  244. package/popover-next/si-popover-title.directive.d.ts +7 -0
  245. package/popover-next/si-popover.component.d.ts +27 -0
  246. package/progressbar/index.d.ts +6 -0
  247. package/progressbar/package.json +3 -0
  248. package/progressbar/si-progressbar.component.d.ts +43 -0
  249. package/progressbar/si-progressbar.module.d.ts +7 -0
  250. package/search-bar/index.d.ts +6 -0
  251. package/search-bar/package.json +3 -0
  252. package/search-bar/si-search-bar.component.d.ts +87 -0
  253. package/search-bar/si-search-bar.module.d.ts +7 -0
  254. package/select/index.d.ts +18 -0
  255. package/select/options/si-select-complex-options.directive.d.ts +69 -0
  256. package/select/options/si-select-lazy-options.directive.d.ts +38 -0
  257. package/select/options/si-select-option.source.d.ts +49 -0
  258. package/select/options/si-select-options-strategy.base.d.ts +35 -0
  259. package/select/options/si-select-options-strategy.d.ts +37 -0
  260. package/select/options/si-select-simple-options.directive.d.ts +34 -0
  261. package/select/package.json +3 -0
  262. package/select/select-input/si-select-input.component.d.ts +43 -0
  263. package/select/select-list/si-select-list-has-filter.component.d.ts +20 -0
  264. package/select/select-list/si-select-list.base.d.ts +37 -0
  265. package/select/select-list/si-select-list.component.d.ts +15 -0
  266. package/select/select-option/si-select-option-row.component.d.ts +16 -0
  267. package/select/select-option/si-select-option.component.d.ts +9 -0
  268. package/select/selection/si-select-multi-value.directive.d.ts +26 -0
  269. package/select/selection/si-select-selection-strategy.d.ts +58 -0
  270. package/select/selection/si-select-single-value.directive.d.ts +26 -0
  271. package/select/si-select-action.directive.d.ts +12 -0
  272. package/select/si-select-actions.directive.d.ts +5 -0
  273. package/select/si-select-group-template.directive.d.ts +20 -0
  274. package/select/si-select-option-row-template.directive.d.ts +9 -0
  275. package/select/si-select-option-template.directive.d.ts +21 -0
  276. package/select/si-select.component.d.ts +96 -0
  277. package/select/si-select.module.d.ts +15 -0
  278. package/select/si-select.types.d.ts +65 -0
  279. package/skip-links/index.d.ts +5 -0
  280. package/skip-links/package.json +3 -0
  281. package/skip-links/si-skip-link-target.directive.d.ts +27 -0
  282. package/skip-links/si-skip-links.component.d.ts +9 -0
  283. package/skip-links/skip-link.service.d.ts +14 -0
  284. package/slider/index.d.ts +6 -0
  285. package/slider/package.json +3 -0
  286. package/slider/si-slider.component.d.ts +129 -0
  287. package/slider/si-slider.module.d.ts +7 -0
  288. package/sort-bar/index.d.ts +6 -0
  289. package/sort-bar/package.json +3 -0
  290. package/sort-bar/si-sort-bar.component.d.ts +42 -0
  291. package/sort-bar/si-sort-bar.module.d.ts +7 -0
  292. package/split/index.d.ts +8 -0
  293. package/split/package.json +3 -0
  294. package/split/si-split-part.component.d.ts +154 -0
  295. package/split/si-split.component.d.ts +48 -0
  296. package/split/si-split.interfaces.d.ts +17 -0
  297. package/split/si-split.module.d.ts +8 -0
  298. package/status-toggle/index.d.ts +6 -0
  299. package/status-toggle/package.json +3 -0
  300. package/status-toggle/si-status-toggle.component.d.ts +54 -0
  301. package/status-toggle/status-toggle.model.d.ts +26 -0
  302. package/summary-widget/index.d.ts +5 -0
  303. package/summary-widget/package.json +3 -0
  304. package/summary-widget/si-summary-widget.component.d.ts +44 -0
  305. package/system-banner/index.d.ts +5 -0
  306. package/system-banner/package.json +3 -0
  307. package/system-banner/system-banner.component.d.ts +23 -0
  308. package/tabs/index.d.ts +7 -0
  309. package/tabs/package.json +3 -0
  310. package/tabs/si-tab/index.d.ts +5 -0
  311. package/tabs/si-tab/si-tab.component.d.ts +58 -0
  312. package/tabs/si-tabs.module.d.ts +8 -0
  313. package/tabs/si-tabset/index.d.ts +5 -0
  314. package/tabs/si-tabset/si-tabset.component.d.ts +100 -0
  315. package/template-i18n.json +111 -1
  316. package/toast-notification/index.d.ts +6 -0
  317. package/toast-notification/package.json +3 -0
  318. package/toast-notification/si-toast-notification/si-toast-notification.component.d.ts +17 -0
  319. package/toast-notification/si-toast-notification-drawer/si-toast-notification-drawer.component.d.ts +9 -0
  320. package/toast-notification/si-toast-notification.service.d.ts +41 -0
  321. package/toast-notification/si-toast.model.d.ts +25 -0
  322. package/translate/si-translatable-keys.interface.d.ts +110 -0
  323. package/typeahead/index.d.ts +8 -0
  324. package/typeahead/package.json +3 -0
  325. package/typeahead/si-typeahead-item-template.directive.d.ts +7 -0
  326. package/typeahead/si-typeahead.component.d.ts +22 -0
  327. package/typeahead/si-typeahead.directive.d.ts +196 -0
  328. package/typeahead/si-typeahead.model.d.ts +60 -0
  329. package/typeahead/si-typeahead.module.d.ts +8 -0
  330. package/typeahead/si-typeahead.sorting.d.ts +10 -0
  331. package/unauthorized-page/index.d.ts +6 -0
  332. package/unauthorized-page/package.json +3 -0
  333. package/unauthorized-page/si-unauthorized-page.component.d.ts +35 -0
  334. package/unauthorized-page/si-unauthorized-page.module.d.ts +7 -0
  335. package/wizard/index.d.ts +7 -0
  336. package/wizard/package.json +3 -0
  337. package/wizard/si-wizard-step.component.d.ts +21 -0
  338. package/wizard/si-wizard.component.d.ts +196 -0
  339. package/wizard/si-wizard.module.d.ts +8 -0
@@ -0,0 +1,827 @@
1
+ import { NgTemplateOutlet } from '@angular/common';
2
+ import * as i0 from '@angular/core';
3
+ import { inject, Injectable, input, booleanAttribute, computed, Component, signal, HostBinding, ChangeDetectionStrategy, InjectionToken, contentChild, ElementRef, isSignal, Input, Injector, HostListener, Directive, NgModule } from '@angular/core';
4
+ import { FormGroup, FormControl, NgControl, RequiredValidator } from '@angular/forms';
5
+ import { SiResponsiveContainerDirective } from '@siemens/element-ng/resize-observer';
6
+ import * as i1 from '@siemens/element-translate-ng/translate';
7
+ import { SiTranslateModule } from '@siemens/element-translate-ng/translate';
8
+ import { SiTooltipService } from '@siemens/element-ng/tooltip';
9
+
10
+ /**
11
+ * Copyright Siemens 2016 - 2025.
12
+ * SPDX-License-Identifier: MIT
13
+ */
14
+ /**
15
+ * Creates the map of default error resolver.
16
+ * This is a function as $localize requires an injection context.
17
+ *
18
+ * @internal
19
+ */
20
+ const buildDefaults = () => ({
21
+ min: $localize `:@@SI_FORM_CONTAINER.ERROR.MIN:The value is too small`,
22
+ max: $localize `:@@SI_FORM_CONTAINER.ERROR.MAX:The value is too large.`,
23
+ required: $localize `:@@SI_FORM_CONTAINER.ERROR.REQUIRED:A value is required.`,
24
+ requiredTrue: $localize `:@@SI_FORM_CONTAINER.ERROR.REQUIRED_TRUE:The value should be true.`,
25
+ email: $localize `:@@SI_FORM_CONTAINER.ERROR.EMAIL:The email is not valid.`,
26
+ minlength: $localize `:@@SI_FORM_CONTAINER.ERROR.MIN_LENGTH:The minimum number of characters is not met.`,
27
+ maxlength: $localize `:@@SI_FORM_CONTAINER.ERROR.MAX_LENGTH:A maximum number of characters is exceeded.`,
28
+ ipv4Address: $localize `:@@SI_FORM_CONTAINER.ERROR.IPV4:Invalid IPv4 address.`,
29
+ ipv6Address: $localize `:@@SI_FORM_CONTAINER.ERROR.IPV6:Invalid IPv6 address.`,
30
+ pattern: $localize `:@@SI_FORM_CONTAINER.ERROR.PATTERN:The value does not match the predefined pattern.`,
31
+ numberFormat: $localize `:@@SI_FORM_CONTAINER.ERROR.NUMBER_FORMAT:The value is not a valid number.`,
32
+ dateFormat: $localize `:@@SI_FORM_CONTAINER.ERROR.DATE_FORMAT:Invalid date format.`,
33
+ maxDate: $localize `:@@SI_FORM_CONTAINER.ERROR.MAX_DATE:The date is too far in the future.`,
34
+ minDate: $localize `:@@SI_FORM_CONTAINER.ERROR.MIN_DATE:The date is too far in the past.`
35
+ });
36
+ /**
37
+ * A service to resolve the validation error of an Angular control to a message or translation key.
38
+ *
39
+ * It can be provided using {@link provideFormValidationErrorMapper}.
40
+ * If not provided, there will be a default instance in the root injector using only the default keys.
41
+ *
42
+ * There can be multiple instances to support providing in a lazy loaded module.
43
+ * If the service cannot find a message, it will try to resolve it using a parent service if available.
44
+ *
45
+ * @internal
46
+ */
47
+ class SiFormValidationErrorService {
48
+ errorMapper;
49
+ parent = inject(SiFormValidationErrorService, {
50
+ optional: true,
51
+ skipSelf: true
52
+ });
53
+ constructor(errorMapper) {
54
+ this.errorMapper = errorMapper;
55
+ }
56
+ /**
57
+ * Resolves the provided form errors to a list of {@link SiFormError}.
58
+ * To resolution order is:
59
+ * 1. componentMapper
60
+ * 2. containerMapper using the controlName
61
+ * 3. containerMapper without controlName
62
+ * 4. errorMapper of the service using the controlName
63
+ * 5. errorMapper of the service
64
+ * 6: parent service
65
+ */
66
+ resolveErrors(controlName, errors, componentMapper, containerMapper) {
67
+ if (!errors) {
68
+ return [];
69
+ }
70
+ /*
71
+ * Converts the angular error object (like: {required: true, minLength: {actualLength: 1, requiredLength: 3}})
72
+ * to SiFormError[].
73
+ * Therefore, the error key is look up in the error mappers.
74
+ * If it can be resolved, the error will be printed using the resolved text.
75
+ */
76
+ return Object.entries(errors).map(([key, params]) => this.resolveError(key, controlName, params, componentMapper, containerMapper));
77
+ }
78
+ resolveError(key, controlName, params, componentMapper, containerMapper) {
79
+ return (this.resolveMessage(key, controlName, params, componentMapper) ??
80
+ this.resolveMessage(key, controlName, params, containerMapper) ??
81
+ this.resolveMessage(key, controlName, params, this.errorMapper) ??
82
+ this.parent?.resolveError(key, controlName, params) ?? { key, params });
83
+ }
84
+ resolveMessage(key, controlName, params, mapper) {
85
+ if (!mapper) {
86
+ return undefined;
87
+ }
88
+ const resolver = mapper[`${controlName}.${key}`] ?? mapper[key];
89
+ if (resolver) {
90
+ const message = typeof resolver === 'function' ? resolver(params) : resolver;
91
+ return message ? { key, message, params } : undefined;
92
+ }
93
+ return undefined;
94
+ }
95
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiFormValidationErrorService, deps: "invalid", target: i0.ɵɵFactoryTarget.Injectable });
96
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiFormValidationErrorService, providedIn: 'root', useFactory: () => new SiFormValidationErrorService(buildDefaults()) });
97
+ }
98
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiFormValidationErrorService, decorators: [{
99
+ type: Injectable,
100
+ args: [{
101
+ providedIn: 'root',
102
+ useFactory: () => new SiFormValidationErrorService(buildDefaults())
103
+ }]
104
+ }], ctorParameters: () => [{ type: undefined }] });
105
+
106
+ /**
107
+ * Copyright Siemens 2016 - 2025.
108
+ * SPDX-License-Identifier: MIT
109
+ */
110
+ class SiFormContainerComponent {
111
+ /**
112
+ * Set the form entity to the container to enable the overall form validation on in
113
+ * the form container edit panel.
114
+ */
115
+ form = input();
116
+ /**
117
+ * A form container in readonly mode is only displaying the form content without ability
118
+ * to change it. The edit panel with typically save and cancel buttons is hidden. Set
119
+ * to true to display the edit panel.
120
+ *
121
+ * @defaultValue false
122
+ */
123
+ readonly = input(false, { transform: booleanAttribute });
124
+ /**
125
+ * The container hosts the form within a siResizeContainer to configure the breakpoint for
126
+ * different screen sizes. Optionally, change the container breakpoints with the contentContainerBreakpoints
127
+ * input.
128
+ */
129
+ contentContainerBreakpoints = input();
130
+ /**
131
+ * In some scenarios, one may not want the form container to be responsible for the layout relevant
132
+ * `si-container-[xs|...]` classes, but let this be done by a different, nested component, e.g. by a
133
+ * group box. In these cases, the property should be set to true.
134
+ *
135
+ * @defaultValue false
136
+ */
137
+ disableContainerBreakpoints = input(false, { transform: booleanAttribute });
138
+ /**
139
+ * Every validation error has an errorCode. This map holds translate keys for error codes. The keys can
140
+ * be used to display a translated message for each validation error. The defaults old english readable
141
+ * key defaults for the Angular standard validators of the `Validators` class like `min`, `max` or `required`.
142
+ *
143
+ * Use the input to set your own translate keys for the form validators you need.
144
+ */
145
+ errorCodeTranslateKeyMap = input();
146
+ /**
147
+ * A map the maps from control names of the form to their translate keys.
148
+ * The initial map is empty and the user is responsible to add the required
149
+ * translate keys.
150
+ *
151
+ * @defaultValue
152
+ * ```
153
+ * new Map<string, string>()
154
+ * ```
155
+ */
156
+ controlNameTranslateKeyMap = input(new Map());
157
+ /**
158
+ * Disables the automatic error printing in all nested {@link SiFormItemComponent}. Error printing will be enabled by default in v46.
159
+ *
160
+ * @defaultValue false
161
+ */
162
+ disableErrorPrinting = input(false, { transform: booleanAttribute });
163
+ /**
164
+ * A custom width value to be applied to all labels.
165
+ *
166
+ * @example labelWidth="100px".
167
+ */
168
+ labelWidth = input();
169
+ hasParentContainer = !!inject(SiFormContainerComponent, {
170
+ optional: true,
171
+ skipSelf: true
172
+ });
173
+ errorResolver = inject(SiFormValidationErrorService);
174
+ /** @internal */
175
+ formErrorMapper = computed(() => {
176
+ const map = this.errorCodeTranslateKeyMap();
177
+ let customMapper;
178
+ if (map instanceof Map) {
179
+ customMapper = Object.fromEntries(map.entries());
180
+ }
181
+ else if (map) {
182
+ customMapper = map;
183
+ }
184
+ return {
185
+ ...customMapper
186
+ };
187
+ });
188
+ /**
189
+ * Indicates whether the user interacted with the form.
190
+ * @returns `true`, if the user selected at least one form element and
191
+ * [blurred]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/blur_event} by losing focus again
192
+ * (e.g. by setting focus on another element), or by editing the content of a form element.
193
+ * Otherwise `false`.
194
+ */
195
+ get userInteractedWithForm() {
196
+ const form = this.form();
197
+ return !!form && (form.dirty || form.touched);
198
+ }
199
+ /**
200
+ * Indicates whether content editor message shall be styled as success.
201
+ * @returns `true`, if {@link SiFormContainerComponent.userInteractedWithForm} is true and
202
+ * the form is valid.
203
+ */
204
+ get validFormContainerMessage() {
205
+ return this.userInteractedWithForm && this.form().status === 'VALID';
206
+ }
207
+ /**
208
+ * Indicates whether the content editor message shall be styled as warning.
209
+ * @returns `true`, if {@link SiFormContainerComponent.userInteractedWithForm} is true and
210
+ * the form is invalid.
211
+ */
212
+ get invalidFormContainerMessage() {
213
+ return this.userInteractedWithForm && this.form().status === 'INVALID';
214
+ }
215
+ /**
216
+ * Returns the validation errors of the form's control when the control name is provided. Otherwise,
217
+ * returns all validation errors of the form. Returns an empty arry when no form is available or if
218
+ * the name does not match to a control.
219
+ * @param controlName - An optional name of a control that is part of the form.
220
+ *
221
+ * @deprecated The {@link SiFormItemComponent} is able to display validation errors automatically when `siFormInput` directive is used.
222
+ */
223
+ getValidationErrors(controlName) {
224
+ const form = this.form();
225
+ if (!form) {
226
+ return [];
227
+ }
228
+ else if (!controlName) {
229
+ return this.getFormValidationErrorsPrivate(form);
230
+ }
231
+ else {
232
+ const control = form.get(controlName);
233
+ if (control) {
234
+ return this.getFormValidationErrorsPrivate(control, controlName);
235
+ }
236
+ else {
237
+ return [];
238
+ }
239
+ }
240
+ }
241
+ getControlNameTranslateKey(controlName) {
242
+ const controlNameTranslateKeyMap = this.controlNameTranslateKeyMap();
243
+ if (!controlNameTranslateKeyMap) {
244
+ return undefined;
245
+ }
246
+ return controlNameTranslateKeyMap.get(controlName) ?? controlName;
247
+ }
248
+ getFormValidationErrorsPrivate(control, controlName) {
249
+ let errors = [];
250
+ // a form must either consist of
251
+ // a) a formgroup (with nested form controls or groups) or
252
+ // b) a single form control
253
+ if (control instanceof FormGroup) {
254
+ const formGroupErrors = this.getFormGroupErrors(control);
255
+ errors = errors.concat(formGroupErrors);
256
+ if (control.controls) {
257
+ Object.keys(control.controls).forEach(key => {
258
+ const formGroupControl = control.controls[key];
259
+ const formGroupControlErrors = this.getFormValidationErrorsPrivate(formGroupControl, key);
260
+ errors = errors.concat(formGroupControlErrors);
261
+ });
262
+ }
263
+ }
264
+ else if (control instanceof FormControl) {
265
+ errors.push(...this.errorResolver
266
+ .resolveErrors(controlName, control.errors, undefined, this.formErrorMapper())
267
+ .map(error => ({
268
+ controlName,
269
+ errorCode: error.key,
270
+ errorParams: error.params,
271
+ errorCodeTranslationKey: error.message,
272
+ controlNameTranslationKey: controlName
273
+ ? this.getControlNameTranslateKey(controlName)
274
+ : undefined
275
+ })));
276
+ }
277
+ return errors;
278
+ }
279
+ getFormGroupErrors(formGroup) {
280
+ return this.errorResolver
281
+ .resolveErrors(null, formGroup.errors, undefined, this.formErrorMapper())
282
+ .map(error => ({
283
+ errorCode: error.key,
284
+ errorParams: error.params,
285
+ errorCodeTranslationKey: error.message
286
+ }));
287
+ }
288
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiFormContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
289
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.6", type: SiFormContainerComponent, isStandalone: true, selector: "si-form-container", inputs: { form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, contentContainerBreakpoints: { classPropertyName: "contentContainerBreakpoints", publicName: "contentContainerBreakpoints", isSignal: true, isRequired: false, transformFunction: null }, disableContainerBreakpoints: { classPropertyName: "disableContainerBreakpoints", publicName: "disableContainerBreakpoints", isSignal: true, isRequired: false, transformFunction: null }, errorCodeTranslateKeyMap: { classPropertyName: "errorCodeTranslateKeyMap", publicName: "errorCodeTranslateKeyMap", isSignal: true, isRequired: false, transformFunction: null }, controlNameTranslateKeyMap: { classPropertyName: "controlNameTranslateKeyMap", publicName: "controlNameTranslateKeyMap", isSignal: true, isRequired: false, transformFunction: null }, disableErrorPrinting: { classPropertyName: "disableErrorPrinting", publicName: "disableErrorPrinting", isSignal: true, isRequired: false, transformFunction: null }, labelWidth: { classPropertyName: "labelWidth", publicName: "labelWidth", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.--si-form-label-width": "labelWidth()" } }, ngImport: i0, template: "<div class=\"d-flex flex-column align-content-stretch flex-grow-1 flex-shrink-1\">\n @if (disableContainerBreakpoints() || hasParentContainer) {\n <div class=\"flex-grow-1 flex-shrink-1\">\n <ng-container *ngTemplateOutlet=\"contentTemplate\" />\n </div>\n } @else {\n <div\n class=\"flex-grow-1 flex-shrink-1\"\n siResponsiveContainer\n [breakpoints]=\"contentContainerBreakpoints()\"\n >\n <ng-container *ngTemplateOutlet=\"contentTemplate\" />\n </div>\n }\n\n @if (!readonly()) {\n <div class=\"d-flex flex-row flex-nowrap flex-grow-0 flex-shrink-0 py-4\">\n <div\n class=\"d-flex flex-grow-1 flex-shrink-1 justify-content-end text-end overflow-hidden mx-6 my-auto\"\n [class.text-success]=\"validFormContainerMessage\"\n [class.text-danger]=\"invalidFormContainerMessage\"\n >\n <ng-content select=\"[si-form-container-message]\" />\n </div>\n\n <div class=\"m-auto flex-grow-0 flex-shrink-0\">\n <ng-content select=\"[si-form-container-buttons]\" />\n </div>\n </div>\n }\n</div>\n\n<ng-template #contentTemplate>\n <ng-content select=\"[si-form-container-content]\" />\n</ng-template>\n", styles: [":host{display:flex;flex:1 1 auto;flex-direction:column}:host ::slotted([si-form-container-message]),:host ::ng-deep [si-form-container-message]{max-inline-size:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.form-container-edit-help{text-decoration:underline;cursor:pointer}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: SiResponsiveContainerDirective, selector: "[siResponsiveContainer]", inputs: ["resizeThrottle", "breakpoints"], exportAs: ["siResponsiveContainer"] }, { kind: "ngmodule", type: SiTranslateModule }] });
290
+ }
291
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiFormContainerComponent, decorators: [{
292
+ type: Component,
293
+ args: [{ selector: 'si-form-container', imports: [NgTemplateOutlet, SiResponsiveContainerDirective, SiTranslateModule], host: {
294
+ '[style.--si-form-label-width]': 'labelWidth()'
295
+ }, template: "<div class=\"d-flex flex-column align-content-stretch flex-grow-1 flex-shrink-1\">\n @if (disableContainerBreakpoints() || hasParentContainer) {\n <div class=\"flex-grow-1 flex-shrink-1\">\n <ng-container *ngTemplateOutlet=\"contentTemplate\" />\n </div>\n } @else {\n <div\n class=\"flex-grow-1 flex-shrink-1\"\n siResponsiveContainer\n [breakpoints]=\"contentContainerBreakpoints()\"\n >\n <ng-container *ngTemplateOutlet=\"contentTemplate\" />\n </div>\n }\n\n @if (!readonly()) {\n <div class=\"d-flex flex-row flex-nowrap flex-grow-0 flex-shrink-0 py-4\">\n <div\n class=\"d-flex flex-grow-1 flex-shrink-1 justify-content-end text-end overflow-hidden mx-6 my-auto\"\n [class.text-success]=\"validFormContainerMessage\"\n [class.text-danger]=\"invalidFormContainerMessage\"\n >\n <ng-content select=\"[si-form-container-message]\" />\n </div>\n\n <div class=\"m-auto flex-grow-0 flex-shrink-0\">\n <ng-content select=\"[si-form-container-buttons]\" />\n </div>\n </div>\n }\n</div>\n\n<ng-template #contentTemplate>\n <ng-content select=\"[si-form-container-content]\" />\n</ng-template>\n", styles: [":host{display:flex;flex:1 1 auto;flex-direction:column}:host ::slotted([si-form-container-message]),:host ::ng-deep [si-form-container-message]{max-inline-size:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.form-container-edit-help{text-decoration:underline;cursor:pointer}\n"] }]
296
+ }] });
297
+
298
+ /**
299
+ * Copyright Siemens 2016 - 2025.
300
+ * SPDX-License-Identifier: MIT
301
+ */
302
+ class SiFormFieldsetComponent {
303
+ static labelIdCounter = 0;
304
+ /** The label for the entire fieldset. */
305
+ label = input.required();
306
+ /** Overrides the parent label width. */
307
+ labelWidth = input();
308
+ /**
309
+ * Adds a required marker to the label
310
+ *
311
+ * @defaultValue false
312
+ */
313
+ required = input(false, { transform: booleanAttribute });
314
+ /**
315
+ * Switches all child inputs to inline mode
316
+ *
317
+ * @defaultValue false
318
+ */
319
+ inline = input(false, { transform: booleanAttribute });
320
+ formItems = signal([]);
321
+ /** @internal */
322
+ hasOnlyRadios = computed(() => {
323
+ // Check if the fieldset only contains radio buttons.
324
+ // We can safely assume that, if all items have the same control name and if there are at least 2 items.
325
+ const items = this.formItems();
326
+ if (items.length > 1) {
327
+ const first = items[0];
328
+ return items.every(item => item.ngControl()?.name === first.ngControl()?.name);
329
+ }
330
+ return false;
331
+ });
332
+ errors = computed(() =>
333
+ // All errors should be the same for radios, so we just take the first.
334
+ this.hasOnlyRadios() ? this.formItems()[0].errors() : []);
335
+ touched = signal(false);
336
+ isRequired = computed(() => this.required() || (this.hasOnlyRadios() && this.formItems().every(item => item.required())));
337
+ labelId = `__si-form-fieldset-label-${SiFormFieldsetComponent.labelIdCounter++}`;
338
+ ngDoCheck() {
339
+ this.touched.set(this.formItems().some(item => item.ngControl()?.touched));
340
+ }
341
+ /** @internal */
342
+ registerFormItem(item) {
343
+ this.formItems.update(items => [...items, item]);
344
+ }
345
+ /** @internal */
346
+ unregisterFormItem(item) {
347
+ this.formItems.update(items => items.filter(i => i !== item));
348
+ }
349
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiFormFieldsetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
350
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.6", type: SiFormFieldsetComponent, isStandalone: true, selector: "si-form-fieldset", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, labelWidth: { classPropertyName: "labelWidth", publicName: "labelWidth", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, inline: { classPropertyName: "inline", publicName: "inline", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "group" }, properties: { "style.--si-form-label-width": "labelWidth()", "attr.aria-labelledby": "this.labelId" }, classAttribute: "si-form-input" }, ngImport: i0, template: "<div class=\"pt-1 pb-0\">\n <div class=\"form-label\" [class.required]=\"isRequired()\" [id]=\"labelId\">{{\n label() | translate\n }}</div>\n</div>\n<div>\n <ng-content />\n @if (hasOnlyRadios()) {\n <div class=\"invalid-feedback\" [class.d-block]=\"touched()\">\n @for (error of errors(); track error) {\n <div>\n {{ error.message | translate: error.params }}\n </div>\n }\n </div>\n }\n</div>\n", styles: [":host.si-form-input{margin-block-end:12px;display:flex;flex-direction:column}:host.si-form-input .form-item-content{flex:1 1 0;display:flex;align-items:center;flex-wrap:wrap;position:relative}.form-label:empty{display:none}:host-context(si-form-fieldset) :host(.form-check):not(.form-check-inline){display:block}:host(.form-check):has(.form-check){padding-block:0}:host-context(.si-container-sm),:host-context(.si-container-md),:host-context(.si-container-lg),:host-context(.si-container-xl),:host-context(.si-container-xxl){flex-direction:row}:host-context(.si-container-sm) .form-label,:host-context(.si-container-md) .form-label,:host-context(.si-container-lg) .form-label,:host-context(.si-container-xl) .form-label,:host-context(.si-container-xxl) .form-label{padding-block:8px;padding-inline:16px;inline-size:var(--si-form-label-width, 16.6666666667%);line-height:1.143}:host-context(.si-container-sm) .form-label:empty,:host-context(.si-container-md) .form-label:empty,:host-context(.si-container-lg) .form-label:empty,:host-context(.si-container-xl) .form-label:empty,:host-context(.si-container-xxl) .form-label:empty{display:block}:host-context(.si-container-sm) :host-context(si-form-fieldset) .form-label,:host-context(.si-container-md) :host-context(si-form-fieldset) .form-label,:host-context(.si-container-lg) :host-context(si-form-fieldset) .form-label,:host-context(.si-container-xl) :host-context(si-form-fieldset) .form-label,:host-context(.si-container-xxl) :host-context(si-form-fieldset) .form-label{padding-block:0}:host-context(.si-container-sm) :host(.form-check) .form-label,:host-context(.si-container-md) :host(.form-check) .form-label,:host-context(.si-container-lg) :host(.form-check) .form-label,:host-context(.si-container-xl) :host(.form-check) .form-label,:host-context(.si-container-xxl) :host(.form-check) .form-label{padding-block:2px}\n"], dependencies: [{ kind: "ngmodule", type: SiTranslateModule }, { kind: "pipe", type: i1.SiTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
351
+ }
352
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiFormFieldsetComponent, decorators: [{
353
+ type: Component,
354
+ args: [{ selector: 'si-form-fieldset', imports: [SiTranslateModule], host: {
355
+ role: 'group',
356
+ class: 'si-form-input',
357
+ '[style.--si-form-label-width]': 'labelWidth()'
358
+ }, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"pt-1 pb-0\">\n <div class=\"form-label\" [class.required]=\"isRequired()\" [id]=\"labelId\">{{\n label() | translate\n }}</div>\n</div>\n<div>\n <ng-content />\n @if (hasOnlyRadios()) {\n <div class=\"invalid-feedback\" [class.d-block]=\"touched()\">\n @for (error of errors(); track error) {\n <div>\n {{ error.message | translate: error.params }}\n </div>\n }\n </div>\n }\n</div>\n", styles: [":host.si-form-input{margin-block-end:12px;display:flex;flex-direction:column}:host.si-form-input .form-item-content{flex:1 1 0;display:flex;align-items:center;flex-wrap:wrap;position:relative}.form-label:empty{display:none}:host-context(si-form-fieldset) :host(.form-check):not(.form-check-inline){display:block}:host(.form-check):has(.form-check){padding-block:0}:host-context(.si-container-sm),:host-context(.si-container-md),:host-context(.si-container-lg),:host-context(.si-container-xl),:host-context(.si-container-xxl){flex-direction:row}:host-context(.si-container-sm) .form-label,:host-context(.si-container-md) .form-label,:host-context(.si-container-lg) .form-label,:host-context(.si-container-xl) .form-label,:host-context(.si-container-xxl) .form-label{padding-block:8px;padding-inline:16px;inline-size:var(--si-form-label-width, 16.6666666667%);line-height:1.143}:host-context(.si-container-sm) .form-label:empty,:host-context(.si-container-md) .form-label:empty,:host-context(.si-container-lg) .form-label:empty,:host-context(.si-container-xl) .form-label:empty,:host-context(.si-container-xxl) .form-label:empty{display:block}:host-context(.si-container-sm) :host-context(si-form-fieldset) .form-label,:host-context(.si-container-md) :host-context(si-form-fieldset) .form-label,:host-context(.si-container-lg) :host-context(si-form-fieldset) .form-label,:host-context(.si-container-xl) :host-context(si-form-fieldset) .form-label,:host-context(.si-container-xxl) :host-context(si-form-fieldset) .form-label{padding-block:0}:host-context(.si-container-sm) :host(.form-check) .form-label,:host-context(.si-container-md) :host(.form-check) .form-label,:host-context(.si-container-lg) :host(.form-check) .form-label,:host-context(.si-container-xl) :host(.form-check) .form-label,:host-context(.si-container-xxl) :host(.form-check) .form-label{padding-block:2px}\n"] }]
359
+ }], propDecorators: { labelId: [{
360
+ type: HostBinding,
361
+ args: ['attr.aria-labelledby']
362
+ }] } });
363
+
364
+ /**
365
+ * Copyright Siemens 2016 - 2025.
366
+ * SPDX-License-Identifier: MIT
367
+ */
368
+ const SI_FORM_ITEM_CONTROL = new InjectionToken('si.form-item.control');
369
+
370
+ /**
371
+ * This will be used by the `si-form-item` to create a form item control if none is provided.
372
+ * This is typically the case for native form controls like `input`, `textarea` and `select`.
373
+ * It allows accessing the control's id and type.
374
+ */
375
+ class SiFormFieldNativeControl {
376
+ element;
377
+ static idCounter = 0;
378
+ static supportedTypes = ['INPUT', 'TEXTAREA', 'SELECT', 'METER', 'PROGRESS'];
379
+ static createForElementRef(element) {
380
+ if (!element) {
381
+ return undefined;
382
+ }
383
+ if (!SiFormFieldNativeControl.supportedTypes.includes(element.nativeElement.tagName)) {
384
+ return undefined;
385
+ }
386
+ return new SiFormFieldNativeControl(element.nativeElement);
387
+ }
388
+ constructor(element) {
389
+ this.element = element;
390
+ if (!element.id) {
391
+ element.id = `__si-form-field-native-control-${SiFormFieldNativeControl.idCounter++}`;
392
+ }
393
+ this.errormessageId = `${this.id}-errormessage`;
394
+ if (element instanceof HTMLInputElement) {
395
+ this.isFormCheck = element.type === 'checkbox' || element.type === 'radio';
396
+ }
397
+ else {
398
+ this.isFormCheck = false;
399
+ }
400
+ element.setAttribute('aria-describedby', this.errormessageId);
401
+ }
402
+ isFormCheck;
403
+ get id() {
404
+ return this.element?.id;
405
+ }
406
+ set id(value) {
407
+ this.element.id = value;
408
+ }
409
+ errormessageId;
410
+ }
411
+
412
+ /**
413
+ * Copyright Siemens 2016 - 2025.
414
+ * SPDX-License-Identifier: MIT
415
+ */
416
+ class SiFormItemComponent {
417
+ /** @deprecated property has longer an effect. SiFormItem detects IDs automatically */
418
+ inputId;
419
+ /**
420
+ * The label to be displayed in the form item.
421
+ * It will be translated if a translation key is available.
422
+ */
423
+ label = input();
424
+ /**
425
+ * A custom width value to be applied to the label.
426
+ * A value of 0 is allowed as well to visually hide away the label area.
427
+ *
428
+ * Numbers will be converted to pixels.
429
+ * Using numbers is discouraged and might be dropped.
430
+ *
431
+ * @example labelWidth="100px"
432
+ */
433
+ labelWidth = input();
434
+ /**
435
+ * @deprecated This input has no effect and can be removed.
436
+ *
437
+ * @defaultValue false
438
+ */
439
+ readonly = false;
440
+ /**
441
+ * Disables the automatic error printing. Error printing will be enabled by default in v46.
442
+ *
443
+ * @defaultValue false
444
+ */
445
+ disableErrorPrinting = input(false, { transform: booleanAttribute });
446
+ formErrorMapper = input();
447
+ /**
448
+ * Defines that this form item is required for the overall form to be valid.
449
+ *
450
+ * @defaultValue false
451
+ */
452
+ // eslint-disable-next-line @angular-eslint/no-input-rename
453
+ requiredInput = input(false, { transform: booleanAttribute, alias: 'required' });
454
+ fieldControlQuery = contentChild(SI_FORM_ITEM_CONTROL, { descendants: true });
455
+ /** @internal */
456
+ ngControl = contentChild(NgControl, { descendants: true });
457
+ controlElementRef = contentChild(NgControl, {
458
+ read: ElementRef,
459
+ descendants: true
460
+ });
461
+ requiredValidator = contentChild(RequiredValidator, { descendants: true });
462
+ /** @internal */
463
+ errors = signal([]);
464
+ /** @deprecated Remove with v48 */
465
+ isLegacyMode = signal(false);
466
+ fieldset = inject(SiFormFieldsetComponent, { optional: true });
467
+ container = inject(SiFormContainerComponent, { optional: true });
468
+ get formItemId() {
469
+ const fieldControl = this.fieldControl();
470
+ return isSignal(fieldControl?.id) ? (fieldControl.id() ?? null) : (fieldControl?.id ?? null);
471
+ }
472
+ get formItemLabelledBy() {
473
+ const fieldControl = this.fieldControl();
474
+ return isSignal(fieldControl?.labelledby)
475
+ ? (fieldControl.labelledby() ?? null)
476
+ : (fieldControl?.labelledby ?? null);
477
+ }
478
+ get formItemErrormessageId() {
479
+ const fieldControl = this.fieldControl();
480
+ return isSignal(fieldControl?.errormessageId)
481
+ ? (fieldControl?.errormessageId() ?? null)
482
+ : (fieldControl?.errormessageId ?? null);
483
+ }
484
+ fieldControl = computed(() => this.fieldControlQuery() ?? this.fieldControlNative());
485
+ elementRef = inject(ElementRef);
486
+ validationErrorService = inject(SiFormValidationErrorService);
487
+ requiredTestControl = new FormControl('');
488
+ validator;
489
+ previousErrors;
490
+ hasRequiredValidator = signal(false);
491
+ fieldControlNative = signal(undefined);
492
+ labelWidthCssVar = computed(() => {
493
+ const labelWidth = this.labelWidth();
494
+ if (typeof labelWidth === 'number') {
495
+ return `${labelWidth}px`;
496
+ }
497
+ return labelWidth;
498
+ });
499
+ printErrors = computed(() => {
500
+ return !this.disableErrorPrinting() && !(this.container?.disableErrorPrinting() ?? false);
501
+ });
502
+ /** @internal */
503
+ required = computed(() => this.requiredInput() || this.hasRequiredValidator());
504
+ ngOnChanges(changes) {
505
+ if (changes.formErrorMapper) {
506
+ this.updateValidationMessages();
507
+ }
508
+ }
509
+ ngOnInit() {
510
+ this.fieldset?.registerFormItem(this);
511
+ }
512
+ ngAfterContentInit() {
513
+ if (!this.fieldControlQuery()) {
514
+ this.fieldControlNative.set(SiFormFieldNativeControl.createForElementRef(this.controlElementRef()));
515
+ }
516
+ }
517
+ ngAfterContentChecked() {
518
+ this.updateRequiredState();
519
+ this.updateValidationMessages();
520
+ }
521
+ ngAfterViewInit() {
522
+ this.isLegacyMode.set(!!this.elementRef.nativeElement.querySelector('.form-check'));
523
+ }
524
+ ngOnDestroy() {
525
+ this.fieldset?.unregisterFormItem(this);
526
+ }
527
+ updateRequiredState() {
528
+ const requiredValidator = this.requiredValidator();
529
+ if (requiredValidator) {
530
+ // the easy case: required validator is applied in the template: <input required>
531
+ this.hasRequiredValidator.set(booleanAttribute(requiredValidator.required));
532
+ }
533
+ else {
534
+ // No required validator is applied via template, it could still be applied in the code.
535
+ // If validators are applied via code, the validator object will change of controls.
536
+ // So we only need to check for required if the validator object was changed.
537
+ const validator = this.ngControl()?.control?.validator;
538
+ if (this.validator !== validator) {
539
+ this.validator = validator;
540
+ this.requiredTestControl.setValidators(this.validator ?? null);
541
+ this.requiredTestControl.updateValueAndValidity();
542
+ this.hasRequiredValidator.set(this.requiredTestControl.errors?.required ?? false);
543
+ }
544
+ }
545
+ }
546
+ updateValidationMessages() {
547
+ const control = this.ngControl();
548
+ const currentErrors = control?.errors;
549
+ if (this.previousErrors !== currentErrors) {
550
+ if (control && this.printErrors()) {
551
+ this.errors.set(this.validationErrorService
552
+ .resolveErrors(control.name, control.errors, this.formErrorMapper(), this.container?.formErrorMapper())
553
+ .filter(error => error.message));
554
+ this.previousErrors = currentErrors;
555
+ }
556
+ else if (this.errors().length) {
557
+ this.errors.set([]);
558
+ }
559
+ }
560
+ }
561
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiFormItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
562
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.6", type: SiFormItemComponent, isStandalone: true, selector: "si-form-item", inputs: { inputId: { classPropertyName: "inputId", publicName: "inputId", isSignal: false, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelWidth: { classPropertyName: "labelWidth", publicName: "labelWidth", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: false, isRequired: false, transformFunction: booleanAttribute }, disableErrorPrinting: { classPropertyName: "disableErrorPrinting", publicName: "disableErrorPrinting", isSignal: true, isRequired: false, transformFunction: null }, formErrorMapper: { classPropertyName: "formErrorMapper", publicName: "formErrorMapper", isSignal: true, isRequired: false, transformFunction: null }, requiredInput: { classPropertyName: "requiredInput", publicName: "required", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.required": "required()", "style.--si-form-label-width": "labelWidthCssVar()", "class.form-check": "fieldControl()?.isFormCheck", "class.form-check-inline": "fieldset?.inline()", "class.si-form-input": "!fieldset" } }, queries: [{ propertyName: "fieldControlQuery", first: true, predicate: SI_FORM_ITEM_CONTROL, descendants: true, isSignal: true }, { propertyName: "ngControl", first: true, predicate: NgControl, descendants: true, isSignal: true }, { propertyName: "controlElementRef", first: true, predicate: NgControl, descendants: true, read: ElementRef, isSignal: true }, { propertyName: "requiredValidator", first: true, predicate: RequiredValidator, descendants: true, isSignal: true }], usesOnChanges: true, ngImport: i0, template: "@if (!fieldControl()?.isFormCheck || (isLegacyMode() && label())) {\n @if (label()) {\n @let labeledBy = formItemLabelledBy;\n @if (labeledBy) {\n <span\n class=\"text-break form-label\"\n [id]=\"labeledBy\"\n [class.required]=\"required() && !this.fieldset?.hasOnlyRadios()\"\n >{{ label() | translate }}</span\n >\n } @else {\n <label class=\"text-break form-label\" [for]=\"formItemId\" [class.required]=\"required()\">{{\n label() | translate\n }}</label>\n }\n }\n <div class=\"form-item-content\">\n <ng-container [ngTemplateOutlet]=\"content\" />\n @if (printErrors() && !fieldset?.hasOnlyRadios()) {\n <div class=\"invalid-feedback\" [attr.id]=\"formItemErrormessageId\">\n @for (error of errors(); track error.key) {\n <div>\n {{ error.message | translate: error.params }}\n </div>\n }\n </div>\n }\n </div>\n} @else {\n <!--Block the space if no form-field is provided. Otherwise it looks weird.-->\n @if (!fieldset) {\n <div class=\"form-label\"></div>\n }\n <div class=\"form-item-content\">\n <ng-container [ngTemplateOutlet]=\"checkbox\" />\n @if (label()) {\n @if (fieldControl()?.labelledby) {\n <span\n class=\"text-break form-check-label\"\n [id]=\"fieldControl()!.labelledby\"\n [class.required]=\"required() && !this.fieldset?.hasOnlyRadios()\"\n >{{ label()! | translate }}</span\n >\n } @else {\n <label\n class=\"text-break form-check-label\"\n [for]=\"formItemId\"\n [class.required]=\"required() && !this.fieldset?.hasOnlyRadios()\"\n >{{ label()! | translate }}</label\n >\n }\n }\n <ng-container [ngTemplateOutlet]=\"content\" />\n @if (printErrors() && !fieldset?.hasOnlyRadios()) {\n <div class=\"invalid-feedback\" [attr.id]=\"formItemErrormessageId\">\n @for (error of errors(); track error.key) {\n <div>\n {{ error.message | translate: error.params }}\n </div>\n }\n </div>\n }\n </div>\n}\n\n<ng-template #checkbox>\n <ng-content select=\"input[type='checkbox'], input[type='radio']\" />\n</ng-template>\n<ng-template #content>\n <ng-content />\n</ng-template>\n", styles: [":host.si-form-input{margin-block-end:12px;display:flex;flex-direction:column}:host.si-form-input .form-item-content{flex:1 1 0;display:flex;align-items:center;flex-wrap:wrap;position:relative}.form-label:empty{display:none}:host-context(si-form-fieldset) :host(.form-check):not(.form-check-inline){display:block}:host(.form-check):has(.form-check){padding-block:0}:host-context(.si-container-sm),:host-context(.si-container-md),:host-context(.si-container-lg),:host-context(.si-container-xl),:host-context(.si-container-xxl){flex-direction:row}:host-context(.si-container-sm) .form-label,:host-context(.si-container-md) .form-label,:host-context(.si-container-lg) .form-label,:host-context(.si-container-xl) .form-label,:host-context(.si-container-xxl) .form-label{padding-block:8px;padding-inline:16px;inline-size:var(--si-form-label-width, 16.6666666667%);line-height:1.143}:host-context(.si-container-sm) .form-label:empty,:host-context(.si-container-md) .form-label:empty,:host-context(.si-container-lg) .form-label:empty,:host-context(.si-container-xl) .form-label:empty,:host-context(.si-container-xxl) .form-label:empty{display:block}:host-context(.si-container-sm) :host-context(si-form-fieldset) .form-label,:host-context(.si-container-md) :host-context(si-form-fieldset) .form-label,:host-context(.si-container-lg) :host-context(si-form-fieldset) .form-label,:host-context(.si-container-xl) :host-context(si-form-fieldset) .form-label,:host-context(.si-container-xxl) :host-context(si-form-fieldset) .form-label{padding-block:0}:host-context(.si-container-sm) :host(.form-check) .form-label,:host-context(.si-container-md) :host(.form-check) .form-label,:host-context(.si-container-lg) :host(.form-check) .form-label,:host-context(.si-container-xl) :host(.form-check) .form-label,:host-context(.si-container-xxl) :host(.form-check) .form-label{padding-block:2px}\n"], dependencies: [{ kind: "ngmodule", type: SiTranslateModule }, { kind: "pipe", type: i1.SiTranslatePipe, name: "translate" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
563
+ }
564
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiFormItemComponent, decorators: [{
565
+ type: Component,
566
+ args: [{ selector: 'si-form-item', imports: [SiTranslateModule, NgTemplateOutlet], changeDetection: ChangeDetectionStrategy.OnPush, host: {
567
+ '[class.required]': 'required()',
568
+ '[style.--si-form-label-width]': 'labelWidthCssVar()',
569
+ '[class.form-check]': 'fieldControl()?.isFormCheck',
570
+ '[class.form-check-inline]': 'fieldset?.inline()',
571
+ '[class.si-form-input]': '!fieldset'
572
+ }, template: "@if (!fieldControl()?.isFormCheck || (isLegacyMode() && label())) {\n @if (label()) {\n @let labeledBy = formItemLabelledBy;\n @if (labeledBy) {\n <span\n class=\"text-break form-label\"\n [id]=\"labeledBy\"\n [class.required]=\"required() && !this.fieldset?.hasOnlyRadios()\"\n >{{ label() | translate }}</span\n >\n } @else {\n <label class=\"text-break form-label\" [for]=\"formItemId\" [class.required]=\"required()\">{{\n label() | translate\n }}</label>\n }\n }\n <div class=\"form-item-content\">\n <ng-container [ngTemplateOutlet]=\"content\" />\n @if (printErrors() && !fieldset?.hasOnlyRadios()) {\n <div class=\"invalid-feedback\" [attr.id]=\"formItemErrormessageId\">\n @for (error of errors(); track error.key) {\n <div>\n {{ error.message | translate: error.params }}\n </div>\n }\n </div>\n }\n </div>\n} @else {\n <!--Block the space if no form-field is provided. Otherwise it looks weird.-->\n @if (!fieldset) {\n <div class=\"form-label\"></div>\n }\n <div class=\"form-item-content\">\n <ng-container [ngTemplateOutlet]=\"checkbox\" />\n @if (label()) {\n @if (fieldControl()?.labelledby) {\n <span\n class=\"text-break form-check-label\"\n [id]=\"fieldControl()!.labelledby\"\n [class.required]=\"required() && !this.fieldset?.hasOnlyRadios()\"\n >{{ label()! | translate }}</span\n >\n } @else {\n <label\n class=\"text-break form-check-label\"\n [for]=\"formItemId\"\n [class.required]=\"required() && !this.fieldset?.hasOnlyRadios()\"\n >{{ label()! | translate }}</label\n >\n }\n }\n <ng-container [ngTemplateOutlet]=\"content\" />\n @if (printErrors() && !fieldset?.hasOnlyRadios()) {\n <div class=\"invalid-feedback\" [attr.id]=\"formItemErrormessageId\">\n @for (error of errors(); track error.key) {\n <div>\n {{ error.message | translate: error.params }}\n </div>\n }\n </div>\n }\n </div>\n}\n\n<ng-template #checkbox>\n <ng-content select=\"input[type='checkbox'], input[type='radio']\" />\n</ng-template>\n<ng-template #content>\n <ng-content />\n</ng-template>\n", styles: [":host.si-form-input{margin-block-end:12px;display:flex;flex-direction:column}:host.si-form-input .form-item-content{flex:1 1 0;display:flex;align-items:center;flex-wrap:wrap;position:relative}.form-label:empty{display:none}:host-context(si-form-fieldset) :host(.form-check):not(.form-check-inline){display:block}:host(.form-check):has(.form-check){padding-block:0}:host-context(.si-container-sm),:host-context(.si-container-md),:host-context(.si-container-lg),:host-context(.si-container-xl),:host-context(.si-container-xxl){flex-direction:row}:host-context(.si-container-sm) .form-label,:host-context(.si-container-md) .form-label,:host-context(.si-container-lg) .form-label,:host-context(.si-container-xl) .form-label,:host-context(.si-container-xxl) .form-label{padding-block:8px;padding-inline:16px;inline-size:var(--si-form-label-width, 16.6666666667%);line-height:1.143}:host-context(.si-container-sm) .form-label:empty,:host-context(.si-container-md) .form-label:empty,:host-context(.si-container-lg) .form-label:empty,:host-context(.si-container-xl) .form-label:empty,:host-context(.si-container-xxl) .form-label:empty{display:block}:host-context(.si-container-sm) :host-context(si-form-fieldset) .form-label,:host-context(.si-container-md) :host-context(si-form-fieldset) .form-label,:host-context(.si-container-lg) :host-context(si-form-fieldset) .form-label,:host-context(.si-container-xl) :host-context(si-form-fieldset) .form-label,:host-context(.si-container-xxl) :host-context(si-form-fieldset) .form-label{padding-block:0}:host-context(.si-container-sm) :host(.form-check) .form-label,:host-context(.si-container-md) :host(.form-check) .form-label,:host-context(.si-container-lg) :host(.form-check) .form-label,:host-context(.si-container-xl) :host(.form-check) .form-label,:host-context(.si-container-xxl) :host(.form-check) .form-label{padding-block:2px}\n"] }]
573
+ }], propDecorators: { inputId: [{
574
+ type: Input
575
+ }], readonly: [{
576
+ type: Input,
577
+ args: [{ transform: booleanAttribute }]
578
+ }] } });
579
+
580
+ /**
581
+ * Copyright Siemens 2016 - 2025.
582
+ * SPDX-License-Identifier: MIT
583
+ */
584
+ const SI_FORM_VALIDATION_TOOLTIP_DATA = new InjectionToken('SiFormValidationTooltipData');
585
+ class SiFormValidationTooltipComponent {
586
+ errors = inject(SI_FORM_VALIDATION_TOOLTIP_DATA);
587
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiFormValidationTooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
588
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.6", type: SiFormValidationTooltipComponent, isStandalone: true, selector: "si-form-validation-tooltip", host: { classAttribute: "d-flex flex-column gap-2" }, ngImport: i0, template: `
589
+ @for (error of errors(); track error.key) {
590
+ <div>{{ error.message | translate: error.params }}</div>
591
+ }
592
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: SiTranslateModule }, { kind: "pipe", type: i1.SiTranslatePipe, name: "translate" }] });
593
+ }
594
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiFormValidationTooltipComponent, decorators: [{
595
+ type: Component,
596
+ args: [{
597
+ selector: 'si-form-validation-tooltip',
598
+ imports: [SiTranslateModule],
599
+ template: `
600
+ @for (error of errors(); track error.key) {
601
+ <div>{{ error.message | translate: error.params }}</div>
602
+ }
603
+ `,
604
+ host: {
605
+ 'class': 'd-flex flex-column gap-2'
606
+ }
607
+ }]
608
+ }] });
609
+
610
+ /**
611
+ * Copyright Siemens 2016 - 2025.
612
+ * SPDX-License-Identifier: MIT
613
+ */
614
+ /**
615
+ * Directive to show a tooltip with validation errors of a form control.
616
+ *
617
+ * In general, `si-form-item` should be used.
618
+ * This directive is intended only for cases where the tooltip cannot be shown inline.
619
+ * This is typically the case for tables and lists where the validation message would break the layout.
620
+ *
621
+ * @example
622
+ * ```html
623
+ * <input siFormValidationTooltip [formControl]="control" />
624
+ * ```
625
+ */
626
+ class SiFormValidationTooltipDirective {
627
+ static idCounter = 0;
628
+ tooltipService = inject(SiTooltipService);
629
+ formValidationService = inject(SiFormValidationErrorService);
630
+ formContainer = inject(SiFormContainerComponent, { optional: true });
631
+ formErrorMapper = input();
632
+ ngControl = inject(NgControl);
633
+ elementRef = inject(ElementRef);
634
+ tooltipRef;
635
+ errors = signal([]);
636
+ currentErrors = null;
637
+ touched = null;
638
+ // Use a counter to track how many events are matched that keep the tooltip active.
639
+ // Active means we are listening to error changes.
640
+ activationCount = 0;
641
+ describedBy = `__si-form-validation-tooltip-${SiFormValidationTooltipDirective.idCounter++}`;
642
+ ngDoCheck() {
643
+ if (this.activationCount &&
644
+ (this.currentErrors !== this.ngControl.errors || this.touched !== this.ngControl.touched)) {
645
+ this.currentErrors = this.ngControl.errors;
646
+ this.touched = this.ngControl.touched;
647
+ this.updateErrors();
648
+ }
649
+ }
650
+ ngOnDestroy() {
651
+ this.destroyTooltip();
652
+ }
653
+ increaseActivation() {
654
+ this.activationCount++;
655
+ if (this.activationCount === 1) {
656
+ this.updateErrors();
657
+ }
658
+ }
659
+ updateErrors() {
660
+ const errors = this.formValidationService
661
+ .resolveErrors(this.ngControl.name, this.currentErrors, this.formErrorMapper(), this.formContainer?.formErrorMapper())
662
+ .filter(error => !!error.message);
663
+ if (!this.tooltipRef && errors.length && this.ngControl.touched) {
664
+ this.tooltipRef = this.tooltipService.createTooltip({
665
+ placement: 'auto',
666
+ element: this.elementRef,
667
+ describedBy: this.describedBy,
668
+ injector: Injector.create({
669
+ providers: [{ provide: SI_FORM_VALIDATION_TOOLTIP_DATA, useValue: this.errors }]
670
+ })
671
+ });
672
+ this.tooltipRef.show(SiFormValidationTooltipComponent);
673
+ }
674
+ else if (this.tooltipRef && (!errors.length || this.ngControl.pristine)) {
675
+ this.destroyTooltip();
676
+ }
677
+ this.errors.set(errors);
678
+ }
679
+ decreaseActivation() {
680
+ this.activationCount--;
681
+ if (!this.activationCount) {
682
+ this.destroyTooltip();
683
+ }
684
+ }
685
+ destroyTooltip() {
686
+ this.tooltipRef?.destroy();
687
+ this.tooltipRef = undefined;
688
+ }
689
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiFormValidationTooltipDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
690
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.0.6", type: SiFormValidationTooltipDirective, isStandalone: true, selector: "[siFormValidationTooltip]", inputs: { formErrorMapper: { classPropertyName: "formErrorMapper", publicName: "formErrorMapper", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "focus": "increaseActivation()", "mouseenter": "increaseActivation()", "blur": "decreaseActivation()", "mouseleave": "decreaseActivation()" }, properties: { "attr.aria-describedby": "describedBy" } }, providers: [SiTooltipService], ngImport: i0 });
691
+ }
692
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiFormValidationTooltipDirective, decorators: [{
693
+ type: Directive,
694
+ args: [{
695
+ selector: '[siFormValidationTooltip]',
696
+ providers: [SiTooltipService],
697
+ host: {
698
+ '[attr.aria-describedby]': 'describedBy'
699
+ }
700
+ }]
701
+ }], propDecorators: { increaseActivation: [{
702
+ type: HostListener,
703
+ args: ['focus']
704
+ }, {
705
+ type: HostListener,
706
+ args: ['mouseenter']
707
+ }], decreaseActivation: [{
708
+ type: HostListener,
709
+ args: ['blur']
710
+ }, {
711
+ type: HostListener,
712
+ args: ['mouseleave']
713
+ }] } });
714
+
715
+ /**
716
+ * Copyright Siemens 2016 - 2025.
717
+ * SPDX-License-Identifier: MIT
718
+ */
719
+ /** @deprecated This directive is no longer needed. {@link SiFormItemComponent} will detect native controls automatically. */
720
+ class SiFormItemControlInputDirective {
721
+ static idCounter = 0;
722
+ id = `__si-form-element-control-input-${SiFormItemControlInputDirective.idCounter++}`;
723
+ set type(value) {
724
+ this.isFormCheck = value === 'checkbox' || value === 'radio';
725
+ this.formControlClass = this.isFormCheck ? 'form-check-input' : 'form-control';
726
+ }
727
+ formControlClass = 'form-control';
728
+ /**
729
+ * Indicate the form item is a checkbox or radio input.
730
+ * @defaultValue false
731
+ */
732
+ isFormCheck = false;
733
+ /** @internal */
734
+ errormessageId = `${this.id}-errormessage`;
735
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiFormItemControlInputDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
736
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.0.6", type: SiFormItemControlInputDirective, isStandalone: true, selector: "[siFormItemControl]", inputs: { id: "id", type: "type" }, host: { properties: { "id": "this.id", "class": "this.formControlClass", "attr.aria-describedby": "this.errormessageId" } }, providers: [{ provide: SI_FORM_ITEM_CONTROL, useExisting: SiFormItemControlInputDirective }], ngImport: i0 });
737
+ }
738
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiFormItemControlInputDirective, decorators: [{
739
+ type: Directive,
740
+ args: [{
741
+ selector: '[siFormItemControl]',
742
+ providers: [{ provide: SI_FORM_ITEM_CONTROL, useExisting: SiFormItemControlInputDirective }]
743
+ }]
744
+ }], propDecorators: { id: [{
745
+ type: Input
746
+ }, {
747
+ type: HostBinding,
748
+ args: ['id']
749
+ }], type: [{
750
+ type: Input
751
+ }], formControlClass: [{
752
+ type: HostBinding,
753
+ args: ['class']
754
+ }], errormessageId: [{
755
+ type: HostBinding,
756
+ args: ['attr.aria-describedby']
757
+ }] } });
758
+
759
+ /**
760
+ * The error mapper is used to resolve an angular validation error to a {@link TranslatableString}.
761
+ * It will be merged with already existing error mappers.
762
+ */
763
+ const provideFormValidationErrorMapper = (mapper) => ({
764
+ provide: SiFormValidationErrorService,
765
+ // defaults must always be provided in case this is called in app.config
766
+ useFactory: () => new SiFormValidationErrorService({ ...buildDefaults(), ...mapper })
767
+ });
768
+
769
+ /**
770
+ * Copyright Siemens 2016 - 2025.
771
+ * SPDX-License-Identifier: MIT
772
+ */
773
+ class SiFormModule {
774
+ /**
775
+ * Overrides the default configuration of the form module.
776
+ *
777
+ * @param errorMapper - The error mappers is used to resolve angular validation errors.
778
+ * It will be merged with already existing error mappers.
779
+ */
780
+ // We have the errorMapper wrapped in an object, to allow the addition of more configuration fields without breaking the API.
781
+ static withConfiguration({ validationErrorMapper }) {
782
+ return {
783
+ ngModule: SiFormModule,
784
+ providers: [provideFormValidationErrorMapper(validationErrorMapper)]
785
+ };
786
+ }
787
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiFormModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
788
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.6", ngImport: i0, type: SiFormModule, imports: [SiFormContainerComponent,
789
+ SiFormFieldsetComponent,
790
+ SiFormItemComponent,
791
+ SiFormItemControlInputDirective], exports: [SiFormContainerComponent,
792
+ SiFormFieldsetComponent,
793
+ SiFormItemComponent,
794
+ SiFormItemControlInputDirective] });
795
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiFormModule, imports: [SiFormContainerComponent,
796
+ SiFormFieldsetComponent,
797
+ SiFormItemComponent] });
798
+ }
799
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiFormModule, decorators: [{
800
+ type: NgModule,
801
+ args: [{
802
+ imports: [
803
+ SiFormContainerComponent,
804
+ SiFormFieldsetComponent,
805
+ SiFormItemComponent,
806
+ SiFormItemControlInputDirective
807
+ ],
808
+ exports: [
809
+ SiFormContainerComponent,
810
+ SiFormFieldsetComponent,
811
+ SiFormItemComponent,
812
+ SiFormItemControlInputDirective
813
+ ]
814
+ }]
815
+ }] });
816
+
817
+ /**
818
+ * Copyright Siemens 2016 - 2025.
819
+ * SPDX-License-Identifier: MIT
820
+ */
821
+
822
+ /**
823
+ * Generated bundle index. Do not edit.
824
+ */
825
+
826
+ export { SI_FORM_ITEM_CONTROL, SiFormContainerComponent, SiFormFieldsetComponent, SiFormItemComponent, SiFormItemControlInputDirective, SiFormModule, SiFormValidationTooltipDirective, provideFormValidationErrorMapper };
827
+ //# sourceMappingURL=siemens-element-ng-form.mjs.map