@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,480 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Component, input, booleanAttribute, model, viewChild, signal, computed, inject, ChangeDetectionStrategy } from '@angular/core';
3
+ import { NgTemplateOutlet } from '@angular/common';
4
+ import { DomSanitizer } from '@angular/platform-browser';
5
+ import * as i1 from '@siemens/element-ng/avatar';
6
+ import { SiAvatarBackgroundColorDirective } from '@siemens/element-ng/avatar';
7
+ import { addIcons, elementStateExclamationMark, elementCircleFilled, elementCancel, SiIconNextComponent, SiIconComponent } from '@siemens/element-ng/icon';
8
+ import { SiModalService } from '@siemens/element-ng/modal';
9
+ import * as i2 from '@siemens/element-translate-ng/translate';
10
+ import { SiTranslateModule } from '@siemens/element-translate-ng/translate';
11
+ import { ImageCropperComponent } from 'ngx-image-cropper';
12
+
13
+ /**
14
+ * Copyright Siemens 2016 - 2025.
15
+ * SPDX-License-Identifier: MIT
16
+ */
17
+ class SiImageCropperStyleComponent {
18
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiImageCropperStyleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
19
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.6", type: SiImageCropperStyleComponent, isStandalone: true, selector: "si-image-cropper-style", ngImport: i0, template: '<ng-content />', isInline: true, styles: [":host ::ng-deep image-cropper{max-block-size:70vh;--image-cropper-outline-color: var(--element-base-translucent-1);--cropper-outline-color: var(--image-cropper-outline-color);--cropper-overlay-color: var(--element-ui-5)}:host ::ng-deep image-cropper .ngx-ic-square{background:var(--element-ui-0)!important}:host ::ng-deep image-cropper .ngx-ic-cropper.ngx-ic-cropper{outline:2px solid var(--element-ui-0)!important}:host ::ng-deep image-cropper .ngx-ic-cropper.ngx-ic-cropper:after{z-index:0;border:unset;box-shadow:0 0 0 9999px var(--cropper-outline-color)}:host ::ng-deep image-cropper .ngx-ic-cropper.ngx-ic-cropper .ngx-ic-move.ngx-ic-move{position:relative;overflow:hidden;border:0}\n"] });
20
+ }
21
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiImageCropperStyleComponent, decorators: [{
22
+ type: Component,
23
+ args: [{ selector: 'si-image-cropper-style', template: '<ng-content />', styles: [":host ::ng-deep image-cropper{max-block-size:70vh;--image-cropper-outline-color: var(--element-base-translucent-1);--cropper-outline-color: var(--image-cropper-outline-color);--cropper-overlay-color: var(--element-ui-5)}:host ::ng-deep image-cropper .ngx-ic-square{background:var(--element-ui-0)!important}:host ::ng-deep image-cropper .ngx-ic-cropper.ngx-ic-cropper{outline:2px solid var(--element-ui-0)!important}:host ::ng-deep image-cropper .ngx-ic-cropper.ngx-ic-cropper:after{z-index:0;border:unset;box-shadow:0 0 0 9999px var(--cropper-outline-color)}:host ::ng-deep image-cropper .ngx-ic-cropper.ngx-ic-cropper .ngx-ic-move.ngx-ic-move{position:relative;overflow:hidden;border:0}\n"] }]
24
+ }] });
25
+
26
+ /**
27
+ * Copyright Siemens 2016 - 2025.
28
+ * SPDX-License-Identifier: MIT
29
+ */
30
+ /**
31
+ * A component used to upload, edit, and delete a user's photo. The user can upload
32
+ * a photo either via file browser or a URL to the photo. You can set the source
33
+ * photo with the `sourcePhoto` Data URL input or the `sourcePhotoUrl` URL input.
34
+ * If you already have a cropped image you can set it with the `croppedPhoto` input.
35
+ * Cropping changes are emitted via the `croppedPhotoChange` output.
36
+ */
37
+ class SiPhotoUploadComponent {
38
+ static idCounter = 0;
39
+ /**
40
+ * Indicate that changing or uploads are disabled.
41
+ *
42
+ * @defaultValue false
43
+ */
44
+ readonly = input(false, { transform: booleanAttribute });
45
+ /**
46
+ * Optionally disable image cropping.
47
+ *
48
+ * @defaultValue false
49
+ */
50
+ disabledCropping = input(false, { transform: booleanAttribute });
51
+ /**
52
+ * Accepted image formats for the file selection dialog.
53
+ *
54
+ * @defaultValue '.png, .jpg, .jpeg'
55
+ *
56
+ * @see
57
+ *
58
+ * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#attr-accept
59
+ */
60
+ acceptedUploadFormats = input('.png, .jpg, .jpeg');
61
+ /**
62
+ * Maximum allowed file size of the uploaded file in kilobytes.
63
+ *
64
+ * @defaultValue 2048
65
+ */
66
+ maxFileSize = input(2048);
67
+ /**
68
+ * If the uploaded file is of an unsupported type, this
69
+ * error message will be displayed to the user.
70
+ *
71
+ * @defaultValue
72
+ * ```
73
+ * $localize`:@@SI_PHOTO_UPLOAD.ERROR_FILE_TYPE:The image file is not valid. Please upload a PNG or JP(E)G.`
74
+ * ```
75
+ */
76
+ uploadErrorWrongType = input($localize `:@@SI_PHOTO_UPLOAD.ERROR_FILE_TYPE:The image file is not valid. Please upload a PNG or JP(E)G.`);
77
+ /**
78
+ * If the uploaded file exceeds the allowed upload size, this
79
+ * error message will be displayed to the user.
80
+ *
81
+ * @defaultValue
82
+ * ```
83
+ * $localize`:@@SI_PHOTO_UPLOAD.ERROR_FILE_SIZE_EXCEEDED:The actual file size {{mb}} MB exceeds the {{maxSizeMb}} MB limit.`
84
+ * ```
85
+ */
86
+ uploadErrorTooBig = input($localize `:@@SI_PHOTO_UPLOAD.ERROR_FILE_SIZE_EXCEEDED:The actual file size {{mb}} MB exceeds the {{maxSizeMb}} MB limit.`);
87
+ /**
88
+ * Alternative text for the photo.
89
+ *
90
+ * @defaultValue ''
91
+ */
92
+ photoAltText = input('');
93
+ /**
94
+ * Alternative text for the photo´s placeholder.
95
+ * The value will be used to calculate the background color when `autoColor` is true.
96
+ *
97
+ * @defaultValue ''
98
+ */
99
+ placeholderAltText = input('');
100
+ /**
101
+ * Text for the button changing the photo.
102
+ *
103
+ * @defaultValue
104
+ * ```
105
+ * $localize`:@@SI_PHOTO_UPLOAD.CHANGE_PHOTO:Change`
106
+ * ```
107
+ */
108
+ changePhotoText = input($localize `:@@SI_PHOTO_UPLOAD.CHANGE_PHOTO:Change`);
109
+ /**
110
+ * Cropper frame aria label.
111
+ *
112
+ * @defaultValue
113
+ * ```
114
+ * $localize`:@@SI_PHOTO_UPLOAD.CROPPER_FRAME_LABEL:Crop photo`
115
+ * ```
116
+ */
117
+ cropperFrameAriaLabel = input($localize `:@@SI_PHOTO_UPLOAD.CROPPER_FRAME_LABEL:Crop photo`);
118
+ /**
119
+ * Text for the button uploading a photo.
120
+ *
121
+ * @defaultValue
122
+ * ```
123
+ * $localize`:@@SI_PHOTO_UPLOAD.UPLOAD_PHOTO:Upload photo`
124
+ * ```
125
+ */
126
+ uploadPhotoText = input($localize `:@@SI_PHOTO_UPLOAD.UPLOAD_PHOTO:Upload photo`);
127
+ /**
128
+ * Text for the button removing the photo.
129
+ *
130
+ * @defaultValue
131
+ * ```
132
+ * $localize`:@@SI_PHOTO_UPLOAD.REMOVE:Remove`
133
+ * ```
134
+ */
135
+ removePhotoText = input($localize `:@@SI_PHOTO_UPLOAD.REMOVE:Remove`);
136
+ /**
137
+ * Text for the button cancelling the editing process.
138
+ *
139
+ * @defaultValue
140
+ * ```
141
+ * $localize`:@@SI_PHOTO_UPLOAD.CANCEL:Cancel`
142
+ * ```
143
+ */
144
+ cancelEditText = input($localize `:@@SI_PHOTO_UPLOAD.CANCEL:Cancel`);
145
+ /**
146
+ * Text for the button applying the edited photo.
147
+ *
148
+ * @defaultValue
149
+ * ```
150
+ * $localize`:@@SI_PHOTO_UPLOAD.APPLY_PHOTO:Apply`
151
+ * ```
152
+ */
153
+ applyEditText = input($localize `:@@SI_PHOTO_UPLOAD.APPLY_PHOTO:Apply`);
154
+ /**
155
+ * Text displayed as header of the editing modal.
156
+ *
157
+ * @defaultValue
158
+ * ```
159
+ * $localize`:@@SI_PHOTO_UPLOAD.MODAL_TITLE:Avatar photo`
160
+ * ```
161
+ */
162
+ modalHeader = input($localize `:@@SI_PHOTO_UPLOAD.MODAL_TITLE:Avatar photo`);
163
+ /**
164
+ * Text displayed as description of the editing modal.
165
+ */
166
+ modalDescription = input();
167
+ /**
168
+ * Output format of the edited image.
169
+ *
170
+ * @defaultValue 'jpeg'
171
+ */
172
+ cropperImageFormat = input('jpeg');
173
+ /**
174
+ * The width / height ratio (e.g. 1 / 1 for a square, 4 / 3, 16 / 9 ...).
175
+ *
176
+ * @defaultValue 1
177
+ */
178
+ cropperAspectRatio = input(1);
179
+ /**
180
+ * Whether to keep the width and height of the cropped image equal according
181
+ * to the aspectRatio.
182
+ *
183
+ * @defaultValue true
184
+ */
185
+ cropperMaintainAspectRatio = input(true, { transform: booleanAttribute });
186
+ /**
187
+ * When set to true, padding will be added around the image to make it fit to
188
+ * the aspect ratio. Be aware that this transformation will cause the loaded
189
+ * image to be a png file with an increased base64 string payload.
190
+ *
191
+ * @defaultValue false
192
+ */
193
+ cropperContainWithinAspectRatio = input(false, { transform: booleanAttribute });
194
+ /**
195
+ * The cropper´s width cannot be made smaller than this number of pixels
196
+ * (relative to original image´s size). (0 = disabled).
197
+ *
198
+ * @defaultValue 50
199
+ */
200
+ cropperMinWidth = input(50);
201
+ /**
202
+ * The cropper´s height cannot be made smaller than this number of pixels
203
+ * (relative to original image´s size). Will be ignored if
204
+ * `cropperMaintainAspectRatio` is set. (0 = disabled).
205
+ *
206
+ * @defaultValue 50
207
+ */
208
+ cropperMinHeight = input(50);
209
+ /**
210
+ * The cropper´s width cannot be made bigger than this number of pixels.
211
+ * Default is 0 (disabled).
212
+ *
213
+ * @defaultValue 0
214
+ */
215
+ cropperMaxWidth = input(0);
216
+ /**
217
+ * The cropper´s height cannot be made bigger than this number of pixels.
218
+ * Default is 0 (disabled).
219
+ *
220
+ * @defaultValue 0
221
+ */
222
+ cropperMaxHeight = input(0);
223
+ /**
224
+ * Set this to true for a round cropper. Resulting image will still
225
+ * be square, but visually clipped with a border-radius: 50% on the
226
+ * resulting image to show it as round.
227
+ *
228
+ * @defaultValue true
229
+ */
230
+ roundImage = input(true, { transform: booleanAttribute });
231
+ /**
232
+ * The input photo to be used for cropping. A string in [Data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs) format
233
+ * with base64 encoding.
234
+ */
235
+ sourcePhoto = model();
236
+ /**
237
+ * URL to a photo to be used for cropping.
238
+ */
239
+ sourcePhotoUrl = input();
240
+ /**
241
+ * The photo to be displayed and edited (when not readonly).
242
+ */
243
+ croppedPhoto = model();
244
+ editPhotoTemplate = viewChild.required('editPhotoTemplate');
245
+ fileInput = viewChild.required('fileInput');
246
+ imageCropper = viewChild('imageCropper');
247
+ // used to label the dialog
248
+ titleId = `__si-photo-upload-${SiPhotoUploadComponent.idCounter++}`;
249
+ /**
250
+ * The trusted photo url string which is used to display the photo.
251
+ */
252
+ sanitizedPhotoUrl = signal(undefined);
253
+ /**
254
+ * The appropriate error message displayed to the user. Might be
255
+ * `uploadErrorWrongType` or `uploadErrorTooBig`.
256
+ */
257
+ uploadErrorMessage = signal(undefined);
258
+ editButtonText = computed(() => this.sanitizedPhotoUrl() ? this.changePhotoText() : this.uploadPhotoText());
259
+ currentFileSizeKilobytes = signal(-1);
260
+ currentFileSizeMegabytes = signal(-1);
261
+ maxSizeMb = computed(() => this.maxFileSize() / 1024);
262
+ /**
263
+ * The photo instance to be used in the image cropper. We need a different
264
+ * reference than `sourcePhoto` to support the cancel after uploading
265
+ * a new photo. While `sourcePhoto` is A and image cropper uploads B,
266
+ * we should not replace `sourcePhoto` A until user presses apply.
267
+ */
268
+ imageCropperPhoto = signal(undefined);
269
+ icons = addIcons({
270
+ elementCancel,
271
+ elementCircleFilled,
272
+ elementStateExclamationMark
273
+ });
274
+ /**
275
+ * Reference to the modal displaying the photo to edit.
276
+ */
277
+ modalRef;
278
+ /**
279
+ * The last cropped event of the image cropper component.
280
+ * Will be set on every mouse drag of the user. It contains
281
+ * the cropped image and the position. When user completes
282
+ * the cropping, the data from the last event is used.
283
+ */
284
+ imageCroppedEvent;
285
+ /**
286
+ * Applied cropper position necessary to restore the cropper position when the use press the Change button.
287
+ */
288
+ cropperPosition;
289
+ sanitizer = inject(DomSanitizer);
290
+ modalService = inject(SiModalService);
291
+ autoBackgroundColorDirective = inject(SiAvatarBackgroundColorDirective);
292
+ ngOnChanges(changes) {
293
+ if (changes.readonly) {
294
+ this.resetErrorMessage();
295
+ this.resetFileInputValue();
296
+ }
297
+ if (changes.sourcePhotoUrl) {
298
+ this.setPhoto(this.sourcePhotoUrl());
299
+ this.cropperPosition = undefined;
300
+ this.croppedPhoto.set(undefined);
301
+ }
302
+ if (changes.sourcePhoto && changes.sourcePhoto.currentValue !== this.imageCropperPhoto()) {
303
+ const sourcePhoto = this.sourcePhoto();
304
+ this.setPhoto(sourcePhoto);
305
+ this.cropperPosition = undefined;
306
+ this.croppedPhoto.set(undefined);
307
+ this.imageCropperPhoto.set(sourcePhoto);
308
+ }
309
+ if (changes.croppedPhoto &&
310
+ changes.croppedPhoto.previousValue?.length > 0 &&
311
+ changes.croppedPhoto.previousValue !== changes.croppedPhoto.currentValue) {
312
+ this.setPhoto(this.croppedPhoto());
313
+ }
314
+ if (changes.placeholderAltText) {
315
+ this.autoBackgroundColorDirective.calculateColorFromInitials(this.placeholderAltText());
316
+ }
317
+ }
318
+ ngOnDestroy() {
319
+ this.modalRef?.detach();
320
+ }
321
+ /**
322
+ * Opens a modal dialog with the cropping component.
323
+ */
324
+ showCroppingDialog() {
325
+ if (this.modalRef) {
326
+ return;
327
+ }
328
+ if (this.disabledCropping()) {
329
+ this.sourcePhoto.set(this.imageCropperPhoto());
330
+ const sourcePhoto = this.sourcePhoto();
331
+ this.updateCroppedPhoto(sourcePhoto ?? '');
332
+ return;
333
+ }
334
+ this.modalRef = this.modalService.show(this.editPhotoTemplate(), {
335
+ ignoreBackdropClick: false,
336
+ keyboard: true,
337
+ class: 'modal-dialog-centered',
338
+ ariaLabelledBy: this.titleId
339
+ }, 'cancel');
340
+ this.resetErrorMessage();
341
+ this.modalRef.hidden.subscribe(() => {
342
+ this.resetErrorMessage();
343
+ this.resetFileInputValue();
344
+ this.modalRef = undefined;
345
+ });
346
+ }
347
+ fileUpload(event) {
348
+ // Initially reset a possible error message
349
+ this.resetErrorMessage();
350
+ const files = event.target.files;
351
+ const file = files && files.length > 0 ? files[0] : undefined;
352
+ if (!file) {
353
+ return;
354
+ }
355
+ const fileType = file.type;
356
+ const allowedFileTypes = this.acceptedUploadFormats()
357
+ .split(',')
358
+ .map(type => type.trim().replace('.', 'image/'));
359
+ const fileTypeWrong = !allowedFileTypes.includes(fileType);
360
+ if (fileTypeWrong) {
361
+ this.uploadErrorMessage.set(this.uploadErrorWrongType());
362
+ return;
363
+ }
364
+ const sizeInKb = file.size / 1024;
365
+ this.currentFileSizeKilobytes.set(Math.round(sizeInKb * 10) / 10);
366
+ this.currentFileSizeMegabytes.set(Math.round((sizeInKb / 1024) * 1000) / 1000);
367
+ const fileSizeTooBig = sizeInKb > this.maxFileSize();
368
+ if (fileSizeTooBig) {
369
+ this.uploadErrorMessage.set(this.uploadErrorTooBig());
370
+ return;
371
+ }
372
+ const reader = new FileReader();
373
+ reader.addEventListener('loadend', () => {
374
+ if (typeof reader.result === 'string') {
375
+ this.cropperPosition = undefined;
376
+ this.imageCropperPhoto.set(reader.result);
377
+ // Bring up the editing modal if not already present
378
+ this.showCroppingDialog();
379
+ }
380
+ });
381
+ reader.readAsDataURL(file);
382
+ }
383
+ updateCroppedPhoto(croppedPhoto, position) {
384
+ this.croppedPhoto.set(croppedPhoto);
385
+ this.setPhoto(this.croppedPhoto());
386
+ this.cropperPosition = position;
387
+ }
388
+ removePhoto() {
389
+ // We emit undefined to notify consumers that the cropped
390
+ // images is removed. This is a kind of special crop event.
391
+ this.croppedPhoto.set(undefined);
392
+ this.imageCropperPhoto.set(undefined);
393
+ this.setPhoto(undefined);
394
+ this.cropperPosition = undefined;
395
+ this.resetFileInputValue();
396
+ this.sourcePhoto.set(undefined);
397
+ }
398
+ /**
399
+ * Invoked when user cropped the photo and pressed apply button.
400
+ * Updates the current photo by the selected cropped photo and
401
+ * closes the modal dialog.
402
+ */
403
+ imageCropperApplied() {
404
+ if (this.imageCroppedEvent) {
405
+ this.sourcePhoto.set(this.imageCropperPhoto());
406
+ this.updateCroppedPhoto(this.imageCroppedEvent.base64.toString(), this.imageCroppedEvent.cropperPosition);
407
+ }
408
+ this.modalRef?.hide();
409
+ }
410
+ imageCropperCanceled() {
411
+ this.imageCropperPhoto.set(this.sourcePhoto());
412
+ this.modalRef?.hide('cancel');
413
+ }
414
+ /**
415
+ * Callback from the image cropper on every mouse drag invoking a cropping.
416
+ *
417
+ * @param event - Event containing the cropped image and the image cropped position.
418
+ *
419
+ */
420
+ cropperImageCropped(event) {
421
+ this.imageCroppedEvent = event;
422
+ }
423
+ /**
424
+ * Lifecycle hook from the image cropper component. Informs
425
+ * us when initialized and ready.
426
+ */
427
+ cropperReady() {
428
+ // When the user opens cropper dialog multiple times we need to
429
+ // apply existing cropper position.
430
+ const imageCropper = this.imageCropper();
431
+ if (this.cropperPosition && imageCropper) {
432
+ imageCropper.cropper = { ...this.cropperPosition };
433
+ imageCropper.crop();
434
+ }
435
+ }
436
+ resetFileInputValue() {
437
+ if (this.fileInput()) {
438
+ // Remove fileInput value to allow for selecting the same
439
+ // file for being uploaded again.
440
+ this.fileInput().nativeElement.value = null;
441
+ }
442
+ }
443
+ resetErrorMessage() {
444
+ this.uploadErrorMessage.set(undefined);
445
+ }
446
+ setPhoto(photo) {
447
+ this.resetErrorMessage();
448
+ this.sanitizedPhotoUrl.set(photo ? this.sanitizer.bypassSecurityTrustResourceUrl(photo) : undefined);
449
+ }
450
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiPhotoUploadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
451
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.6", type: SiPhotoUploadComponent, isStandalone: true, selector: "si-photo-upload", inputs: { readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, disabledCropping: { classPropertyName: "disabledCropping", publicName: "disabledCropping", isSignal: true, isRequired: false, transformFunction: null }, acceptedUploadFormats: { classPropertyName: "acceptedUploadFormats", publicName: "acceptedUploadFormats", isSignal: true, isRequired: false, transformFunction: null }, maxFileSize: { classPropertyName: "maxFileSize", publicName: "maxFileSize", isSignal: true, isRequired: false, transformFunction: null }, uploadErrorWrongType: { classPropertyName: "uploadErrorWrongType", publicName: "uploadErrorWrongType", isSignal: true, isRequired: false, transformFunction: null }, uploadErrorTooBig: { classPropertyName: "uploadErrorTooBig", publicName: "uploadErrorTooBig", isSignal: true, isRequired: false, transformFunction: null }, photoAltText: { classPropertyName: "photoAltText", publicName: "photoAltText", isSignal: true, isRequired: false, transformFunction: null }, placeholderAltText: { classPropertyName: "placeholderAltText", publicName: "placeholderAltText", isSignal: true, isRequired: false, transformFunction: null }, changePhotoText: { classPropertyName: "changePhotoText", publicName: "changePhotoText", isSignal: true, isRequired: false, transformFunction: null }, cropperFrameAriaLabel: { classPropertyName: "cropperFrameAriaLabel", publicName: "cropperFrameAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, uploadPhotoText: { classPropertyName: "uploadPhotoText", publicName: "uploadPhotoText", isSignal: true, isRequired: false, transformFunction: null }, removePhotoText: { classPropertyName: "removePhotoText", publicName: "removePhotoText", isSignal: true, isRequired: false, transformFunction: null }, cancelEditText: { classPropertyName: "cancelEditText", publicName: "cancelEditText", isSignal: true, isRequired: false, transformFunction: null }, applyEditText: { classPropertyName: "applyEditText", publicName: "applyEditText", isSignal: true, isRequired: false, transformFunction: null }, modalHeader: { classPropertyName: "modalHeader", publicName: "modalHeader", isSignal: true, isRequired: false, transformFunction: null }, modalDescription: { classPropertyName: "modalDescription", publicName: "modalDescription", isSignal: true, isRequired: false, transformFunction: null }, cropperImageFormat: { classPropertyName: "cropperImageFormat", publicName: "cropperImageFormat", isSignal: true, isRequired: false, transformFunction: null }, cropperAspectRatio: { classPropertyName: "cropperAspectRatio", publicName: "cropperAspectRatio", isSignal: true, isRequired: false, transformFunction: null }, cropperMaintainAspectRatio: { classPropertyName: "cropperMaintainAspectRatio", publicName: "cropperMaintainAspectRatio", isSignal: true, isRequired: false, transformFunction: null }, cropperContainWithinAspectRatio: { classPropertyName: "cropperContainWithinAspectRatio", publicName: "cropperContainWithinAspectRatio", isSignal: true, isRequired: false, transformFunction: null }, cropperMinWidth: { classPropertyName: "cropperMinWidth", publicName: "cropperMinWidth", isSignal: true, isRequired: false, transformFunction: null }, cropperMinHeight: { classPropertyName: "cropperMinHeight", publicName: "cropperMinHeight", isSignal: true, isRequired: false, transformFunction: null }, cropperMaxWidth: { classPropertyName: "cropperMaxWidth", publicName: "cropperMaxWidth", isSignal: true, isRequired: false, transformFunction: null }, cropperMaxHeight: { classPropertyName: "cropperMaxHeight", publicName: "cropperMaxHeight", isSignal: true, isRequired: false, transformFunction: null }, roundImage: { classPropertyName: "roundImage", publicName: "roundImage", isSignal: true, isRequired: false, transformFunction: null }, sourcePhoto: { classPropertyName: "sourcePhoto", publicName: "sourcePhoto", isSignal: true, isRequired: false, transformFunction: null }, sourcePhotoUrl: { classPropertyName: "sourcePhotoUrl", publicName: "sourcePhotoUrl", isSignal: true, isRequired: false, transformFunction: null }, croppedPhoto: { classPropertyName: "croppedPhoto", publicName: "croppedPhoto", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sourcePhoto: "sourcePhotoChange", croppedPhoto: "croppedPhotoChange" }, viewQueries: [{ propertyName: "editPhotoTemplate", first: true, predicate: ["editPhotoTemplate"], descendants: true, isSignal: true }, { propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }, { propertyName: "imageCropper", first: true, predicate: ["imageCropper"], descendants: true, isSignal: true }], usesOnChanges: true, hostDirectives: [{ directive: i1.SiAvatarBackgroundColorDirective, inputs: ["color", "color", "autoColor", "autoColor"] }], ngImport: i0, template: "<div class=\"photo-upload d-flex flex-column p-6\">\n <!-- File upload -->\n <input\n #fileInput\n type=\"file\"\n class=\"d-none\"\n [accept]=\"acceptedUploadFormats()\"\n (change)=\"fileUpload($event)\"\n />\n\n <!-- Image -->\n @if (sanitizedPhotoUrl()) {\n <img\n class=\"photo-upload-photo\"\n [class.round]=\"roundImage()\"\n [src]=\"sanitizedPhotoUrl()\"\n [alt]=\"photoAltText() | translate\"\n />\n } @else {\n <span\n class=\"photo-upload-placeholder d-flex align-items-center justify-content-center flex-none\"\n [class.round]=\"roundImage()\"\n >\n {{ placeholderAltText() | translate }}\n </span>\n }\n <!-- Buttons -->\n @if (!readonly()) {\n <div class=\"d-flex justify-content-center gap-6 mt-8\">\n <button\n type=\"button\"\n class=\"btn btn-secondary\"\n (click)=\"\n (sourcePhoto() || sourcePhotoUrl()) && !disabledCropping()\n ? showCroppingDialog()\n : fileInput.click()\n \"\n >\n {{ editButtonText() | translate }}\n </button>\n @if (sanitizedPhotoUrl()) {\n <button type=\"button\" class=\"btn btn-danger\" (click)=\"removePhoto()\">\n {{ removePhotoText() | translate }}\n </button>\n }\n </div>\n }\n\n <!-- Error message -->\n @if (uploadErrorMessage() && !modalRef) {\n <div class=\"mt-6\">\n <ng-container [ngTemplateOutlet]=\"errorMessageTemplate\" />\n </div>\n }\n</div>\n\n<!-- Template: modal -->\n<ng-template #editPhotoTemplate>\n <!-- Header -->\n <div class=\"modal-header\">\n <h4 class=\"modal-title\" [id]=\"titleId\">{{ modalHeader() | translate }}</h4>\n <button\n type=\"button\"\n class=\"btn btn-circle btn-sm btn-ghost\"\n [attr.aria-label]=\"cancelEditText() | translate\"\n (click)=\"imageCropperCanceled()\"\n >\n <si-icon-next [icon]=\"icons.elementCancel\" />\n </button>\n </div>\n <!-- Content -->\n <div class=\"modal-body\">\n @if (modalDescription()) {\n <div class=\"mb-4\">\n <span class=\"text-secondary\">{{ modalDescription() | translate }}</span>\n </div>\n }\n <ng-container [ngTemplateOutlet]=\"imageCropperTemplate\" />\n @if (uploadErrorMessage()) {\n <div class=\"d-flex mt-4\">\n <ng-container [ngTemplateOutlet]=\"errorMessageTemplate\" />\n </div>\n }\n </div>\n <!-- Footer -->\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-secondary me-auto\" (click)=\"fileInput.click()\">\n {{ changePhotoText() | translate }}\n </button>\n <div class=\"d-flex gap-6\">\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"imageCropperCanceled()\">\n {{ cancelEditText() | translate }}\n </button>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"imageCropperApplied()\">\n {{ applyEditText() | translate }}\n </button>\n </div>\n </div>\n</ng-template>\n\n<!-- Template: error message -->\n<ng-template #errorMessageTemplate>\n <div class=\"d-flex align-items-center\">\n <span class=\"icon-small icon-stack d-inline-block my-n2 me-2\">\n <si-icon-next class=\"status-danger\" [icon]=\"icons.elementCircleFilled\" />\n <si-icon-next class=\"status-danger-contrast\" [icon]=\"icons.elementStateExclamationMark\" />\n </span>\n <span class=\"text-danger\">{{\n uploadErrorMessage()\n | translate\n : {\n mb: currentFileSizeMegabytes(),\n kb: currentFileSizeKilobytes(),\n maxSizeMb: maxSizeMb()\n }\n }}</span>\n </div>\n</ng-template>\n\n<!-- Template: image cropper -->\n<ng-template #imageCropperTemplate>\n <si-image-cropper-style>\n <image-cropper\n #imageCropper\n output=\"base64\"\n [aspectRatio]=\"cropperAspectRatio()\"\n [containWithinAspectRatio]=\"cropperContainWithinAspectRatio()\"\n [cropperMinWidth]=\"cropperMinWidth()\"\n [cropperMinHeight]=\"cropperMinHeight()\"\n [cropperMaxWidth]=\"cropperMaxWidth()\"\n [cropperMaxHeight]=\"cropperMaxHeight()\"\n [cropperFrameAriaLabel]=\"cropperFrameAriaLabel() | translate\"\n [format]=\"cropperImageFormat()\"\n [imageBase64]=\"imageCropperPhoto()\"\n [imageURL]=\"sourcePhotoUrl()\"\n [maintainAspectRatio]=\"cropperMaintainAspectRatio()\"\n [onlyScaleDown]=\"true\"\n [roundCropper]=\"roundImage()\"\n (cropperReady)=\"cropperReady()\"\n (imageCropped)=\"cropperImageCropped($event)\"\n />\n </si-image-cropper-style>\n</ng-template>\n", styles: [":host{--si-photo-upload-photo-width: 200px;--si-photo-upload-photo-height: 200px}.photo-upload{box-sizing:content-box;max-inline-size:var(--si-photo-upload-photo-width)}.photo-upload-photo,.photo-upload-placeholder{display:block;margin:auto;inline-size:var(--si-photo-upload-photo-width);max-inline-size:100%;block-size:var(--si-photo-upload-photo-height);object-fit:contain}.photo-upload-photo.round,.photo-upload-placeholder.round{border-radius:50%}.photo-upload-placeholder{background-color:var(--background);color:var(--element-ui-5);font-size:3rem;text-align:center;overflow:hidden;word-break:break-all;-webkit-user-select:none;user-select:none}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ImageCropperComponent, selector: "image-cropper", inputs: ["imageChangedEvent", "imageURL", "imageBase64", "imageFile", "imageAltText", "options", "cropperFrameAriaLabel", "output", "format", "autoCrop", "cropper", "transform", "maintainAspectRatio", "aspectRatio", "resetCropOnAspectRatioChange", "resizeToWidth", "resizeToHeight", "cropperMinWidth", "cropperMinHeight", "cropperMaxHeight", "cropperMaxWidth", "cropperStaticWidth", "cropperStaticHeight", "canvasRotation", "initialStepSize", "roundCropper", "onlyScaleDown", "imageQuality", "backgroundColor", "containWithinAspectRatio", "hideResizeSquares", "allowMoveImage", "checkImageType", "alignImage", "disabled", "hidden"], outputs: ["imageCropped", "startCropImage", "imageLoaded", "cropperReady", "loadImageFailed", "transformChange", "cropperChange"] }, { kind: "component", type: SiIconNextComponent, selector: "si-icon-next", inputs: ["icon"] }, { kind: "component", type: SiImageCropperStyleComponent, selector: "si-image-cropper-style" }, { kind: "ngmodule", type: SiTranslateModule }, { kind: "pipe", type: i2.SiTranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
452
+ }
453
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.6", ngImport: i0, type: SiPhotoUploadComponent, decorators: [{
454
+ type: Component,
455
+ args: [{ selector: 'si-photo-upload', imports: [
456
+ NgTemplateOutlet,
457
+ ImageCropperComponent,
458
+ SiIconComponent,
459
+ SiIconNextComponent,
460
+ SiImageCropperStyleComponent,
461
+ SiTranslateModule
462
+ ], changeDetection: ChangeDetectionStrategy.OnPush, hostDirectives: [
463
+ {
464
+ directive: SiAvatarBackgroundColorDirective,
465
+ inputs: ['color', 'autoColor']
466
+ }
467
+ ], template: "<div class=\"photo-upload d-flex flex-column p-6\">\n <!-- File upload -->\n <input\n #fileInput\n type=\"file\"\n class=\"d-none\"\n [accept]=\"acceptedUploadFormats()\"\n (change)=\"fileUpload($event)\"\n />\n\n <!-- Image -->\n @if (sanitizedPhotoUrl()) {\n <img\n class=\"photo-upload-photo\"\n [class.round]=\"roundImage()\"\n [src]=\"sanitizedPhotoUrl()\"\n [alt]=\"photoAltText() | translate\"\n />\n } @else {\n <span\n class=\"photo-upload-placeholder d-flex align-items-center justify-content-center flex-none\"\n [class.round]=\"roundImage()\"\n >\n {{ placeholderAltText() | translate }}\n </span>\n }\n <!-- Buttons -->\n @if (!readonly()) {\n <div class=\"d-flex justify-content-center gap-6 mt-8\">\n <button\n type=\"button\"\n class=\"btn btn-secondary\"\n (click)=\"\n (sourcePhoto() || sourcePhotoUrl()) && !disabledCropping()\n ? showCroppingDialog()\n : fileInput.click()\n \"\n >\n {{ editButtonText() | translate }}\n </button>\n @if (sanitizedPhotoUrl()) {\n <button type=\"button\" class=\"btn btn-danger\" (click)=\"removePhoto()\">\n {{ removePhotoText() | translate }}\n </button>\n }\n </div>\n }\n\n <!-- Error message -->\n @if (uploadErrorMessage() && !modalRef) {\n <div class=\"mt-6\">\n <ng-container [ngTemplateOutlet]=\"errorMessageTemplate\" />\n </div>\n }\n</div>\n\n<!-- Template: modal -->\n<ng-template #editPhotoTemplate>\n <!-- Header -->\n <div class=\"modal-header\">\n <h4 class=\"modal-title\" [id]=\"titleId\">{{ modalHeader() | translate }}</h4>\n <button\n type=\"button\"\n class=\"btn btn-circle btn-sm btn-ghost\"\n [attr.aria-label]=\"cancelEditText() | translate\"\n (click)=\"imageCropperCanceled()\"\n >\n <si-icon-next [icon]=\"icons.elementCancel\" />\n </button>\n </div>\n <!-- Content -->\n <div class=\"modal-body\">\n @if (modalDescription()) {\n <div class=\"mb-4\">\n <span class=\"text-secondary\">{{ modalDescription() | translate }}</span>\n </div>\n }\n <ng-container [ngTemplateOutlet]=\"imageCropperTemplate\" />\n @if (uploadErrorMessage()) {\n <div class=\"d-flex mt-4\">\n <ng-container [ngTemplateOutlet]=\"errorMessageTemplate\" />\n </div>\n }\n </div>\n <!-- Footer -->\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-secondary me-auto\" (click)=\"fileInput.click()\">\n {{ changePhotoText() | translate }}\n </button>\n <div class=\"d-flex gap-6\">\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"imageCropperCanceled()\">\n {{ cancelEditText() | translate }}\n </button>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"imageCropperApplied()\">\n {{ applyEditText() | translate }}\n </button>\n </div>\n </div>\n</ng-template>\n\n<!-- Template: error message -->\n<ng-template #errorMessageTemplate>\n <div class=\"d-flex align-items-center\">\n <span class=\"icon-small icon-stack d-inline-block my-n2 me-2\">\n <si-icon-next class=\"status-danger\" [icon]=\"icons.elementCircleFilled\" />\n <si-icon-next class=\"status-danger-contrast\" [icon]=\"icons.elementStateExclamationMark\" />\n </span>\n <span class=\"text-danger\">{{\n uploadErrorMessage()\n | translate\n : {\n mb: currentFileSizeMegabytes(),\n kb: currentFileSizeKilobytes(),\n maxSizeMb: maxSizeMb()\n }\n }}</span>\n </div>\n</ng-template>\n\n<!-- Template: image cropper -->\n<ng-template #imageCropperTemplate>\n <si-image-cropper-style>\n <image-cropper\n #imageCropper\n output=\"base64\"\n [aspectRatio]=\"cropperAspectRatio()\"\n [containWithinAspectRatio]=\"cropperContainWithinAspectRatio()\"\n [cropperMinWidth]=\"cropperMinWidth()\"\n [cropperMinHeight]=\"cropperMinHeight()\"\n [cropperMaxWidth]=\"cropperMaxWidth()\"\n [cropperMaxHeight]=\"cropperMaxHeight()\"\n [cropperFrameAriaLabel]=\"cropperFrameAriaLabel() | translate\"\n [format]=\"cropperImageFormat()\"\n [imageBase64]=\"imageCropperPhoto()\"\n [imageURL]=\"sourcePhotoUrl()\"\n [maintainAspectRatio]=\"cropperMaintainAspectRatio()\"\n [onlyScaleDown]=\"true\"\n [roundCropper]=\"roundImage()\"\n (cropperReady)=\"cropperReady()\"\n (imageCropped)=\"cropperImageCropped($event)\"\n />\n </si-image-cropper-style>\n</ng-template>\n", styles: [":host{--si-photo-upload-photo-width: 200px;--si-photo-upload-photo-height: 200px}.photo-upload{box-sizing:content-box;max-inline-size:var(--si-photo-upload-photo-width)}.photo-upload-photo,.photo-upload-placeholder{display:block;margin:auto;inline-size:var(--si-photo-upload-photo-width);max-inline-size:100%;block-size:var(--si-photo-upload-photo-height);object-fit:contain}.photo-upload-photo.round,.photo-upload-placeholder.round{border-radius:50%}.photo-upload-placeholder{background-color:var(--background);color:var(--element-ui-5);font-size:3rem;text-align:center;overflow:hidden;word-break:break-all;-webkit-user-select:none;user-select:none}\n"] }]
468
+ }] });
469
+
470
+ /**
471
+ * Copyright Siemens 2016 - 2025.
472
+ * SPDX-License-Identifier: MIT
473
+ */
474
+
475
+ /**
476
+ * Generated bundle index. Do not edit.
477
+ */
478
+
479
+ export { SiImageCropperStyleComponent, SiPhotoUploadComponent };
480
+ //# sourceMappingURL=siemens-element-ng-photo-upload.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"siemens-element-ng-photo-upload.mjs","sources":["../../../../projects/element-ng/photo-upload/si-image-cropper-style.component.ts","../../../../projects/element-ng/photo-upload/si-photo-upload.component.ts","../../../../projects/element-ng/photo-upload/si-photo-upload.component.html","../../../../projects/element-ng/photo-upload/index.ts","../../../../projects/element-ng/photo-upload/siemens-element-ng-photo-upload.ts"],"sourcesContent":["/**\n * Copyright Siemens 2016 - 2025.\n * SPDX-License-Identifier: MIT\n */\nimport { Component } from '@angular/core';\n\n@Component({\n selector: 'si-image-cropper-style',\n styleUrl: './si-image-cropper-style.component.scss',\n template: '<ng-content />'\n})\nexport class SiImageCropperStyleComponent {}\n","/**\n * Copyright Siemens 2016 - 2025.\n * SPDX-License-Identifier: MIT\n */\nimport { NgTemplateOutlet } from '@angular/common';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n inject,\n input,\n model,\n OnChanges,\n OnDestroy,\n signal,\n SimpleChanges,\n TemplateRef,\n viewChild\n} from '@angular/core';\nimport { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';\nimport { SiAvatarBackgroundColorDirective } from '@siemens/element-ng/avatar';\nimport {\n addIcons,\n elementCancel,\n elementCircleFilled,\n elementStateExclamationMark,\n SiIconComponent,\n SiIconNextComponent\n} from '@siemens/element-ng/icon';\nimport { ModalRef, SiModalService } from '@siemens/element-ng/modal';\nimport { SiTranslateModule, TranslatableString } from '@siemens/element-translate-ng/translate';\nimport { CropperPosition, ImageCroppedEvent, ImageCropperComponent } from 'ngx-image-cropper';\n\nimport { SiImageCropperStyleComponent } from './si-image-cropper-style.component';\n\n/**\n * A component used to upload, edit, and delete a user's photo. The user can upload\n * a photo either via file browser or a URL to the photo. You can set the source\n * photo with the `sourcePhoto` Data URL input or the `sourcePhotoUrl` URL input.\n * If you already have a cropped image you can set it with the `croppedPhoto` input.\n * Cropping changes are emitted via the `croppedPhotoChange` output.\n */\n@Component({\n selector: 'si-photo-upload',\n styleUrl: './si-photo-upload.component.scss',\n templateUrl: './si-photo-upload.component.html',\n imports: [\n NgTemplateOutlet,\n ImageCropperComponent,\n SiIconComponent,\n SiIconNextComponent,\n SiImageCropperStyleComponent,\n SiTranslateModule\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n hostDirectives: [\n {\n directive: SiAvatarBackgroundColorDirective,\n inputs: ['color', 'autoColor']\n }\n ]\n})\nexport class SiPhotoUploadComponent implements OnChanges, OnDestroy {\n private static idCounter = 0;\n\n /**\n * Indicate that changing or uploads are disabled.\n *\n * @defaultValue false\n */\n readonly readonly = input(false, { transform: booleanAttribute });\n\n /**\n * Optionally disable image cropping.\n *\n * @defaultValue false\n */\n readonly disabledCropping = input(false, { transform: booleanAttribute });\n\n /**\n * Accepted image formats for the file selection dialog.\n *\n * @defaultValue '.png, .jpg, .jpeg'\n *\n * @see\n *\n * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#attr-accept\n */\n readonly acceptedUploadFormats = input('.png, .jpg, .jpeg');\n\n /**\n * Maximum allowed file size of the uploaded file in kilobytes.\n *\n * @defaultValue 2048\n */\n readonly maxFileSize = input(2048);\n\n /**\n * If the uploaded file is of an unsupported type, this\n * error message will be displayed to the user.\n *\n * @defaultValue\n * ```\n * $localize`:@@SI_PHOTO_UPLOAD.ERROR_FILE_TYPE:The image file is not valid. Please upload a PNG or JP(E)G.`\n * ```\n */\n readonly uploadErrorWrongType = input(\n $localize`:@@SI_PHOTO_UPLOAD.ERROR_FILE_TYPE:The image file is not valid. Please upload a PNG or JP(E)G.`\n );\n\n /**\n * If the uploaded file exceeds the allowed upload size, this\n * error message will be displayed to the user.\n *\n * @defaultValue\n * ```\n * $localize`:@@SI_PHOTO_UPLOAD.ERROR_FILE_SIZE_EXCEEDED:The actual file size {{mb}} MB exceeds the {{maxSizeMb}} MB limit.`\n * ```\n */\n readonly uploadErrorTooBig = input(\n $localize`:@@SI_PHOTO_UPLOAD.ERROR_FILE_SIZE_EXCEEDED:The actual file size {{mb}} MB exceeds the {{maxSizeMb}} MB limit.`\n );\n\n /**\n * Alternative text for the photo.\n *\n * @defaultValue ''\n */\n readonly photoAltText = input<TranslatableString>('');\n\n /**\n * Alternative text for the photo´s placeholder.\n * The value will be used to calculate the background color when `autoColor` is true.\n *\n * @defaultValue ''\n */\n readonly placeholderAltText = input<TranslatableString>('');\n\n /**\n * Text for the button changing the photo.\n *\n * @defaultValue\n * ```\n * $localize`:@@SI_PHOTO_UPLOAD.CHANGE_PHOTO:Change`\n * ```\n */\n readonly changePhotoText = input($localize`:@@SI_PHOTO_UPLOAD.CHANGE_PHOTO:Change`);\n\n /**\n * Cropper frame aria label.\n *\n * @defaultValue\n * ```\n * $localize`:@@SI_PHOTO_UPLOAD.CROPPER_FRAME_LABEL:Crop photo`\n * ```\n */\n readonly cropperFrameAriaLabel = input(\n $localize`:@@SI_PHOTO_UPLOAD.CROPPER_FRAME_LABEL:Crop photo`\n );\n\n /**\n * Text for the button uploading a photo.\n *\n * @defaultValue\n * ```\n * $localize`:@@SI_PHOTO_UPLOAD.UPLOAD_PHOTO:Upload photo`\n * ```\n */\n readonly uploadPhotoText = input($localize`:@@SI_PHOTO_UPLOAD.UPLOAD_PHOTO:Upload photo`);\n\n /**\n * Text for the button removing the photo.\n *\n * @defaultValue\n * ```\n * $localize`:@@SI_PHOTO_UPLOAD.REMOVE:Remove`\n * ```\n */\n readonly removePhotoText = input($localize`:@@SI_PHOTO_UPLOAD.REMOVE:Remove`);\n\n /**\n * Text for the button cancelling the editing process.\n *\n * @defaultValue\n * ```\n * $localize`:@@SI_PHOTO_UPLOAD.CANCEL:Cancel`\n * ```\n */\n readonly cancelEditText = input($localize`:@@SI_PHOTO_UPLOAD.CANCEL:Cancel`);\n\n /**\n * Text for the button applying the edited photo.\n *\n * @defaultValue\n * ```\n * $localize`:@@SI_PHOTO_UPLOAD.APPLY_PHOTO:Apply`\n * ```\n */\n readonly applyEditText = input($localize`:@@SI_PHOTO_UPLOAD.APPLY_PHOTO:Apply`);\n\n /**\n * Text displayed as header of the editing modal.\n *\n * @defaultValue\n * ```\n * $localize`:@@SI_PHOTO_UPLOAD.MODAL_TITLE:Avatar photo`\n * ```\n */\n readonly modalHeader = input($localize`:@@SI_PHOTO_UPLOAD.MODAL_TITLE:Avatar photo`);\n\n /**\n * Text displayed as description of the editing modal.\n */\n readonly modalDescription = input<TranslatableString>();\n\n /**\n * Output format of the edited image.\n *\n * @defaultValue 'jpeg'\n */\n readonly cropperImageFormat = input<'png' | 'jpeg'>('jpeg');\n\n /**\n * The width / height ratio (e.g. 1 / 1 for a square, 4 / 3, 16 / 9 ...).\n *\n * @defaultValue 1\n */\n readonly cropperAspectRatio = input(1);\n\n /**\n * Whether to keep the width and height of the cropped image equal according\n * to the aspectRatio.\n *\n * @defaultValue true\n */\n readonly cropperMaintainAspectRatio = input(true, { transform: booleanAttribute });\n\n /**\n * When set to true, padding will be added around the image to make it fit to\n * the aspect ratio. Be aware that this transformation will cause the loaded\n * image to be a png file with an increased base64 string payload.\n *\n * @defaultValue false\n */\n readonly cropperContainWithinAspectRatio = input(false, { transform: booleanAttribute });\n\n /**\n * The cropper´s width cannot be made smaller than this number of pixels\n * (relative to original image´s size). (0 = disabled).\n *\n * @defaultValue 50\n */\n readonly cropperMinWidth = input(50);\n\n /**\n * The cropper´s height cannot be made smaller than this number of pixels\n * (relative to original image´s size). Will be ignored if\n * `cropperMaintainAspectRatio` is set. (0 = disabled).\n *\n * @defaultValue 50\n */\n readonly cropperMinHeight = input(50);\n\n /**\n * The cropper´s width cannot be made bigger than this number of pixels.\n * Default is 0 (disabled).\n *\n * @defaultValue 0\n */\n readonly cropperMaxWidth = input(0);\n\n /**\n * The cropper´s height cannot be made bigger than this number of pixels.\n * Default is 0 (disabled).\n *\n * @defaultValue 0\n */\n readonly cropperMaxHeight = input(0);\n\n /**\n * Set this to true for a round cropper. Resulting image will still\n * be square, but visually clipped with a border-radius: 50% on the\n * resulting image to show it as round.\n *\n * @defaultValue true\n */\n readonly roundImage = input(true, { transform: booleanAttribute });\n\n /**\n * The input photo to be used for cropping. A string in [Data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs) format\n * with base64 encoding.\n */\n readonly sourcePhoto = model<string>();\n\n /**\n * URL to a photo to be used for cropping.\n */\n readonly sourcePhotoUrl = input<string>();\n\n /**\n * The photo to be displayed and edited (when not readonly).\n */\n readonly croppedPhoto = model<string>();\n\n protected readonly editPhotoTemplate = viewChild.required<TemplateRef<any>>('editPhotoTemplate');\n protected readonly fileInput = viewChild.required<ElementRef<any>>('fileInput');\n protected readonly imageCropper = viewChild<ImageCropperComponent>('imageCropper');\n\n // used to label the dialog\n protected readonly titleId = `__si-photo-upload-${SiPhotoUploadComponent.idCounter++}`;\n\n /**\n * The trusted photo url string which is used to display the photo.\n */\n protected readonly sanitizedPhotoUrl = signal<SafeResourceUrl | undefined>(undefined);\n\n /**\n * The appropriate error message displayed to the user. Might be\n * `uploadErrorWrongType` or `uploadErrorTooBig`.\n */\n protected readonly uploadErrorMessage = signal<string | undefined>(undefined);\n protected readonly editButtonText = computed(() =>\n this.sanitizedPhotoUrl() ? this.changePhotoText() : this.uploadPhotoText()\n );\n protected readonly currentFileSizeKilobytes = signal(-1);\n protected readonly currentFileSizeMegabytes = signal(-1);\n protected readonly maxSizeMb = computed(() => this.maxFileSize() / 1024);\n\n /**\n * The photo instance to be used in the image cropper. We need a different\n * reference than `sourcePhoto` to support the cancel after uploading\n * a new photo. While `sourcePhoto` is A and image cropper uploads B,\n * we should not replace `sourcePhoto` A until user presses apply.\n */\n protected readonly imageCropperPhoto = signal<string | undefined>(undefined);\n\n protected readonly icons = addIcons({\n elementCancel,\n elementCircleFilled,\n elementStateExclamationMark\n });\n /**\n * Reference to the modal displaying the photo to edit.\n */\n protected modalRef?: ModalRef;\n /**\n * The last cropped event of the image cropper component.\n * Will be set on every mouse drag of the user. It contains\n * the cropped image and the position. When user completes\n * the cropping, the data from the last event is used.\n */\n private imageCroppedEvent?: ImageCroppedEvent;\n /**\n * Applied cropper position necessary to restore the cropper position when the use press the Change button.\n */\n private cropperPosition?: CropperPosition;\n\n private readonly sanitizer = inject(DomSanitizer);\n private readonly modalService = inject(SiModalService);\n private readonly autoBackgroundColorDirective = inject(SiAvatarBackgroundColorDirective);\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes.readonly) {\n this.resetErrorMessage();\n this.resetFileInputValue();\n }\n\n if (changes.sourcePhotoUrl) {\n this.setPhoto(this.sourcePhotoUrl());\n this.cropperPosition = undefined;\n this.croppedPhoto.set(undefined);\n }\n if (changes.sourcePhoto && changes.sourcePhoto.currentValue !== this.imageCropperPhoto()) {\n const sourcePhoto = this.sourcePhoto();\n this.setPhoto(sourcePhoto);\n this.cropperPosition = undefined;\n this.croppedPhoto.set(undefined);\n this.imageCropperPhoto.set(sourcePhoto);\n }\n if (\n changes.croppedPhoto &&\n changes.croppedPhoto.previousValue?.length > 0 &&\n changes.croppedPhoto.previousValue !== changes.croppedPhoto.currentValue\n ) {\n this.setPhoto(this.croppedPhoto());\n }\n if (changes.placeholderAltText) {\n this.autoBackgroundColorDirective.calculateColorFromInitials(this.placeholderAltText());\n }\n }\n\n ngOnDestroy(): void {\n this.modalRef?.detach();\n }\n\n /**\n * Opens a modal dialog with the cropping component.\n */\n protected showCroppingDialog(): void {\n if (this.modalRef) {\n return;\n }\n if (this.disabledCropping()) {\n this.sourcePhoto.set(this.imageCropperPhoto());\n const sourcePhoto = this.sourcePhoto();\n this.updateCroppedPhoto(sourcePhoto ?? '');\n return;\n }\n this.modalRef = this.modalService.show(\n this.editPhotoTemplate(),\n {\n ignoreBackdropClick: false,\n keyboard: true,\n class: 'modal-dialog-centered',\n ariaLabelledBy: this.titleId\n },\n 'cancel'\n );\n this.resetErrorMessage();\n this.modalRef.hidden.subscribe(() => {\n this.resetErrorMessage();\n this.resetFileInputValue();\n this.modalRef = undefined;\n });\n }\n\n protected fileUpload(event: Event): void {\n // Initially reset a possible error message\n this.resetErrorMessage();\n const files = (event.target as HTMLInputElement).files;\n const file = files && files.length > 0 ? files[0] : undefined;\n if (!file) {\n return;\n }\n const fileType = file.type;\n const allowedFileTypes = this.acceptedUploadFormats()\n .split(',')\n .map(type => type.trim().replace('.', 'image/'));\n const fileTypeWrong = !allowedFileTypes.includes(fileType);\n if (fileTypeWrong) {\n this.uploadErrorMessage.set(this.uploadErrorWrongType());\n return;\n }\n const sizeInKb = file.size / 1024;\n this.currentFileSizeKilobytes.set(Math.round(sizeInKb * 10) / 10);\n this.currentFileSizeMegabytes.set(Math.round((sizeInKb / 1024) * 1000) / 1000);\n const fileSizeTooBig = sizeInKb > this.maxFileSize();\n if (fileSizeTooBig) {\n this.uploadErrorMessage.set(this.uploadErrorTooBig());\n return;\n }\n const reader = new FileReader();\n reader.addEventListener('loadend', () => {\n if (typeof reader.result === 'string') {\n this.cropperPosition = undefined;\n this.imageCropperPhoto.set(reader.result);\n\n // Bring up the editing modal if not already present\n this.showCroppingDialog();\n }\n });\n reader.readAsDataURL(file);\n }\n\n private updateCroppedPhoto(croppedPhoto: string, position?: CropperPosition): void {\n this.croppedPhoto.set(croppedPhoto);\n this.setPhoto(this.croppedPhoto());\n this.cropperPosition = position;\n }\n\n protected removePhoto(): void {\n // We emit undefined to notify consumers that the cropped\n // images is removed. This is a kind of special crop event.\n this.croppedPhoto.set(undefined);\n this.imageCropperPhoto.set(undefined);\n this.setPhoto(undefined);\n this.cropperPosition = undefined;\n this.resetFileInputValue();\n this.sourcePhoto.set(undefined);\n }\n\n /**\n * Invoked when user cropped the photo and pressed apply button.\n * Updates the current photo by the selected cropped photo and\n * closes the modal dialog.\n */\n protected imageCropperApplied(): void {\n if (this.imageCroppedEvent) {\n this.sourcePhoto.set(this.imageCropperPhoto());\n this.updateCroppedPhoto(\n this.imageCroppedEvent.base64!.toString(),\n this.imageCroppedEvent.cropperPosition\n );\n }\n this.modalRef?.hide();\n }\n\n protected imageCropperCanceled(): void {\n this.imageCropperPhoto.set(this.sourcePhoto());\n this.modalRef?.hide('cancel');\n }\n\n /**\n * Callback from the image cropper on every mouse drag invoking a cropping.\n *\n * @param event - Event containing the cropped image and the image cropped position.\n *\n */\n protected cropperImageCropped(event: ImageCroppedEvent): void {\n this.imageCroppedEvent = event;\n }\n\n /**\n * Lifecycle hook from the image cropper component. Informs\n * us when initialized and ready.\n */\n protected cropperReady(): void {\n // When the user opens cropper dialog multiple times we need to\n // apply existing cropper position.\n const imageCropper = this.imageCropper();\n if (this.cropperPosition && imageCropper) {\n imageCropper.cropper = { ...this.cropperPosition };\n imageCropper.crop();\n }\n }\n\n private resetFileInputValue(): void {\n if (this.fileInput()) {\n // Remove fileInput value to allow for selecting the same\n // file for being uploaded again.\n this.fileInput().nativeElement.value = null;\n }\n }\n\n private resetErrorMessage(): void {\n this.uploadErrorMessage.set(undefined);\n }\n\n private setPhoto(photo?: string): void {\n this.resetErrorMessage();\n this.sanitizedPhotoUrl.set(\n photo ? this.sanitizer.bypassSecurityTrustResourceUrl(photo) : undefined\n );\n }\n}\n","<div class=\"photo-upload d-flex flex-column p-6\">\n <!-- File upload -->\n <input\n #fileInput\n type=\"file\"\n class=\"d-none\"\n [accept]=\"acceptedUploadFormats()\"\n (change)=\"fileUpload($event)\"\n />\n\n <!-- Image -->\n @if (sanitizedPhotoUrl()) {\n <img\n class=\"photo-upload-photo\"\n [class.round]=\"roundImage()\"\n [src]=\"sanitizedPhotoUrl()\"\n [alt]=\"photoAltText() | translate\"\n />\n } @else {\n <span\n class=\"photo-upload-placeholder d-flex align-items-center justify-content-center flex-none\"\n [class.round]=\"roundImage()\"\n >\n {{ placeholderAltText() | translate }}\n </span>\n }\n <!-- Buttons -->\n @if (!readonly()) {\n <div class=\"d-flex justify-content-center gap-6 mt-8\">\n <button\n type=\"button\"\n class=\"btn btn-secondary\"\n (click)=\"\n (sourcePhoto() || sourcePhotoUrl()) && !disabledCropping()\n ? showCroppingDialog()\n : fileInput.click()\n \"\n >\n {{ editButtonText() | translate }}\n </button>\n @if (sanitizedPhotoUrl()) {\n <button type=\"button\" class=\"btn btn-danger\" (click)=\"removePhoto()\">\n {{ removePhotoText() | translate }}\n </button>\n }\n </div>\n }\n\n <!-- Error message -->\n @if (uploadErrorMessage() && !modalRef) {\n <div class=\"mt-6\">\n <ng-container [ngTemplateOutlet]=\"errorMessageTemplate\" />\n </div>\n }\n</div>\n\n<!-- Template: modal -->\n<ng-template #editPhotoTemplate>\n <!-- Header -->\n <div class=\"modal-header\">\n <h4 class=\"modal-title\" [id]=\"titleId\">{{ modalHeader() | translate }}</h4>\n <button\n type=\"button\"\n class=\"btn btn-circle btn-sm btn-ghost\"\n [attr.aria-label]=\"cancelEditText() | translate\"\n (click)=\"imageCropperCanceled()\"\n >\n <si-icon-next [icon]=\"icons.elementCancel\" />\n </button>\n </div>\n <!-- Content -->\n <div class=\"modal-body\">\n @if (modalDescription()) {\n <div class=\"mb-4\">\n <span class=\"text-secondary\">{{ modalDescription() | translate }}</span>\n </div>\n }\n <ng-container [ngTemplateOutlet]=\"imageCropperTemplate\" />\n @if (uploadErrorMessage()) {\n <div class=\"d-flex mt-4\">\n <ng-container [ngTemplateOutlet]=\"errorMessageTemplate\" />\n </div>\n }\n </div>\n <!-- Footer -->\n <div class=\"modal-footer\">\n <button type=\"button\" class=\"btn btn-secondary me-auto\" (click)=\"fileInput.click()\">\n {{ changePhotoText() | translate }}\n </button>\n <div class=\"d-flex gap-6\">\n <button type=\"button\" class=\"btn btn-secondary\" (click)=\"imageCropperCanceled()\">\n {{ cancelEditText() | translate }}\n </button>\n <button type=\"button\" class=\"btn btn-primary\" (click)=\"imageCropperApplied()\">\n {{ applyEditText() | translate }}\n </button>\n </div>\n </div>\n</ng-template>\n\n<!-- Template: error message -->\n<ng-template #errorMessageTemplate>\n <div class=\"d-flex align-items-center\">\n <span class=\"icon-small icon-stack d-inline-block my-n2 me-2\">\n <si-icon-next class=\"status-danger\" [icon]=\"icons.elementCircleFilled\" />\n <si-icon-next class=\"status-danger-contrast\" [icon]=\"icons.elementStateExclamationMark\" />\n </span>\n <span class=\"text-danger\">{{\n uploadErrorMessage()\n | translate\n : {\n mb: currentFileSizeMegabytes(),\n kb: currentFileSizeKilobytes(),\n maxSizeMb: maxSizeMb()\n }\n }}</span>\n </div>\n</ng-template>\n\n<!-- Template: image cropper -->\n<ng-template #imageCropperTemplate>\n <si-image-cropper-style>\n <image-cropper\n #imageCropper\n output=\"base64\"\n [aspectRatio]=\"cropperAspectRatio()\"\n [containWithinAspectRatio]=\"cropperContainWithinAspectRatio()\"\n [cropperMinWidth]=\"cropperMinWidth()\"\n [cropperMinHeight]=\"cropperMinHeight()\"\n [cropperMaxWidth]=\"cropperMaxWidth()\"\n [cropperMaxHeight]=\"cropperMaxHeight()\"\n [cropperFrameAriaLabel]=\"cropperFrameAriaLabel() | translate\"\n [format]=\"cropperImageFormat()\"\n [imageBase64]=\"imageCropperPhoto()\"\n [imageURL]=\"sourcePhotoUrl()\"\n [maintainAspectRatio]=\"cropperMaintainAspectRatio()\"\n [onlyScaleDown]=\"true\"\n [roundCropper]=\"roundImage()\"\n (cropperReady)=\"cropperReady()\"\n (imageCropped)=\"cropperImageCropped($event)\"\n />\n </si-image-cropper-style>\n</ng-template>\n","/**\n * Copyright Siemens 2016 - 2025.\n * SPDX-License-Identifier: MIT\n */\nexport * from './si-image-cropper-style.component';\nexport * from './si-photo-upload.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}