@seniorsistemas/angular-components 19.9.3 → 19.9.4

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 (95) hide show
  1. package/checkbox/lib/checkbox/checkbox.component.d.ts +1 -6
  2. package/checkbox-list/lib/checkbox-list/checkbox-list.component.d.ts +8 -0
  3. package/content-generator/lib/content-generator/content-generator.component.d.ts +2 -2
  4. package/country-phone-picker/lib/country-phone-picker/country-phone-picker.component.d.ts +2 -0
  5. package/drawer/README.md +9 -2
  6. package/drawer/lib/drawer/drawer.component.d.ts +12 -1
  7. package/editor/lib/editor/editor.component.d.ts +1 -1
  8. package/esm2022/button/lib/button/button.component.mjs +3 -3
  9. package/esm2022/checkbox/lib/checkbox/checkbox.component.mjs +3 -9
  10. package/esm2022/checkbox-list/lib/checkbox-list/checkbox-list.component.mjs +17 -5
  11. package/esm2022/content-generator/lib/content-generator/content-generator.component.mjs +9 -8
  12. package/esm2022/country-phone-picker/lib/country-phone-picker/country-phone-picker.component.mjs +18 -3
  13. package/esm2022/drawer/lib/drawer/drawer.component.mjs +33 -11
  14. package/esm2022/drawer/lib/drawer/drawer.module.mjs +2 -2
  15. package/esm2022/dynamic-form/dynamic-form/components/lookup/lookup.component.mjs +3 -3
  16. package/esm2022/dynamic-form/dynamic-form/form-field/fields/bignumber/bignumber-field.component.mjs +3 -3
  17. package/esm2022/dynamic-form/dynamic-form/form-field/fields/boolean/boolean-switch-field/boolean-switch-field.component.mjs +3 -3
  18. package/esm2022/dynamic-form/dynamic-form/form-field/fields/checkbox/checkbox-field.component.mjs +4 -3
  19. package/esm2022/dynamic-form/dynamic-form/form-field/fields/currency/currency-field.component.mjs +3 -3
  20. package/esm2022/dynamic-form/dynamic-form/form-field/fields/number/number-field.component.mjs +3 -3
  21. package/esm2022/dynamic-form/dynamic-form/form-field/fields/password/password-field.component.mjs +3 -3
  22. package/esm2022/dynamic-form/dynamic-form/form-field/fields/text/text-field.component.mjs +3 -3
  23. package/esm2022/editor/lib/editor/editor.component.mjs +8 -8
  24. package/esm2022/file-picker/lib/file-picker/file-picker.component.mjs +4 -4
  25. package/esm2022/global-search/lib/global-search/components/dropdown/global-search-dropdown-item.component.mjs +4 -4
  26. package/esm2022/global-search/lib/global-search/global-search.module.mjs +2 -2
  27. package/esm2022/inline-edit/lib/inline-edit/components/fields/inline-edit-number/inline-edit-number.component.mjs +3 -3
  28. package/esm2022/inline-edit/lib/inline-edit/components/fields/inline-edit-text/inline-edit-text.component.mjs +2 -3
  29. package/esm2022/paginator/lib/models/paginator.models.mjs +1 -1
  30. package/esm2022/paginator/lib/paginator/paginator.component.mjs +19 -13
  31. package/esm2022/profile-picture-picker/lib/profile-picture-picker/profile-picture-picker.component.mjs +19 -8
  32. package/esm2022/profile-picture-picker/lib/profile-picture-picker/profile-picture-picker.module.mjs +3 -4
  33. package/esm2022/select/lib/select/select.component.mjs +3 -3
  34. package/esm2022/side-sheet/lib/side-sheet/side-sheet.component.mjs +6 -5
  35. package/esm2022/slider/lib/slider/slider.component.mjs +3 -3
  36. package/esm2022/speech-recognition/lib/speech-recognition/speech-recognition/speech-recognition.component.mjs +54 -8
  37. package/esm2022/star-rating/star-rating/star-rating.component.mjs +3 -3
  38. package/esm2022/table-header/lib/table-header/table-header-checkbox.component.mjs +14 -21
  39. package/esm2022/text-area/lib/text-area/text-area.component.mjs +3 -3
  40. package/esm2022/tooltip/lib/tooltip/tooltip.directive.mjs +3 -2
  41. package/esm2022/utils/lib/utils/utils.mjs +49 -3
  42. package/fesm2022/seniorsistemas-angular-components-button.mjs +2 -2
  43. package/fesm2022/seniorsistemas-angular-components-button.mjs.map +1 -1
  44. package/fesm2022/seniorsistemas-angular-components-checkbox-list.mjs +16 -4
  45. package/fesm2022/seniorsistemas-angular-components-checkbox-list.mjs.map +1 -1
  46. package/fesm2022/seniorsistemas-angular-components-checkbox.mjs +2 -8
  47. package/fesm2022/seniorsistemas-angular-components-checkbox.mjs.map +1 -1
  48. package/fesm2022/seniorsistemas-angular-components-content-generator.mjs +8 -6
  49. package/fesm2022/seniorsistemas-angular-components-content-generator.mjs.map +1 -1
  50. package/fesm2022/seniorsistemas-angular-components-country-phone-picker.mjs +17 -2
  51. package/fesm2022/seniorsistemas-angular-components-country-phone-picker.mjs.map +1 -1
  52. package/fesm2022/seniorsistemas-angular-components-drawer.mjs +32 -9
  53. package/fesm2022/seniorsistemas-angular-components-drawer.mjs.map +1 -1
  54. package/fesm2022/seniorsistemas-angular-components-dynamic-form.mjs +16 -16
  55. package/fesm2022/seniorsistemas-angular-components-dynamic-form.mjs.map +1 -1
  56. package/fesm2022/seniorsistemas-angular-components-editor.mjs +7 -7
  57. package/fesm2022/seniorsistemas-angular-components-editor.mjs.map +1 -1
  58. package/fesm2022/seniorsistemas-angular-components-file-picker.mjs +3 -3
  59. package/fesm2022/seniorsistemas-angular-components-file-picker.mjs.map +1 -1
  60. package/fesm2022/seniorsistemas-angular-components-global-search.mjs +3 -3
  61. package/fesm2022/seniorsistemas-angular-components-global-search.mjs.map +1 -1
  62. package/fesm2022/seniorsistemas-angular-components-inline-edit.mjs +3 -4
  63. package/fesm2022/seniorsistemas-angular-components-inline-edit.mjs.map +1 -1
  64. package/fesm2022/seniorsistemas-angular-components-paginator.mjs +18 -12
  65. package/fesm2022/seniorsistemas-angular-components-paginator.mjs.map +1 -1
  66. package/fesm2022/seniorsistemas-angular-components-profile-picture-picker.mjs +20 -9
  67. package/fesm2022/seniorsistemas-angular-components-profile-picture-picker.mjs.map +1 -1
  68. package/fesm2022/seniorsistemas-angular-components-select.mjs +2 -2
  69. package/fesm2022/seniorsistemas-angular-components-select.mjs.map +1 -1
  70. package/fesm2022/seniorsistemas-angular-components-side-sheet.mjs +5 -4
  71. package/fesm2022/seniorsistemas-angular-components-side-sheet.mjs.map +1 -1
  72. package/fesm2022/seniorsistemas-angular-components-slider.mjs +2 -2
  73. package/fesm2022/seniorsistemas-angular-components-slider.mjs.map +1 -1
  74. package/fesm2022/seniorsistemas-angular-components-speech-recognition.mjs +53 -7
  75. package/fesm2022/seniorsistemas-angular-components-speech-recognition.mjs.map +1 -1
  76. package/fesm2022/seniorsistemas-angular-components-star-rating.mjs +2 -2
  77. package/fesm2022/seniorsistemas-angular-components-star-rating.mjs.map +1 -1
  78. package/fesm2022/seniorsistemas-angular-components-table-header.mjs +13 -20
  79. package/fesm2022/seniorsistemas-angular-components-table-header.mjs.map +1 -1
  80. package/fesm2022/seniorsistemas-angular-components-text-area.mjs +2 -2
  81. package/fesm2022/seniorsistemas-angular-components-text-area.mjs.map +1 -1
  82. package/fesm2022/seniorsistemas-angular-components-tooltip.mjs +2 -1
  83. package/fesm2022/seniorsistemas-angular-components-tooltip.mjs.map +1 -1
  84. package/fesm2022/seniorsistemas-angular-components-utils.mjs +49 -3
  85. package/fesm2022/seniorsistemas-angular-components-utils.mjs.map +1 -1
  86. package/global-search/lib/global-search/global-search.module.d.ts +1 -1
  87. package/package.json +7 -9
  88. package/paginator/lib/models/paginator.models.d.ts +1 -0
  89. package/paginator/lib/paginator/paginator.component.d.ts +3 -1
  90. package/profile-picture-picker/lib/profile-picture-picker/profile-picture-picker.component.d.ts +3 -1
  91. package/side-sheet/README.md +4 -4
  92. package/side-sheet/lib/side-sheet/side-sheet.component.d.ts +1 -0
  93. package/speech-recognition/lib/speech-recognition/speech-recognition/speech-recognition.component.d.ts +2 -1
  94. package/table-header/lib/table-header/table-header-checkbox.component.d.ts +1 -4
  95. package/utils/lib/utils/utils.d.ts +21 -0
@@ -1 +1 @@
1
- {"version":3,"file":"seniorsistemas-angular-components-paginator.mjs","sources":["../../projects/angular-components/paginator/src/lib/paginator/paginator.component.ts","../../projects/angular-components/paginator/src/lib/paginator/paginator.component.html","../../projects/angular-components/paginator/src/seniorsistemas-angular-components-paginator.ts"],"sourcesContent":["import { Component, computed, effect, input, model, OnDestroy, output, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { InteractiveContentDirective } from '@seniorsistemas/angular-components/interactive-content';\nimport { SelectComponent } from '@seniorsistemas/angular-components/select';\nimport { TranslateModule } from '@ngx-translate/core';\n\nimport { PageChange, PaginatorInternalButton } from '../models/paginator.models';\n/**\n * @description Componente de paginação standalone que exibe botões de páginas,\n * seletor de itens por página e navegação para primeira/última página.\n * Emite `pageChange` a cada mudança de página ou tamanho de página.\n *\n * @example\n * ```html\n * <s-paginator\n * [totalRecords]=\"total\"\n * [(rows)]=\"tamanhoPagina\"\n * (pageChange)=\"onPaginaMudou($event)\" />\n * ```\n *\n * @category Structure\n */\n@Component({\n selector: 's-paginator',\n standalone: true,\n imports: [InteractiveContentDirective, SelectComponent, FormsModule, TranslateModule],\n templateUrl: './paginator.component.html',\n})\nexport class PaginatorComponent implements OnDestroy {\n /** @description Número total de registros. Campo obrigatório. */\n totalRecords = input.required<number>();\n /** @description Número de itens por página. Suporta two-way binding. @default 10 */\n rows = model(10);\n /** @description Opções do seletor de itens por página. @default [10, 20, 50, 100, 200] */\n rowsPerPageOptions = input<number[]>([10, 20, 50, 100, 200]);\n /** @description Emitido sempre que a página ou o número de itens por página muda. */\n pageChange = output<PageChange>();\n\n private readonly currentPageEffect = effect(() => {\n const page = this.currentPage() - 1;\n this.pageChange.emit({\n page,\n pageCount: this.totalPages(),\n rows: this.rows(),\n first: this.rows() * page,\n });\n });\n private readonly MAX_PAGE_BUTTONS = 5;\n private readonly hasPreviousPage = computed(() => {\n const previousPage = this.currentPage() - 1;\n return previousPage >= 1;\n });\n\n private readonly hasNextPage = computed(() => {\n const nextPage = this.currentPage() + 1;\n return nextPage <= this.totalPages();\n });\n\n protected readonly currentPage = signal(1);\n\n protected buttons = computed(() => {\n const navigationPageButtons: PaginatorInternalButton[] = [];\n const maxPageButtons = this.MAX_PAGE_BUTTONS;\n const currentPage = this.currentPage();\n const middle = Math.floor(maxPageButtons / 2);\n const _startPage = currentPage - middle;\n let startPage = _startPage < 1 ? 1 : _startPage;\n const _endPage = startPage + maxPageButtons - 1;\n const endPageIsMoreThanTotalPages = _endPage > this.totalPages();\n\n if (endPageIsMoreThanTotalPages) {\n const diff = _endPage - this.totalPages();\n const canModifyStartPage = startPage - diff >= 1;\n if (canModifyStartPage) {\n startPage = startPage - diff;\n }\n }\n const endPage = endPageIsMoreThanTotalPages ? this.totalPages() : _endPage;\n\n for (let i = startPage; i <= endPage; i++) {\n navigationPageButtons.push({\n clicked: (page) => this.goToPage(page.pageIndex as number),\n pageIndex: i,\n });\n }\n\n return [\n this.FIRST_PAGE_BUTTON,\n this.PREVIOUS_PAGE_BUTTON,\n ...navigationPageButtons,\n this.NEXT_PAGE_BUTTON,\n this.LAST_PAGE_BUTTON,\n ];\n });\n\n private readonly FIRST_PAGE_BUTTON: PaginatorInternalButton = {\n clicked: this.goFirstPage.bind(this),\n icon: 'fas fa-step-backward',\n validate: computed(() => {\n return !this.hasPreviousPage();\n }),\n };\n\n private readonly PREVIOUS_PAGE_BUTTON: PaginatorInternalButton = {\n clicked: this.goPreviousPage.bind(this),\n icon: 'fas fa-caret-left',\n validate: computed(() => {\n return !this.hasPreviousPage();\n }),\n };\n\n private readonly LAST_PAGE_BUTTON: PaginatorInternalButton = {\n clicked: this.goLastPage.bind(this),\n icon: 'fas fa-step-forward',\n validate: computed(() => {\n return !this.hasNextPage();\n }),\n };\n\n private readonly NEXT_PAGE_BUTTON: PaginatorInternalButton = {\n clicked: this.goNextPage.bind(this),\n icon: 'fas fa-caret-right',\n validate: computed(() => {\n return !this.hasNextPage();\n }),\n };\n\n private totalPages = computed(() => {\n const totalRecords = this.totalRecords();\n const _pages = totalRecords / this.rows();\n const pages = Math.ceil(_pages);\n const isExactPages = _pages === pages;\n return isExactPages ? pages : pages + 1;\n });\n\n public ngOnDestroy(): void {\n this.currentPageEffect.destroy();\n }\n\n protected rowsPerPageChange(): void {\n if (this.currentPage() !== 1) {\n this.goToPage(1);\n }\n }\n\n protected activatedButton(button: PaginatorInternalButton): void {\n button.clicked(button);\n }\n\n private goFirstPage(): void {\n this.goToPage(1);\n }\n\n private goNextPage(): void {\n if (!this.hasNextPage()) {\n return;\n }\n this.currentPage.update((value) => value + 1);\n }\n\n private goPreviousPage(): void {\n if (!this.hasPreviousPage()) {\n return;\n }\n this.currentPage.update((value) => value - 1);\n }\n\n private goLastPage(): void {\n this.goToPage(this.totalPages());\n }\n\n private goToPage(pageIndex: number): void {\n this.currentPage.set(pageIndex);\n }\n}\n\n","<div class=\"flex justify-between\">\n <section class=\"flex items-center gap-2\">\n <div\n class=\"inline-block h-8 divide-x divide-grayscale-30 overflow-hidden rounded-medium border border-grayscale-30 bg-grayscale-0\"\n >\n @for (btn of buttons(); track $index) {\n @let active = btn.pageIndex === currentPage();\n <button\n [class.bg-criticality-blue]=\"active\"\n [class.text-grayscale-0]=\"active\"\n [class.text-criticality-blue]=\"!active\"\n (sInteractiveContent)=\"activatedButton(btn)\"\n [disabled]=\"btn.disabled || (btn.validate && btn.validate()) || false\"\n class=\"group h-8 w-8 hover:bg-grayscale-20 hover:text-grayscale-100 disabled:hover:bg-[transparent] disabled:hover:text-criticality-blue\"\n >\n <div class=\"group-disabled:opacity-50\">\n @let page = btn.pageIndex;\n @let icon = btn.icon;\n @if (page !== undefined) {\n {{ page }}\n }\n @if (icon) {\n <i [class]=\"icon\"></i>\n }\n </div>\n </button>\n }\n </div>\n <s-select\n [options]=\"rowsPerPageOptions()\"\n [(ngModel)]=\"rows\"\n (ngModelChange)=\"rowsPerPageChange()\"\n ></s-select>\n </section>\n <section class=\"flex items-center gap-2\">\n @let text =\n totalRecords() === 0\n ? 'platform.angular_components.total_record'\n : 'platform.angular_components.total_records';\n <p class=\"text-[14px] text-[#212533]\">\n {{ text | translate: { count: totalRecords() } }}\n </p>\n <ng-content></ng-content>\n </section>\n</div>\n\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"seniorsistemas-angular-components-paginator.mjs","sources":["../../projects/angular-components/paginator/src/lib/paginator/paginator.component.ts","../../projects/angular-components/paginator/src/lib/paginator/paginator.component.html","../../projects/angular-components/paginator/src/seniorsistemas-angular-components-paginator.ts"],"sourcesContent":["import { Component, computed, effect, input, model, OnDestroy, output, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { InteractiveContentDirective } from '@seniorsistemas/angular-components/interactive-content';\nimport { SelectComponent } from '@seniorsistemas/angular-components/select';\nimport { TranslateModule } from '@ngx-translate/core';\n\nimport { PageChange, PaginatorInternalButton } from '../models/paginator.models';\n/**\n * @description Componente de paginação standalone que exibe botões de páginas,\n * seletor de itens por página e navegação para primeira/última página.\n * Emite `pageChange` a cada mudança de página ou tamanho de página.\n *\n * @example\n * ```html\n * <s-paginator\n * [totalRecords]=\"total\"\n * [(rows)]=\"tamanhoPagina\"\n * (pageChange)=\"onPaginaMudou($event)\" />\n * ```\n *\n * @category Structure\n */\n@Component({\n selector: 's-paginator',\n standalone: true,\n imports: [InteractiveContentDirective, SelectComponent, FormsModule, TranslateModule],\n templateUrl: './paginator.component.html',\n})\nexport class PaginatorComponent implements OnDestroy {\n /** @description Número total de registros. Campo obrigatório. */\n totalRecords = input.required<number>();\n /** @description Número de itens por página. Suporta two-way binding. @default 10 */\n rows = model(10);\n /** @description Opções do seletor de itens por página. @default [10, 20, 50, 100, 200] */\n rowsPerPageOptions = input<number[]>([10, 20, 50, 100, 200]);\n /** @description Emitido sempre que a página ou o número de itens por página muda. */\n pageChange = output<PageChange>();\n\n private readonly currentPageEffect = effect(() => {\n const totalPages = this.totalPages();\n const page = this.currentPage() - 1;\n this.pageChange.emit({\n page,\n pageCount: totalPages,\n rows: this.rows(),\n first: this.rows() * page,\n });\n });\n private readonly MAX_PAGE_BUTTONS = 5;\n private readonly hasPreviousPage = computed(() => {\n const previousPage = this.currentPage() - 1;\n return previousPage >= 1;\n });\n\n private readonly hasNextPage = computed(() => {\n const nextPage = this.currentPage() + 1;\n return nextPage <= this.totalPages();\n });\n\n private readonly requestedPage = signal(1);\n /** @description Página atual, sempre reajustada para o intervalo válido de `[1, totalPages]`. */\n protected readonly currentPage = computed(() => {\n const maxPage = Math.max(this.totalPages(), 1);\n return Math.min(Math.max(this.requestedPage(), 1), maxPage);\n });\n\n protected buttons = computed(() => {\n const navigationPageButtons: PaginatorInternalButton[] = [];\n const maxPageButtons = this.MAX_PAGE_BUTTONS;\n const currentPage = this.currentPage();\n const middle = Math.floor(maxPageButtons / 2);\n const _startPage = currentPage - middle;\n let startPage = _startPage < 1 ? 1 : _startPage;\n const _endPage = startPage + maxPageButtons - 1;\n const endPageIsMoreThanTotalPages = _endPage > this.totalPages();\n\n if (endPageIsMoreThanTotalPages) {\n const diff = _endPage - this.totalPages();\n const canModifyStartPage = startPage - diff >= 1;\n if (canModifyStartPage) {\n startPage = startPage - diff;\n }\n }\n const endPage = endPageIsMoreThanTotalPages ? this.totalPages() : _endPage;\n\n for (let i = startPage; i <= endPage; i++) {\n navigationPageButtons.push({\n clicked: (page) => this.goToPage(page.pageIndex as number),\n pageIndex: i,\n });\n }\n\n return [\n this.FIRST_PAGE_BUTTON,\n this.PREVIOUS_PAGE_BUTTON,\n ...navigationPageButtons,\n this.NEXT_PAGE_BUTTON,\n this.LAST_PAGE_BUTTON,\n ];\n });\n\n private readonly FIRST_PAGE_BUTTON: PaginatorInternalButton = {\n clicked: this.goFirstPage.bind(this),\n icon: 'fas fa-step-backward',\n ariaLabelKey: 'platform.angular_components.aria_first_page',\n validate: computed(() => {\n return !this.hasPreviousPage();\n }),\n };\n\n private readonly PREVIOUS_PAGE_BUTTON: PaginatorInternalButton = {\n clicked: this.goPreviousPage.bind(this),\n icon: 'fas fa-caret-left',\n ariaLabelKey: 'platform.angular_components.aria_previous_page',\n validate: computed(() => {\n return !this.hasPreviousPage();\n }),\n };\n\n private readonly LAST_PAGE_BUTTON: PaginatorInternalButton = {\n clicked: this.goLastPage.bind(this),\n icon: 'fas fa-step-forward',\n ariaLabelKey: 'platform.angular_components.aria_last_page',\n validate: computed(() => {\n return !this.hasNextPage();\n }),\n };\n\n private readonly NEXT_PAGE_BUTTON: PaginatorInternalButton = {\n clicked: this.goNextPage.bind(this),\n icon: 'fas fa-caret-right',\n ariaLabelKey: 'platform.angular_components.aria_next_page',\n validate: computed(() => {\n return !this.hasNextPage();\n }),\n };\n\n private totalPages = computed(() => {\n return Math.ceil(this.totalRecords() / this.rows());\n });\n\n public ngOnDestroy(): void {\n this.currentPageEffect.destroy();\n }\n\n protected rowsPerPageChange(): void {\n if (this.currentPage() !== 1) {\n this.goToPage(1);\n }\n }\n\n protected activatedButton(button: PaginatorInternalButton): void {\n button.clicked(button);\n }\n\n private goFirstPage(): void {\n this.goToPage(1);\n }\n\n private goNextPage(): void {\n if (!this.hasNextPage()) {\n return;\n }\n this.goToPage(this.currentPage() + 1);\n }\n\n private goPreviousPage(): void {\n if (!this.hasPreviousPage()) {\n return;\n }\n this.goToPage(this.currentPage() - 1);\n }\n\n private goLastPage(): void {\n this.goToPage(this.totalPages());\n }\n\n private goToPage(pageIndex: number): void {\n this.requestedPage.set(pageIndex);\n }\n}\n\n","<div class=\"flex justify-between\">\n <section class=\"flex items-center gap-2\">\n <div\n class=\"inline-block h-8 divide-x divide-grayscale-30 overflow-hidden rounded-medium border border-grayscale-30 bg-grayscale-0\"\n >\n @for (btn of buttons(); track $index) {\n @let active = btn.pageIndex === currentPage();\n @let ariaLabelKey =\n btn.ariaLabelKey ??\n (active\n ? 'platform.angular_components.aria_current_page'\n : 'platform.angular_components.aria_page_number');\n <button\n [class.bg-criticality-blue]=\"active\"\n [class.text-grayscale-0]=\"active\"\n [class.text-criticality-blue]=\"!active\"\n (sInteractiveContent)=\"activatedButton(btn)\"\n [disabled]=\"btn.disabled || (btn.validate && btn.validate()) || false\"\n [attr.aria-label]=\"ariaLabelKey | translate: { page: btn.pageIndex }\"\n [attr.aria-current]=\"active ? 'page' : null\"\n class=\"group h-8 w-8 hover:bg-grayscale-20 hover:text-grayscale-100 disabled:hover:bg-[transparent] disabled:hover:text-criticality-blue\"\n >\n <div class=\"group-disabled:opacity-50\">\n @let page = btn.pageIndex;\n @let icon = btn.icon;\n @if (page !== undefined) {\n {{ page }}\n }\n @if (icon) {\n <i [class]=\"icon\" aria-hidden=\"true\"></i>\n }\n </div>\n </button>\n }\n </div>\n <s-select\n [options]=\"rowsPerPageOptions()\"\n [ariaLabel]=\"'platform.angular_components.aria_page_selection' | translate\"\n [(ngModel)]=\"rows\"\n (ngModelChange)=\"rowsPerPageChange()\"\n ></s-select>\n </section>\n <section class=\"flex items-center gap-2\">\n @let text =\n totalRecords() === 0\n ? 'platform.angular_components.total_record'\n : 'platform.angular_components.total_records';\n <p class=\"text-[14px] text-[#212533]\">\n {{ text | translate: { count: totalRecords() } }}\n </p>\n <ng-content></ng-content>\n </section>\n</div>\n\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -2,10 +2,9 @@ import * as i0 from '@angular/core';
2
2
  import { inject, EventEmitter, forwardRef, ElementRef, Component, Input, ViewChild, Output, HostListener, NgModule } from '@angular/core';
3
3
  import { NG_VALUE_ACCESSOR } from '@angular/forms';
4
4
  import { TranslateService, TranslatePipe } from '@ngx-translate/core';
5
- import { ConfirmationService } from 'primeng/api';
6
5
  import { isNullOrUndefined } from '@seniorsistemas/angular-components/utils';
7
6
  import { ImageCropperService } from '@seniorsistemas/angular-components/image-cropper';
8
- import { ConfirmDialog } from 'primeng/confirmdialog';
7
+ import { ConfirmDialogService } from '@seniorsistemas/angular-components/confirm-dialog';
9
8
  import { ThumbnailComponent } from '@seniorsistemas/angular-components/thumbnail';
10
9
  import { ButtonComponent } from '@seniorsistemas/angular-components/button';
11
10
 
@@ -30,7 +29,7 @@ import { ButtonComponent } from '@seniorsistemas/angular-components/button';
30
29
  */
31
30
  class ProfilePicturePickerComponent {
32
31
  imageCropperService = inject(ImageCropperService);
33
- confirmationService = inject(ConfirmationService);
32
+ confirmDialogService = inject(ConfirmDialogService);
34
33
  translateService = inject(TranslateService);
35
34
  /**
36
35
  * @description Título simples exibido quando nenhuma imagem está selecionada.
@@ -123,6 +122,7 @@ class ProfilePicturePickerComponent {
123
122
  get imageBase64() {
124
123
  return typeof this.image === 'string' ? this.image : (this.image?.base64 ?? '');
125
124
  }
125
+ disabled = false;
126
126
  _onChange;
127
127
  _onTouched;
128
128
  writeValue(value) {
@@ -134,6 +134,9 @@ class ProfilePicturePickerComponent {
134
134
  registerOnTouched(onTouched) {
135
135
  this._onTouched = onTouched;
136
136
  }
137
+ setDisabledState(isDisabled) {
138
+ this.disabled = isDisabled;
139
+ }
137
140
  ngOnInit() {
138
141
  this._normalizeSuportedExtensions();
139
142
  }
@@ -148,6 +151,9 @@ class ProfilePicturePickerComponent {
148
151
  onDrop(event) {
149
152
  event.preventDefault();
150
153
  event.stopPropagation();
154
+ if (this.disabled) {
155
+ return;
156
+ }
151
157
  this._onTouched?.();
152
158
  const files = [];
153
159
  const dataTransferFiles = event.dataTransfer?.files;
@@ -176,13 +182,19 @@ class ProfilePicturePickerComponent {
176
182
  }
177
183
  }
178
184
  selectPhoto() {
185
+ if (this.disabled) {
186
+ return;
187
+ }
179
188
  const fileInputElement = this.fileInput?.nativeElement;
180
189
  fileInputElement.value = '';
181
190
  fileInputElement.click();
182
191
  this._onTouched?.();
183
192
  }
184
193
  removePhoto() {
185
- this.confirmationService.confirm({
194
+ if (this.disabled) {
195
+ return;
196
+ }
197
+ this.confirmDialogService.confirm({
186
198
  message: this.confirmationTexts?.removalMessage ??
187
199
  this.translateService.instant('platform.angular_components.confirmation_remove_image'),
188
200
  acceptLabel: this.confirmationTexts?.removalAcceptLabel ??
@@ -191,7 +203,6 @@ class ProfilePicturePickerComponent {
191
203
  this.translateService.instant('platform.angular_components.cancel'),
192
204
  header: this.confirmationTexts?.removalHeader ??
193
205
  this.translateService.instant('platform.angular_components.remove_image'),
194
- rejectButtonStyleClass: 'ui-button-secondary',
195
206
  accept: () => {
196
207
  const fileInputElement = this.fileInput?.nativeElement;
197
208
  fileInputElement.value = '';
@@ -285,7 +296,7 @@ class ProfilePicturePickerComponent {
285
296
  useExisting: forwardRef(() => ProfilePicturePickerComponent),
286
297
  multi: true,
287
298
  },
288
- ], viewQueries: [{ propertyName: "uploadPicture", first: true, predicate: ["uploadPicture"], descendants: true }, { propertyName: "info", first: true, predicate: ["info"], descendants: true }, { propertyName: "thumbnail", first: true, predicate: ["thumbnail"], descendants: true, read: ElementRef }, { propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true, read: ElementRef }], ngImport: i0, template: "<p-confirmDialog></p-confirmDialog>\n\n<input\n #fileInput\n [accept]=\"accept\"\n class=\"file-input\"\n type=\"file\"\n (change)=\"photoSelected($event)\"\n/>\n<div\n #uploadPicture\n class=\"upload-picture\"\n>\n <s-thumbnail\n #thumbnail\n iconClass=\"far fa-user\"\n [imageSource]=\"imageBase64\"\n [hasAction]=\"!image\"\n (click)=\"selectPhoto()\"\n >\n </s-thumbnail>\n <div\n #info\n class=\"info\"\n >\n @if (image) {\n <div class=\"buttons\">\n <s-button\n [label]=\"changeButtonLabel || 'platform.angular_components.change_photo' | translate\"\n priority=\"primary\"\n (clicked)=\"selectPhoto()\"\n >\n </s-button>\n <s-button\n [label]=\"removeButtonLabel || 'platform.angular_components.remove' | translate\"\n priority=\"secondary\"\n (clicked)=\"removePhoto()\"\n >\n </s-button>\n </div>\n } @else {\n <p class=\"title\">\n {{ simpleTitle || 'platform.angular_components.drag_your_photo_or' | translate }}\n <span\n class=\"action-title\"\n (click)=\"selectPhoto()\"\n >\n {{ actionTitle || 'platform.angular_components.select_a_file' | translate }}\n </span>\n </p>\n }\n <p class=\"subtitle\">{{ subtitle }}</p>\n </div>\n</div>\n", styles: [".file-input{display:none}.upload-picture{display:flex;flex-wrap:wrap}.upload-picture .info{display:flex;flex-direction:column;padding:12px 20px;align-items:flex-start}.upload-picture .info .title{font-family:Open Sans,sans-serif;font-weight:700;font-size:.875rem;line-height:150%;color:#333}.upload-picture .info .title .action-title{cursor:pointer;color:#428bca}.upload-picture .info .buttons{display:flex;gap:8px}.upload-picture .info .buttons s-button{margin:0}.upload-picture .info .subtitle{padding:6px 0;font-family:Open Sans,sans-serif;font-weight:400;font-size:.75rem;line-height:150%;color:#697882;text-align:center}.upload-picture--small .info{align-items:center}.upload-picture--small .info .title,.upload-picture--small .info .subtitle{text-align:center}.upload-picture--small .info .buttons{justify-content:center;flex-wrap:wrap}\n"], dependencies: [{ kind: "component", type: ConfirmDialog, selector: "p-confirmDialog, p-confirmdialog, p-confirm-dialog", inputs: ["header", "icon", "message", "style", "styleClass", "maskStyleClass", "acceptIcon", "acceptLabel", "closeAriaLabel", "acceptAriaLabel", "acceptVisible", "rejectIcon", "rejectLabel", "rejectAriaLabel", "rejectVisible", "acceptButtonStyleClass", "rejectButtonStyleClass", "closeOnEscape", "dismissableMask", "blockScroll", "rtl", "closable", "appendTo", "key", "autoZIndex", "baseZIndex", "transitionOptions", "focusTrap", "defaultFocus", "breakpoints", "visible", "position"], outputs: ["onHide"] }, { kind: "component", type: ThumbnailComponent, selector: "s-thumbnail", inputs: ["id", "size", "imageSource", "imageFallback", "imageAlt", "iconClass", "hasAction", "actionIconClass", "isTile", "isBrand"] }, { kind: "component", type: ButtonComponent, selector: "s-button", inputs: ["id", "label", "tooltip", "tooltipPosition", "iconClass", "rightIconClass", "caret", "styleClass", "baseZIndex", "disabled", "auxiliary", "type", "priority", "menuOptions", "size", "slide", "animation", "badge", "iconColor", "menuAriaLabel", "ariaLabel"], outputs: ["clicked"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
299
+ ], viewQueries: [{ propertyName: "uploadPicture", first: true, predicate: ["uploadPicture"], descendants: true }, { propertyName: "info", first: true, predicate: ["info"], descendants: true }, { propertyName: "thumbnail", first: true, predicate: ["thumbnail"], descendants: true, read: ElementRef }, { propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true, read: ElementRef }], ngImport: i0, template: "<input\n #fileInput\n [accept]=\"accept\"\n [disabled]=\"disabled\"\n class=\"file-input\"\n type=\"file\"\n (change)=\"photoSelected($event)\"\n/>\n<div\n #uploadPicture\n class=\"upload-picture\"\n [class.upload-picture--disabled]=\"disabled\"\n [attr.aria-disabled]=\"disabled\"\n>\n <s-thumbnail\n #thumbnail\n iconClass=\"far fa-user\"\n [imageSource]=\"imageBase64\"\n [hasAction]=\"!image\"\n (click)=\"selectPhoto()\"\n >\n </s-thumbnail>\n <div\n #info\n class=\"info\"\n >\n @if (image) {\n <div class=\"buttons\">\n <s-button\n [label]=\"changeButtonLabel || 'platform.angular_components.change_photo' | translate\"\n priority=\"primary\"\n [disabled]=\"disabled\"\n (clicked)=\"selectPhoto()\"\n >\n </s-button>\n <s-button\n [label]=\"removeButtonLabel || 'platform.angular_components.remove' | translate\"\n priority=\"secondary\"\n [disabled]=\"disabled\"\n (clicked)=\"removePhoto()\"\n >\n </s-button>\n </div>\n } @else {\n <p class=\"title\">\n {{ simpleTitle || 'platform.angular_components.drag_your_photo_or' | translate }}\n <span\n class=\"action-title\"\n (click)=\"selectPhoto()\"\n >\n {{ actionTitle || 'platform.angular_components.select_a_file' | translate }}\n </span>\n </p>\n }\n <p class=\"subtitle\">{{ subtitle }}</p>\n </div>\n</div>\n", styles: [".file-input{display:none}.upload-picture{display:flex;flex-wrap:wrap}.upload-picture--disabled{opacity:.5;pointer-events:none}.upload-picture .info{display:flex;flex-direction:column;padding:12px 20px;align-items:flex-start}.upload-picture .info .title{font-family:Open Sans,sans-serif;font-weight:700;font-size:.875rem;line-height:150%;color:#333}.upload-picture .info .title .action-title{cursor:pointer;color:#428bca}.upload-picture .info .buttons{display:flex;gap:8px}.upload-picture .info .buttons s-button{margin:0}.upload-picture .info .subtitle{padding:6px 0;font-family:Open Sans,sans-serif;font-weight:400;font-size:.75rem;line-height:150%;color:#697882;text-align:center}.upload-picture--small .info{align-items:center}.upload-picture--small .info .title,.upload-picture--small .info .subtitle{text-align:center}.upload-picture--small .info .buttons{justify-content:center;flex-wrap:wrap}\n"], dependencies: [{ kind: "component", type: ThumbnailComponent, selector: "s-thumbnail", inputs: ["id", "size", "imageSource", "imageFallback", "imageAlt", "iconClass", "hasAction", "actionIconClass", "isTile", "isBrand"] }, { kind: "component", type: ButtonComponent, selector: "s-button", inputs: ["id", "label", "tooltip", "tooltipPosition", "iconClass", "rightIconClass", "caret", "styleClass", "baseZIndex", "disabled", "auxiliary", "type", "priority", "menuOptions", "size", "slide", "animation", "badge", "iconColor", "menuAriaLabel", "ariaLabel"], outputs: ["clicked"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }] });
289
300
  }
290
301
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ProfilePicturePickerComponent, decorators: [{
291
302
  type: Component,
@@ -295,7 +306,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
295
306
  useExisting: forwardRef(() => ProfilePicturePickerComponent),
296
307
  multi: true,
297
308
  },
298
- ], standalone: true, imports: [ConfirmDialog, ThumbnailComponent, ButtonComponent, TranslatePipe], template: "<p-confirmDialog></p-confirmDialog>\n\n<input\n #fileInput\n [accept]=\"accept\"\n class=\"file-input\"\n type=\"file\"\n (change)=\"photoSelected($event)\"\n/>\n<div\n #uploadPicture\n class=\"upload-picture\"\n>\n <s-thumbnail\n #thumbnail\n iconClass=\"far fa-user\"\n [imageSource]=\"imageBase64\"\n [hasAction]=\"!image\"\n (click)=\"selectPhoto()\"\n >\n </s-thumbnail>\n <div\n #info\n class=\"info\"\n >\n @if (image) {\n <div class=\"buttons\">\n <s-button\n [label]=\"changeButtonLabel || 'platform.angular_components.change_photo' | translate\"\n priority=\"primary\"\n (clicked)=\"selectPhoto()\"\n >\n </s-button>\n <s-button\n [label]=\"removeButtonLabel || 'platform.angular_components.remove' | translate\"\n priority=\"secondary\"\n (clicked)=\"removePhoto()\"\n >\n </s-button>\n </div>\n } @else {\n <p class=\"title\">\n {{ simpleTitle || 'platform.angular_components.drag_your_photo_or' | translate }}\n <span\n class=\"action-title\"\n (click)=\"selectPhoto()\"\n >\n {{ actionTitle || 'platform.angular_components.select_a_file' | translate }}\n </span>\n </p>\n }\n <p class=\"subtitle\">{{ subtitle }}</p>\n </div>\n</div>\n", styles: [".file-input{display:none}.upload-picture{display:flex;flex-wrap:wrap}.upload-picture .info{display:flex;flex-direction:column;padding:12px 20px;align-items:flex-start}.upload-picture .info .title{font-family:Open Sans,sans-serif;font-weight:700;font-size:.875rem;line-height:150%;color:#333}.upload-picture .info .title .action-title{cursor:pointer;color:#428bca}.upload-picture .info .buttons{display:flex;gap:8px}.upload-picture .info .buttons s-button{margin:0}.upload-picture .info .subtitle{padding:6px 0;font-family:Open Sans,sans-serif;font-weight:400;font-size:.75rem;line-height:150%;color:#697882;text-align:center}.upload-picture--small .info{align-items:center}.upload-picture--small .info .title,.upload-picture--small .info .subtitle{text-align:center}.upload-picture--small .info .buttons{justify-content:center;flex-wrap:wrap}\n"] }]
309
+ ], standalone: true, imports: [ThumbnailComponent, ButtonComponent, TranslatePipe], template: "<input\n #fileInput\n [accept]=\"accept\"\n [disabled]=\"disabled\"\n class=\"file-input\"\n type=\"file\"\n (change)=\"photoSelected($event)\"\n/>\n<div\n #uploadPicture\n class=\"upload-picture\"\n [class.upload-picture--disabled]=\"disabled\"\n [attr.aria-disabled]=\"disabled\"\n>\n <s-thumbnail\n #thumbnail\n iconClass=\"far fa-user\"\n [imageSource]=\"imageBase64\"\n [hasAction]=\"!image\"\n (click)=\"selectPhoto()\"\n >\n </s-thumbnail>\n <div\n #info\n class=\"info\"\n >\n @if (image) {\n <div class=\"buttons\">\n <s-button\n [label]=\"changeButtonLabel || 'platform.angular_components.change_photo' | translate\"\n priority=\"primary\"\n [disabled]=\"disabled\"\n (clicked)=\"selectPhoto()\"\n >\n </s-button>\n <s-button\n [label]=\"removeButtonLabel || 'platform.angular_components.remove' | translate\"\n priority=\"secondary\"\n [disabled]=\"disabled\"\n (clicked)=\"removePhoto()\"\n >\n </s-button>\n </div>\n } @else {\n <p class=\"title\">\n {{ simpleTitle || 'platform.angular_components.drag_your_photo_or' | translate }}\n <span\n class=\"action-title\"\n (click)=\"selectPhoto()\"\n >\n {{ actionTitle || 'platform.angular_components.select_a_file' | translate }}\n </span>\n </p>\n }\n <p class=\"subtitle\">{{ subtitle }}</p>\n </div>\n</div>\n", styles: [".file-input{display:none}.upload-picture{display:flex;flex-wrap:wrap}.upload-picture--disabled{opacity:.5;pointer-events:none}.upload-picture .info{display:flex;flex-direction:column;padding:12px 20px;align-items:flex-start}.upload-picture .info .title{font-family:Open Sans,sans-serif;font-weight:700;font-size:.875rem;line-height:150%;color:#333}.upload-picture .info .title .action-title{cursor:pointer;color:#428bca}.upload-picture .info .buttons{display:flex;gap:8px}.upload-picture .info .buttons s-button{margin:0}.upload-picture .info .subtitle{padding:6px 0;font-family:Open Sans,sans-serif;font-weight:400;font-size:.75rem;line-height:150%;color:#697882;text-align:center}.upload-picture--small .info{align-items:center}.upload-picture--small .info .title,.upload-picture--small .info .subtitle{text-align:center}.upload-picture--small .info .buttons{justify-content:center;flex-wrap:wrap}\n"] }]
299
310
  }], propDecorators: { simpleTitle: [{
300
311
  type: Input
301
312
  }], actionTitle: [{
@@ -358,14 +369,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
358
369
  class ProfilePicturePickerModule {
359
370
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ProfilePicturePickerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
360
371
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: ProfilePicturePickerModule, imports: [ProfilePicturePickerComponent], exports: [ProfilePicturePickerComponent] });
361
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ProfilePicturePickerModule, providers: [ImageCropperService, ConfirmationService], imports: [ProfilePicturePickerComponent] });
372
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ProfilePicturePickerModule, providers: [ImageCropperService], imports: [ProfilePicturePickerComponent] });
362
373
  }
363
374
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ProfilePicturePickerModule, decorators: [{
364
375
  type: NgModule,
365
376
  args: [{
366
377
  imports: [ProfilePicturePickerComponent],
367
378
  exports: [ProfilePicturePickerComponent],
368
- providers: [ImageCropperService, ConfirmationService],
379
+ providers: [ImageCropperService],
369
380
  }]
370
381
  }] });
371
382
 
@@ -1 +1 @@
1
- {"version":3,"file":"seniorsistemas-angular-components-profile-picture-picker.mjs","sources":["../../projects/angular-components/profile-picture-picker/src/lib/profile-picture-picker/profile-picture-picker.component.ts","../../projects/angular-components/profile-picture-picker/src/lib/profile-picture-picker/profile-picture-picker.component.html","../../projects/angular-components/profile-picture-picker/src/lib/profile-picture-picker/profile-picture-picker.module.ts","../../projects/angular-components/profile-picture-picker/src/lib/profile-picture-picker/validators/validators.ts","../../projects/angular-components/profile-picture-picker/src/seniorsistemas-angular-components-profile-picture-picker.ts"],"sourcesContent":["import {\r\n Component,\r\n ElementRef,\r\n EventEmitter,\r\n forwardRef,\r\n HostListener,\r\n Input,\r\n OnInit,\r\n Output,\r\n ViewChild,\r\n inject,\r\n} from '@angular/core';\r\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\r\n\r\nimport { TranslateService, TranslatePipe } from '@ngx-translate/core';\r\nimport { ConfirmationService } from 'primeng/api';\r\nimport { ConfirmationTexts, CropperLabelsConfig, FileValidationErrors, ProfilePicturePickerData } from './models/index';\r\nimport { isNullOrUndefined } from '@seniorsistemas/angular-components/utils';\r\nimport { ImageCropperService } from '@seniorsistemas/angular-components/image-cropper';\r\nimport { ConfirmDialog } from 'primeng/confirmdialog';\r\nimport { ThumbnailComponent } from '@seniorsistemas/angular-components/thumbnail';\r\nimport { ButtonComponent } from '@seniorsistemas/angular-components/button';\r\n\r\n/**\r\n * @description Componente para seleção, edição e remoção de foto de perfil do usuário.\r\n * Permite ao usuário fazer upload de uma imagem, recortá-la com o {@link ImageCropperService}\r\n * e confirmar ou remover a foto atual. Implementa {@link ControlValueAccessor} para uso\r\n * em formulários reativos e template-driven do Angular.\r\n *\r\n * @example\r\n * ```html\r\n * <s-profile-picture-picker\r\n * formControlName=\"avatar\"\r\n * subtitle=\"Formatos aceitos: JPG e PNG\"\r\n * [maxFileSize]=\"2097152\"\r\n * accept=\"image/jpeg,image/png\"\r\n * (imageChange)=\"onImageChange($event)\"\r\n * (removedImage)=\"onImageRemoved()\" />\r\n * ```\r\n *\r\n * @category Inputs\r\n */\r\n@Component({\r\n selector: 's-profile-picture-picker',\r\n templateUrl: 'profile-picture-picker.component.html',\r\n styleUrls: ['profile-picture-picker.component.scss'],\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: forwardRef(() => ProfilePicturePickerComponent),\r\n multi: true,\r\n },\r\n ],\r\n standalone: true,\r\n imports: [ConfirmDialog, ThumbnailComponent, ButtonComponent, TranslatePipe],\r\n})\r\nexport class ProfilePicturePickerComponent implements OnInit, ControlValueAccessor {\r\n private readonly imageCropperService = inject(ImageCropperService);\r\n private readonly confirmationService = inject(ConfirmationService);\r\n private readonly translateService = inject(TranslateService);\r\n\r\n /**\r\n * @description Título simples exibido quando nenhuma imagem está selecionada.\r\n */\r\n @Input()\r\n public simpleTitle!: string;\r\n\r\n /**\r\n * @description Título de ação exibido como label principal do botão de upload.\r\n */\r\n @Input()\r\n public actionTitle!: string;\r\n\r\n /**\r\n * @description Legenda exibida abaixo do título, descrevendo formatos suportados\r\n * ou outras orientações para o usuário. Campo obrigatório.\r\n */\r\n @Input({ required: true })\r\n public subtitle!: string;\r\n\r\n /**\r\n * @description Proporção (aspect ratio) do recorte da imagem.\r\n * Por exemplo, `1` para quadrado, `16/9` para widescreen.\r\n *\r\n * @default 1\r\n */\r\n @Input()\r\n public aspectRatio = 1;\r\n\r\n /**\r\n * @description Configurações de rótulos exibidos no componente de recorte de imagem (cropper).\r\n * Permite sobrescrever os textos padrão dos botões e instruções do cropper.\r\n */\r\n @Input()\r\n public cropperLabelsConfig?: CropperLabelsConfig;\r\n\r\n /**\r\n * @description Texto do botão de remoção da foto atual.\r\n * Se não informado, utiliza o label padrão de remoção.\r\n */\r\n @Input()\r\n public removeButtonLabel?: string;\r\n\r\n /**\r\n * @description Texto do botão de troca da foto atual.\r\n * Se não informado, utiliza o label padrão de alteração.\r\n */\r\n @Input()\r\n public changeButtonLabel?: string;\r\n\r\n /**\r\n * @description Textos personalizados exibidos no diálogo de confirmação\r\n * ao remover ou substituir a foto. Permite sobrescrever título, mensagem e botões.\r\n */\r\n @Input()\r\n public confirmationTexts?: ConfirmationTexts;\r\n\r\n /**\r\n * @description Tamanho máximo permitido para o arquivo de imagem, em bytes.\r\n * Quando o arquivo excede esse limite, o output `invalidFile` é emitido.\r\n */\r\n @Input()\r\n public maxFileSize?: number;\r\n\r\n /**\r\n * @description Tipos MIME aceitos pelo input de arquivo.\r\n * Exemplo: `\"image/jpeg,image/png\"`.\r\n */\r\n @Input()\r\n public accept?: string;\r\n\r\n /**\r\n * @description Lista de extensões de arquivo aceitas para validação.\r\n * Exemplo: `['.jpg', '.jpeg', '.png']`.\r\n *\r\n * @default []\r\n */\r\n @Input()\r\n public supportedExtensions: string[] = [];\r\n\r\n /**\r\n * @description Imagem atual do componente. Pode ser uma string base64, um objeto\r\n * {@link ProfilePicturePickerData} com metadados, ou `null` para sem imagem.\r\n *\r\n * @default null\r\n */\r\n @Input()\r\n public image: string | ProfilePicturePickerData | null = null;\r\n\r\n @ViewChild('uploadPicture')\r\n public uploadPicture: ElementRef | null = null;\r\n\r\n @ViewChild('info')\r\n public info: ElementRef | null = null;\r\n\r\n @ViewChild('thumbnail', { read: ElementRef })\r\n public thumbnail: ElementRef | null = null;\r\n\r\n @ViewChild('fileInput', { read: ElementRef })\r\n public fileInput: ElementRef | null = null;\r\n\r\n /**\r\n * @deprecated Use `imageChange` em vez deste output.\r\n * @description Emitido ao selecionar ou recortar uma nova imagem. Emite a string base64 da imagem.\r\n */\r\n @Output()\r\n public changedImage: EventEmitter<string> = new EventEmitter();\r\n\r\n /**\r\n * @description Emitido ao selecionar, recortar ou alterar a imagem.\r\n * Emite a string base64 ou um objeto {@link ProfilePicturePickerData} com os dados da imagem.\r\n */\r\n @Output()\r\n public imageChange = new EventEmitter<string | ProfilePicturePickerData>();\r\n\r\n /**\r\n * @description Emitido quando o usuário confirma a remoção da foto atual.\r\n */\r\n @Output()\r\n public removedImage = new EventEmitter();\r\n\r\n /**\r\n * @description Emitido quando o arquivo selecionado não passa na validação.\r\n * Emite um objeto {@link FileValidationErrors} descrevendo os erros encontrados\r\n * (ex.: tamanho excedido, extensão inválida).\r\n */\r\n @Output()\r\n public invalidFile: EventEmitter<FileValidationErrors> = new EventEmitter();\r\n\r\n public get imageBase64(): string {\r\n return typeof this.image === 'string' ? this.image : (this.image?.base64 ?? '');\r\n }\r\n\r\n private _onChange?: (value: string | ProfilePicturePickerData) => void;\r\n private _onTouched?: () => void;\r\n\r\n public writeValue(value: string | ProfilePicturePickerData): void {\r\n this.image = value;\r\n }\r\n\r\n public registerOnChange(onChange: (value: string | ProfilePicturePickerData) => void): void {\r\n this._onChange = onChange;\r\n }\r\n\r\n public registerOnTouched(onTouched: () => void): void {\r\n this._onTouched = onTouched;\r\n }\r\n\r\n public ngOnInit(): void {\r\n this._normalizeSuportedExtensions();\r\n }\r\n\r\n @HostListener('dragover', ['$event'])\r\n public onDragOver(event: DragEvent) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n }\r\n\r\n @HostListener('dragleave', ['$event'])\r\n public onDragLeave(event: DragEvent): void {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n }\r\n\r\n @HostListener('drop', ['$event'])\r\n public onDrop(event: DragEvent): void {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n this._onTouched?.();\r\n\r\n const files: File[] = [];\r\n const dataTransferFiles = event.dataTransfer?.files;\r\n\r\n if (!isNullOrUndefined(dataTransferFiles)) {\r\n for (let i = 0; i < dataTransferFiles?.length; i++) {\r\n const item = dataTransferFiles.item(i);\r\n if (!isNullOrUndefined(item)) {\r\n files.push(item);\r\n }\r\n }\r\n }\r\n\r\n this._showImageCropper(files);\r\n }\r\n\r\n // Verificando o redimensionamento para ajustar o design para ficar responsivo.\r\n @HostListener('window:resize')\r\n public onResize(): void {\r\n if (this.uploadPicture && this.info && this.thumbnail) {\r\n const uploadPictureWidth = this._getWidthElement(this.uploadPicture);\r\n const infoWidth = this._getWidthElement(this.info);\r\n const thumbnailWidth = this._getWidthElement(this.thumbnail);\r\n\r\n if (thumbnailWidth + infoWidth > uploadPictureWidth) {\r\n this.uploadPicture.nativeElement.classList.add('upload-picture--small');\r\n } else {\r\n this.uploadPicture.nativeElement.classList.remove('upload-picture--small');\r\n }\r\n }\r\n }\r\n\r\n public selectPhoto(): void {\r\n const fileInputElement = this.fileInput?.nativeElement;\r\n fileInputElement.value = '';\r\n fileInputElement.click();\r\n\r\n this._onTouched?.();\r\n }\r\n\r\n public removePhoto(): void {\r\n this.confirmationService.confirm({\r\n message:\r\n this.confirmationTexts?.removalMessage ??\r\n this.translateService.instant('platform.angular_components.confirmation_remove_image'),\r\n acceptLabel:\r\n this.confirmationTexts?.removalAcceptLabel ??\r\n this.translateService.instant('platform.angular_components.remove'),\r\n rejectLabel:\r\n this.confirmationTexts?.removalRejectLabel ??\r\n this.translateService.instant('platform.angular_components.cancel'),\r\n header:\r\n this.confirmationTexts?.removalHeader ??\r\n this.translateService.instant('platform.angular_components.remove_image'),\r\n rejectButtonStyleClass: 'ui-button-secondary',\r\n accept: () => {\r\n const fileInputElement = this.fileInput?.nativeElement;\r\n fileInputElement.value = '';\r\n this.image = null;\r\n this.removedImage.emit();\r\n },\r\n });\r\n }\r\n\r\n public photoSelected(event: any): void {\r\n this._showImageCropper(event.srcElement.files);\r\n }\r\n\r\n private _showImageCropper(files: File[]): void {\r\n if (!this._validateData(files)) {\r\n return;\r\n }\r\n\r\n const file = files[0];\r\n\r\n const fileReader = new FileReader();\r\n fileReader.readAsDataURL(file);\r\n fileReader.onloadend = (fileEvent: any) => {\r\n this.imageCropperService.show({\r\n imageSource: fileEvent.target.result,\r\n croppedImage: (image) => {\r\n this.changedImage.emit(image);\r\n\r\n const data: ProfilePicturePickerData = { source: file, base64: image };\r\n\r\n // Se o tipo do image for string eu preciso atualizar e mandar para o imageChange uma string.\r\n // Se for ProfilePicturePickerData eu preciso mandar o data completo.\r\n if (typeof this.image === 'string') {\r\n this.image = image;\r\n this.imageChange.emit(image);\r\n } else {\r\n this.image = data;\r\n this.imageChange.emit(data);\r\n }\r\n\r\n this._onChange?.(this.image);\r\n },\r\n changeImage: () => this.selectPhoto(),\r\n allowSelectAnother: false,\r\n aspectRatio: this.aspectRatio,\r\n ...this.cropperLabelsConfig,\r\n });\r\n };\r\n }\r\n\r\n private _normalizeSuportedExtensions(): void {\r\n this.supportedExtensions = this.supportedExtensions?.map((extension) =>\r\n extension.replace('.', '').toLocaleLowerCase(),\r\n );\r\n }\r\n\r\n private _validateData(files: File[]): boolean {\r\n if (!files.length) {\r\n return false;\r\n }\r\n\r\n if (files.length > 1) {\r\n this.invalidFile.emit({ file: null, validation: 'maxFileLimit' });\r\n return false;\r\n }\r\n\r\n const file = files[0];\r\n\r\n if (!file.type.includes('image')) {\r\n this.invalidFile.emit({ file, validation: 'typeInvalid' });\r\n return false;\r\n }\r\n\r\n if (!this._validateFileExtension(file)) {\r\n this.invalidFile.emit({ file, validation: 'unsupportedExtension' });\r\n return false;\r\n }\r\n\r\n if (!this._validateFileSize(file)) {\r\n this.invalidFile.emit({ file, validation: 'maxFileSize' });\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private _validateFileExtension(file: File): boolean {\r\n if (this.supportedExtensions?.length) {\r\n const extension = file.name.split('.').pop()?.toLowerCase() ?? '';\r\n return this.supportedExtensions.includes(extension);\r\n }\r\n return true;\r\n }\r\n\r\n private _validateFileSize(file: File): boolean {\r\n if (this.maxFileSize) {\r\n return file.size <= this.maxFileSize;\r\n }\r\n return true;\r\n }\r\n\r\n private _getWidthElement(element: ElementRef): number {\r\n const { left, right } = element.nativeElement.getBoundingClientRect();\r\n return right - left;\r\n }\r\n}\r\n","<p-confirmDialog></p-confirmDialog>\n\n<input\n #fileInput\n [accept]=\"accept\"\n class=\"file-input\"\n type=\"file\"\n (change)=\"photoSelected($event)\"\n/>\n<div\n #uploadPicture\n class=\"upload-picture\"\n>\n <s-thumbnail\n #thumbnail\n iconClass=\"far fa-user\"\n [imageSource]=\"imageBase64\"\n [hasAction]=\"!image\"\n (click)=\"selectPhoto()\"\n >\n </s-thumbnail>\n <div\n #info\n class=\"info\"\n >\n @if (image) {\n <div class=\"buttons\">\n <s-button\n [label]=\"changeButtonLabel || 'platform.angular_components.change_photo' | translate\"\n priority=\"primary\"\n (clicked)=\"selectPhoto()\"\n >\n </s-button>\n <s-button\n [label]=\"removeButtonLabel || 'platform.angular_components.remove' | translate\"\n priority=\"secondary\"\n (clicked)=\"removePhoto()\"\n >\n </s-button>\n </div>\n } @else {\n <p class=\"title\">\n {{ simpleTitle || 'platform.angular_components.drag_your_photo_or' | translate }}\n <span\n class=\"action-title\"\n (click)=\"selectPhoto()\"\n >\n {{ actionTitle || 'platform.angular_components.select_a_file' | translate }}\n </span>\n </p>\n }\n <p class=\"subtitle\">{{ subtitle }}</p>\n </div>\n</div>\n","import { NgModule } from '@angular/core';\r\n\r\nimport { ConfirmationService } from 'primeng/api';\r\n\r\nimport { ProfilePicturePickerComponent } from './profile-picture-picker.component';\r\nimport { ImageCropperService } from '@seniorsistemas/angular-components/image-cropper';\r\n\r\n@NgModule({\r\n imports: [ProfilePicturePickerComponent],\r\n exports: [ProfilePicturePickerComponent],\r\n providers: [ImageCropperService, ConfirmationService],\r\n})\r\nexport class ProfilePicturePickerModule {}\r\n","import { AbstractControl, ValidatorFn } from \"@angular/forms\";\n\nconst maxFileSize = (size: number): ValidatorFn => {\n return (control: AbstractControl) => {\n if (control.value?.source?.size > size) {\n return {\n maxFileSize: true,\n };\n }\n\n return null;\n };\n};\n\nconst fileExtension = (extensions: string[]) => {\n return (control: AbstractControl) => {\n if (extensions.length) {\n const extension = control.value?.source?.name?.split(\".\").pop().toLowerCase();\n if (extension?.includes(extension)) {\n return {\n fileExtension: true,\n };\n }\n }\n return null;\n };\n};\n\nexport const Validators = {\n maxFileSize,\n fileExtension,\n};\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"seniorsistemas-angular-components-profile-picture-picker.mjs","sources":["../../projects/angular-components/profile-picture-picker/src/lib/profile-picture-picker/profile-picture-picker.component.ts","../../projects/angular-components/profile-picture-picker/src/lib/profile-picture-picker/profile-picture-picker.component.html","../../projects/angular-components/profile-picture-picker/src/lib/profile-picture-picker/profile-picture-picker.module.ts","../../projects/angular-components/profile-picture-picker/src/lib/profile-picture-picker/validators/validators.ts","../../projects/angular-components/profile-picture-picker/src/seniorsistemas-angular-components-profile-picture-picker.ts"],"sourcesContent":["import {\r\n Component,\r\n ElementRef,\r\n EventEmitter,\r\n forwardRef,\r\n HostListener,\r\n Input,\r\n OnInit,\r\n Output,\r\n ViewChild,\r\n inject,\r\n} from '@angular/core';\r\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\r\n\r\nimport { TranslateService, TranslatePipe } from '@ngx-translate/core';\r\nimport { ConfirmationTexts, CropperLabelsConfig, FileValidationErrors, ProfilePicturePickerData } from './models/index';\r\nimport { isNullOrUndefined } from '@seniorsistemas/angular-components/utils';\r\nimport { ImageCropperService } from '@seniorsistemas/angular-components/image-cropper';\r\nimport { ConfirmDialogService } from '@seniorsistemas/angular-components/confirm-dialog';\r\nimport { ThumbnailComponent } from '@seniorsistemas/angular-components/thumbnail';\r\nimport { ButtonComponent } from '@seniorsistemas/angular-components/button';\r\n\r\n/**\r\n * @description Componente para seleção, edição e remoção de foto de perfil do usuário.\r\n * Permite ao usuário fazer upload de uma imagem, recortá-la com o {@link ImageCropperService}\r\n * e confirmar ou remover a foto atual. Implementa {@link ControlValueAccessor} para uso\r\n * em formulários reativos e template-driven do Angular.\r\n *\r\n * @example\r\n * ```html\r\n * <s-profile-picture-picker\r\n * formControlName=\"avatar\"\r\n * subtitle=\"Formatos aceitos: JPG e PNG\"\r\n * [maxFileSize]=\"2097152\"\r\n * accept=\"image/jpeg,image/png\"\r\n * (imageChange)=\"onImageChange($event)\"\r\n * (removedImage)=\"onImageRemoved()\" />\r\n * ```\r\n *\r\n * @category Inputs\r\n */\r\n@Component({\r\n selector: 's-profile-picture-picker',\r\n templateUrl: 'profile-picture-picker.component.html',\r\n styleUrls: ['profile-picture-picker.component.scss'],\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: forwardRef(() => ProfilePicturePickerComponent),\r\n multi: true,\r\n },\r\n ],\r\n standalone: true,\r\n imports: [ThumbnailComponent, ButtonComponent, TranslatePipe],\r\n})\r\nexport class ProfilePicturePickerComponent implements OnInit, ControlValueAccessor {\r\n private readonly imageCropperService = inject(ImageCropperService);\r\n private readonly confirmDialogService = inject(ConfirmDialogService);\r\n private readonly translateService = inject(TranslateService);\r\n\r\n /**\r\n * @description Título simples exibido quando nenhuma imagem está selecionada.\r\n */\r\n @Input()\r\n public simpleTitle!: string;\r\n\r\n /**\r\n * @description Título de ação exibido como label principal do botão de upload.\r\n */\r\n @Input()\r\n public actionTitle!: string;\r\n\r\n /**\r\n * @description Legenda exibida abaixo do título, descrevendo formatos suportados\r\n * ou outras orientações para o usuário. Campo obrigatório.\r\n */\r\n @Input({ required: true })\r\n public subtitle!: string;\r\n\r\n /**\r\n * @description Proporção (aspect ratio) do recorte da imagem.\r\n * Por exemplo, `1` para quadrado, `16/9` para widescreen.\r\n *\r\n * @default 1\r\n */\r\n @Input()\r\n public aspectRatio = 1;\r\n\r\n /**\r\n * @description Configurações de rótulos exibidos no componente de recorte de imagem (cropper).\r\n * Permite sobrescrever os textos padrão dos botões e instruções do cropper.\r\n */\r\n @Input()\r\n public cropperLabelsConfig?: CropperLabelsConfig;\r\n\r\n /**\r\n * @description Texto do botão de remoção da foto atual.\r\n * Se não informado, utiliza o label padrão de remoção.\r\n */\r\n @Input()\r\n public removeButtonLabel?: string;\r\n\r\n /**\r\n * @description Texto do botão de troca da foto atual.\r\n * Se não informado, utiliza o label padrão de alteração.\r\n */\r\n @Input()\r\n public changeButtonLabel?: string;\r\n\r\n /**\r\n * @description Textos personalizados exibidos no diálogo de confirmação\r\n * ao remover ou substituir a foto. Permite sobrescrever título, mensagem e botões.\r\n */\r\n @Input()\r\n public confirmationTexts?: ConfirmationTexts;\r\n\r\n /**\r\n * @description Tamanho máximo permitido para o arquivo de imagem, em bytes.\r\n * Quando o arquivo excede esse limite, o output `invalidFile` é emitido.\r\n */\r\n @Input()\r\n public maxFileSize?: number;\r\n\r\n /**\r\n * @description Tipos MIME aceitos pelo input de arquivo.\r\n * Exemplo: `\"image/jpeg,image/png\"`.\r\n */\r\n @Input()\r\n public accept?: string;\r\n\r\n /**\r\n * @description Lista de extensões de arquivo aceitas para validação.\r\n * Exemplo: `['.jpg', '.jpeg', '.png']`.\r\n *\r\n * @default []\r\n */\r\n @Input()\r\n public supportedExtensions: string[] = [];\r\n\r\n /**\r\n * @description Imagem atual do componente. Pode ser uma string base64, um objeto\r\n * {@link ProfilePicturePickerData} com metadados, ou `null` para sem imagem.\r\n *\r\n * @default null\r\n */\r\n @Input()\r\n public image: string | ProfilePicturePickerData | null = null;\r\n\r\n @ViewChild('uploadPicture')\r\n public uploadPicture: ElementRef | null = null;\r\n\r\n @ViewChild('info')\r\n public info: ElementRef | null = null;\r\n\r\n @ViewChild('thumbnail', { read: ElementRef })\r\n public thumbnail: ElementRef | null = null;\r\n\r\n @ViewChild('fileInput', { read: ElementRef })\r\n public fileInput: ElementRef | null = null;\r\n\r\n /**\r\n * @deprecated Use `imageChange` em vez deste output.\r\n * @description Emitido ao selecionar ou recortar uma nova imagem. Emite a string base64 da imagem.\r\n */\r\n @Output()\r\n public changedImage: EventEmitter<string> = new EventEmitter();\r\n\r\n /**\r\n * @description Emitido ao selecionar, recortar ou alterar a imagem.\r\n * Emite a string base64 ou um objeto {@link ProfilePicturePickerData} com os dados da imagem.\r\n */\r\n @Output()\r\n public imageChange = new EventEmitter<string | ProfilePicturePickerData>();\r\n\r\n /**\r\n * @description Emitido quando o usuário confirma a remoção da foto atual.\r\n */\r\n @Output()\r\n public removedImage = new EventEmitter();\r\n\r\n /**\r\n * @description Emitido quando o arquivo selecionado não passa na validação.\r\n * Emite um objeto {@link FileValidationErrors} descrevendo os erros encontrados\r\n * (ex.: tamanho excedido, extensão inválida).\r\n */\r\n @Output()\r\n public invalidFile: EventEmitter<FileValidationErrors> = new EventEmitter();\r\n\r\n public get imageBase64(): string {\r\n return typeof this.image === 'string' ? this.image : (this.image?.base64 ?? '');\r\n }\r\n\r\n public disabled = false;\r\n\r\n private _onChange?: (value: string | ProfilePicturePickerData) => void;\r\n private _onTouched?: () => void;\r\n\r\n public writeValue(value: string | ProfilePicturePickerData): void {\r\n this.image = value;\r\n }\r\n\r\n public registerOnChange(onChange: (value: string | ProfilePicturePickerData) => void): void {\r\n this._onChange = onChange;\r\n }\r\n\r\n public registerOnTouched(onTouched: () => void): void {\r\n this._onTouched = onTouched;\r\n }\r\n\r\n public setDisabledState(isDisabled: boolean): void {\r\n this.disabled = isDisabled;\r\n }\r\n\r\n public ngOnInit(): void {\r\n this._normalizeSuportedExtensions();\r\n }\r\n\r\n @HostListener('dragover', ['$event'])\r\n public onDragOver(event: DragEvent) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n }\r\n\r\n @HostListener('dragleave', ['$event'])\r\n public onDragLeave(event: DragEvent): void {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n }\r\n\r\n @HostListener('drop', ['$event'])\r\n public onDrop(event: DragEvent): void {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n if (this.disabled) {\r\n return;\r\n }\r\n\r\n this._onTouched?.();\r\n\r\n const files: File[] = [];\r\n const dataTransferFiles = event.dataTransfer?.files;\r\n\r\n if (!isNullOrUndefined(dataTransferFiles)) {\r\n for (let i = 0; i < dataTransferFiles?.length; i++) {\r\n const item = dataTransferFiles.item(i);\r\n if (!isNullOrUndefined(item)) {\r\n files.push(item);\r\n }\r\n }\r\n }\r\n\r\n this._showImageCropper(files);\r\n }\r\n\r\n // Verificando o redimensionamento para ajustar o design para ficar responsivo.\r\n @HostListener('window:resize')\r\n public onResize(): void {\r\n if (this.uploadPicture && this.info && this.thumbnail) {\r\n const uploadPictureWidth = this._getWidthElement(this.uploadPicture);\r\n const infoWidth = this._getWidthElement(this.info);\r\n const thumbnailWidth = this._getWidthElement(this.thumbnail);\r\n\r\n if (thumbnailWidth + infoWidth > uploadPictureWidth) {\r\n this.uploadPicture.nativeElement.classList.add('upload-picture--small');\r\n } else {\r\n this.uploadPicture.nativeElement.classList.remove('upload-picture--small');\r\n }\r\n }\r\n }\r\n\r\n public selectPhoto(): void {\r\n if (this.disabled) {\r\n return;\r\n }\r\n\r\n const fileInputElement = this.fileInput?.nativeElement;\r\n fileInputElement.value = '';\r\n fileInputElement.click();\r\n\r\n this._onTouched?.();\r\n }\r\n\r\n public removePhoto(): void {\r\n if (this.disabled) {\r\n return;\r\n }\r\n\r\n this.confirmDialogService.confirm({\r\n message:\r\n this.confirmationTexts?.removalMessage ??\r\n this.translateService.instant('platform.angular_components.confirmation_remove_image'),\r\n acceptLabel:\r\n this.confirmationTexts?.removalAcceptLabel ??\r\n this.translateService.instant('platform.angular_components.remove'),\r\n rejectLabel:\r\n this.confirmationTexts?.removalRejectLabel ??\r\n this.translateService.instant('platform.angular_components.cancel'),\r\n header:\r\n this.confirmationTexts?.removalHeader ??\r\n this.translateService.instant('platform.angular_components.remove_image'),\r\n accept: () => {\r\n const fileInputElement = this.fileInput?.nativeElement;\r\n fileInputElement.value = '';\r\n this.image = null;\r\n this.removedImage.emit();\r\n },\r\n });\r\n }\r\n\r\n public photoSelected(event: any): void {\r\n this._showImageCropper(event.srcElement.files);\r\n }\r\n\r\n private _showImageCropper(files: File[]): void {\r\n if (!this._validateData(files)) {\r\n return;\r\n }\r\n\r\n const file = files[0];\r\n\r\n const fileReader = new FileReader();\r\n fileReader.readAsDataURL(file);\r\n fileReader.onloadend = (fileEvent: any) => {\r\n this.imageCropperService.show({\r\n imageSource: fileEvent.target.result,\r\n croppedImage: (image) => {\r\n this.changedImage.emit(image);\r\n\r\n const data: ProfilePicturePickerData = { source: file, base64: image };\r\n\r\n // Se o tipo do image for string eu preciso atualizar e mandar para o imageChange uma string.\r\n // Se for ProfilePicturePickerData eu preciso mandar o data completo.\r\n if (typeof this.image === 'string') {\r\n this.image = image;\r\n this.imageChange.emit(image);\r\n } else {\r\n this.image = data;\r\n this.imageChange.emit(data);\r\n }\r\n\r\n this._onChange?.(this.image);\r\n },\r\n changeImage: () => this.selectPhoto(),\r\n allowSelectAnother: false,\r\n aspectRatio: this.aspectRatio,\r\n ...this.cropperLabelsConfig,\r\n });\r\n };\r\n }\r\n\r\n private _normalizeSuportedExtensions(): void {\r\n this.supportedExtensions = this.supportedExtensions?.map((extension) =>\r\n extension.replace('.', '').toLocaleLowerCase(),\r\n );\r\n }\r\n\r\n private _validateData(files: File[]): boolean {\r\n if (!files.length) {\r\n return false;\r\n }\r\n\r\n if (files.length > 1) {\r\n this.invalidFile.emit({ file: null, validation: 'maxFileLimit' });\r\n return false;\r\n }\r\n\r\n const file = files[0];\r\n\r\n if (!file.type.includes('image')) {\r\n this.invalidFile.emit({ file, validation: 'typeInvalid' });\r\n return false;\r\n }\r\n\r\n if (!this._validateFileExtension(file)) {\r\n this.invalidFile.emit({ file, validation: 'unsupportedExtension' });\r\n return false;\r\n }\r\n\r\n if (!this._validateFileSize(file)) {\r\n this.invalidFile.emit({ file, validation: 'maxFileSize' });\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private _validateFileExtension(file: File): boolean {\r\n if (this.supportedExtensions?.length) {\r\n const extension = file.name.split('.').pop()?.toLowerCase() ?? '';\r\n return this.supportedExtensions.includes(extension);\r\n }\r\n return true;\r\n }\r\n\r\n private _validateFileSize(file: File): boolean {\r\n if (this.maxFileSize) {\r\n return file.size <= this.maxFileSize;\r\n }\r\n return true;\r\n }\r\n\r\n private _getWidthElement(element: ElementRef): number {\r\n const { left, right } = element.nativeElement.getBoundingClientRect();\r\n return right - left;\r\n }\r\n}\r\n","<input\n #fileInput\n [accept]=\"accept\"\n [disabled]=\"disabled\"\n class=\"file-input\"\n type=\"file\"\n (change)=\"photoSelected($event)\"\n/>\n<div\n #uploadPicture\n class=\"upload-picture\"\n [class.upload-picture--disabled]=\"disabled\"\n [attr.aria-disabled]=\"disabled\"\n>\n <s-thumbnail\n #thumbnail\n iconClass=\"far fa-user\"\n [imageSource]=\"imageBase64\"\n [hasAction]=\"!image\"\n (click)=\"selectPhoto()\"\n >\n </s-thumbnail>\n <div\n #info\n class=\"info\"\n >\n @if (image) {\n <div class=\"buttons\">\n <s-button\n [label]=\"changeButtonLabel || 'platform.angular_components.change_photo' | translate\"\n priority=\"primary\"\n [disabled]=\"disabled\"\n (clicked)=\"selectPhoto()\"\n >\n </s-button>\n <s-button\n [label]=\"removeButtonLabel || 'platform.angular_components.remove' | translate\"\n priority=\"secondary\"\n [disabled]=\"disabled\"\n (clicked)=\"removePhoto()\"\n >\n </s-button>\n </div>\n } @else {\n <p class=\"title\">\n {{ simpleTitle || 'platform.angular_components.drag_your_photo_or' | translate }}\n <span\n class=\"action-title\"\n (click)=\"selectPhoto()\"\n >\n {{ actionTitle || 'platform.angular_components.select_a_file' | translate }}\n </span>\n </p>\n }\n <p class=\"subtitle\">{{ subtitle }}</p>\n </div>\n</div>\n","import { NgModule } from '@angular/core';\r\n\r\nimport { ProfilePicturePickerComponent } from './profile-picture-picker.component';\r\nimport { ImageCropperService } from '@seniorsistemas/angular-components/image-cropper';\r\n\r\n@NgModule({\r\n imports: [ProfilePicturePickerComponent],\r\n exports: [ProfilePicturePickerComponent],\r\n providers: [ImageCropperService],\r\n})\r\nexport class ProfilePicturePickerModule {}\r\n","import { AbstractControl, ValidatorFn } from \"@angular/forms\";\n\nconst maxFileSize = (size: number): ValidatorFn => {\n return (control: AbstractControl) => {\n if (control.value?.source?.size > size) {\n return {\n maxFileSize: true,\n };\n }\n\n return null;\n };\n};\n\nconst fileExtension = (extensions: string[]) => {\n return (control: AbstractControl) => {\n if (extensions.length) {\n const extension = control.value?.source?.name?.split(\".\").pop().toLowerCase();\n if (extension?.includes(extension)) {\n return {\n fileExtension: true,\n };\n }\n }\n return null;\n };\n};\n\nexport const Validators = {\n maxFileSize,\n fileExtension,\n};\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -868,7 +868,7 @@ class SelectComponent {
868
868
  useExisting: forwardRef(() => SelectComponent),
869
869
  multi: true,
870
870
  },
871
- ], viewQueries: [{ propertyName: "_containerDiv", first: true, predicate: ["containerDiv"], descendants: true, isSignal: true }, { propertyName: "_filterInput", first: true, predicate: ["filterInput"], descendants: true, isSignal: true }, { propertyName: "_selectAllCheckbox", first: true, predicate: ["selectAllCheckbox"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n #containerDiv\n cdkOverlayOrigin\n #trigger=\"cdkOverlayOrigin\"\n class=\"select-container group flex h-[35px] w-full overflow-hidden rounded-[3px] border outline-1 outline-primary focus:outline\"\n [class.pointer-events-none]=\"disabled()\"\n [class.border-grayscale-20]=\"disabled()\"\n [class.bg-grayscale-5]=\"disabled()\"\n [class.pointer-events-auto]=\"!disabled()\"\n [class.border-grayscale-30]=\"!disabled()\"\n [class.bg-grayscale-0]=\"!disabled()\"\n [attr.aria-disabled]=\"disabled()\"\n [attr.aria-expanded]=\"showOptions()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-controls]=\"componentId + '-listbox'\"\n [attr.aria-owns]=\"showOptions() ? componentId + '-listbox' : null\"\n [attr.aria-activedescendant]=\"showOptions() ? focusedOptionId() : null\"\n role=\"combobox\"\n [id]=\"componentId + '-combobox'\"\n (click)=\"onContainerDivClick()\"\n (keydown)=\"onKeyDown($event)\"\n tabindex=\"0\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-labelledby]=\"resolvedAriaLabelledBy() || null\"\n>\n <span\n class=\"flex flex-grow select-none px-3 py-[7px]\"\n [class.text-grayscale-90]=\"!disabled() && !isClean()\"\n [class.text-grayscale-60]=\"!disabled() && isClean()\"\n [class.text-grayscale-30]=\"disabled()\"\n >\n {{ print() || placeholder() }}\n </span>\n\n @if (!disabled() && showClear() && !isClean()) {\n <button\n class=\"mx-3\"\n (click)=\"clear($event)\"\n [attr.aria-label]=\"'platform.angular_components.aria_clear_selection' | translate\"\n >\n <i\n class=\"fas fa-times flex items-center\"\n aria-hidden=\"true\"\n ></i>\n </button>\n }\n\n <div\n class=\"dropdown-container flex items-center border-l px-3 group-hover:bg-grayscale-10 group-focus:border-primary\"\n [class.border-grayscale-20]=\"disabled()\"\n [class.border-grayscale-30]=\"!disabled()\"\n >\n <i\n class=\"fas\"\n aria-hidden=\"true\"\n [class.text-grayscale-30]=\"disabled()\"\n [class.text-grayscale-90]=\"!disabled()\"\n [class.fa-caret-down]=\"!showOptions()\"\n [class.fa-caret-up]=\"showOptions()\"\n ></i>\n </div>\n</div>\n\n<ng-template\n #dropdownTemplate\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"showOptions()\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n (backdropClick)=\"showOptions.set(false)\"\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n (detach)=\"showOptions.set(false)\"\n>\n <div\n [id]=\"componentId + '-listbox'\"\n class=\"dropdown-body-class z-[1000] rounded-[3px] bg-grayscale-0 py-1 shadow-md\"\n (click)=\"$event.stopPropagation()\"\n [style.width.px]=\"containerDiv.offsetWidth\"\n [attr.aria-multiselectable]=\"multiple() ? true : null\"\n [@visibilityChanged]\n role=\"listbox\"\n >\n @if (filter()) {\n <div class=\"flex w-full items-center gap-3 px-3 py-1.5\">\n @if (multiple()) {\n <s-checkbox\n #selectAllCheckbox\n [checked]=\"allSelected()\"\n [indeterminate]=\"selectAllIsIndeterminate()\"\n (checkedChange)=\"toggleSelectAll()\"\n ></s-checkbox>\n }\n\n <div class=\"relative flex h-[35px] grow\">\n <form\n class=\"flex w-full grow\"\n [formGroup]=\"filterForm\"\n >\n <input\n #filterInput\n class=\"w-full grow rounded-[3px] border border-grayscale-30 pl-2.5 pr-7 outline-1 outline-primary\"\n type=\"text\"\n formControlName=\"filter\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"onFilterKeyDown($event)\"\n [attr.aria-label]=\"'platform.angular_components.filter_options' | translate\"\n [attr.aria-controls]=\"componentId + '-listbox'\"\n [attr.aria-activedescendant]=\"focusedOptionId()\"\n autocomplete=\"off\"\n />\n </form>\n <i\n class=\"fas fa-search absolute right-2.5 top-2.5 text-grayscale-90\"\n aria-hidden=\"true\"\n ></i>\n </div>\n <button\n (click)=\"clearFilter()\"\n [attr.aria-label]=\"'platform.angular_components.clear_filter' | translate\"\n >\n <i\n class=\"fas fa-times flex items-center\"\n aria-hidden=\"true\"\n ></i>\n </button>\n </div>\n }\n\n <!-- Virtual scroll -->\n @if (virtualScroll() && filteredOptions().length > 10) {\n <cdk-virtual-scroll-viewport\n [itemSize]=\"virtualScrollItemSize()\"\n class=\"h-52 overflow-auto\"\n >\n <ng-container *cdkVirtualFor=\"let option of filteredOptions(); trackBy: trackById\">\n <s-select-option\n [id]=\"option.id\"\n [label]=\"getOptionLabel(option.data)\"\n [multiple]=\"multiple()\"\n [checkmark]=\"checkmark()\"\n [isSelected]=\"isOptionSelected(option)\"\n (selected)=\"selectItem(option)\"\n [isGrouper]=\"option.grouper ?? false\"\n [isFocused]=\"option.data === focusedItem()\"\n ></s-select-option>\n </ng-container>\n </cdk-virtual-scroll-viewport>\n }\n\n <!-- Normal list -->\n @if (!virtualScroll() || filteredOptions().length <= 10) {\n <ul class=\"max-h-52 overflow-auto\">\n @for (option of filteredOptions(); track option.id) {\n <s-select-option\n [id]=\"option.id\"\n [label]=\"getOptionLabel(option.data)\"\n [multiple]=\"multiple()\"\n [checkmark]=\"checkmark()\"\n [isSelected]=\"isOptionSelected(option)\"\n (selected)=\"selectItem(option)\"\n [isGrouper]=\"option.grouper ?? false\"\n [isFocused]=\"option.data === focusedItem()\"\n ></s-select-option>\n }\n </ul>\n }\n\n @if (filteredOptions().length === 0) {\n <span class=\"m-3 text-grayscale-60\">\n {{ emptyMessage() ?? 'platform.angular_components.no_records_found' | translate }}\n </span>\n }\n </div>\n</ng-template>\n\n", styles: [":host.ng-dirty.ng-invalid{.dropdown-container,.select-container{border-color:#c13018;outline:none}}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i2.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i2.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i2.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: SelectOptionComponent, selector: "s-select-option", inputs: ["id", "label", "multiple", "checkmark", "isGrouper", "isFocused", "isSelected"], outputs: ["isSelectedChange", "selected"] }, { kind: "component", type: CheckboxComponent, selector: "s-checkbox", inputs: ["disabled", "checked", "indeterminate", "label", "ariaLabel", "ariaLabelledBy"], outputs: ["disabledChange", "checkedChange"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i4.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i4.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }], animations: [
871
+ ], viewQueries: [{ propertyName: "_containerDiv", first: true, predicate: ["containerDiv"], descendants: true, isSignal: true }, { propertyName: "_filterInput", first: true, predicate: ["filterInput"], descendants: true, isSignal: true }, { propertyName: "_selectAllCheckbox", first: true, predicate: ["selectAllCheckbox"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n #containerDiv\n cdkOverlayOrigin\n #trigger=\"cdkOverlayOrigin\"\n class=\"select-container group flex h-[35px] w-full overflow-hidden rounded-[3px] border outline-1 outline-primary focus:outline\"\n [class.pointer-events-none]=\"disabled()\"\n [class.border-grayscale-20]=\"disabled()\"\n [class.bg-grayscale-5]=\"disabled()\"\n [class.pointer-events-auto]=\"!disabled()\"\n [class.border-grayscale-30]=\"!disabled()\"\n [class.bg-grayscale-0]=\"!disabled()\"\n [attr.aria-disabled]=\"disabled()\"\n [attr.aria-expanded]=\"showOptions()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-controls]=\"componentId + '-listbox'\"\n [attr.aria-owns]=\"showOptions() ? componentId + '-listbox' : null\"\n [attr.aria-activedescendant]=\"showOptions() ? focusedOptionId() : null\"\n role=\"combobox\"\n [id]=\"componentId + '-combobox'\"\n (click)=\"onContainerDivClick()\"\n (keydown)=\"onKeyDown($event)\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-labelledby]=\"resolvedAriaLabelledBy() || null\"\n>\n <span\n class=\"flex flex-grow select-none px-3 py-[7px]\"\n [class.text-grayscale-90]=\"!disabled() && !isClean()\"\n [class.text-grayscale-60]=\"!disabled() && isClean()\"\n [class.text-grayscale-30]=\"disabled()\"\n >\n {{ print() || placeholder() }}\n </span>\n\n @if (!disabled() && showClear() && !isClean()) {\n <button\n class=\"mx-3\"\n (click)=\"clear($event)\"\n [attr.aria-label]=\"'platform.angular_components.aria_clear_selection' | translate\"\n >\n <i\n class=\"fas fa-times flex items-center\"\n aria-hidden=\"true\"\n ></i>\n </button>\n }\n\n <div\n class=\"dropdown-container flex items-center border-l px-3 group-hover:bg-grayscale-10 group-focus:border-primary\"\n [class.border-grayscale-20]=\"disabled()\"\n [class.border-grayscale-30]=\"!disabled()\"\n >\n <i\n class=\"fas\"\n aria-hidden=\"true\"\n [class.text-grayscale-30]=\"disabled()\"\n [class.text-grayscale-90]=\"!disabled()\"\n [class.fa-caret-down]=\"!showOptions()\"\n [class.fa-caret-up]=\"showOptions()\"\n ></i>\n </div>\n</div>\n\n<ng-template\n #dropdownTemplate\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"showOptions()\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n (backdropClick)=\"showOptions.set(false)\"\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n (detach)=\"showOptions.set(false)\"\n>\n <div\n [id]=\"componentId + '-listbox'\"\n class=\"dropdown-body-class z-[1000] rounded-[3px] bg-grayscale-0 py-1 shadow-md\"\n (click)=\"$event.stopPropagation()\"\n [style.width.px]=\"containerDiv.offsetWidth\"\n [attr.aria-multiselectable]=\"multiple() ? true : null\"\n [@visibilityChanged]\n role=\"listbox\"\n >\n @if (filter()) {\n <div class=\"flex w-full items-center gap-3 px-3 py-1.5\">\n @if (multiple()) {\n <s-checkbox\n #selectAllCheckbox\n [checked]=\"allSelected()\"\n [indeterminate]=\"selectAllIsIndeterminate()\"\n (checkedChange)=\"toggleSelectAll()\"\n ></s-checkbox>\n }\n\n <div class=\"relative flex h-[35px] grow\">\n <form\n class=\"flex w-full grow\"\n [formGroup]=\"filterForm\"\n >\n <input\n #filterInput\n class=\"w-full grow rounded-[3px] border border-grayscale-30 pl-2.5 pr-7 outline-1 outline-primary\"\n type=\"text\"\n formControlName=\"filter\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"onFilterKeyDown($event)\"\n [attr.aria-label]=\"'platform.angular_components.filter_options' | translate\"\n [attr.aria-controls]=\"componentId + '-listbox'\"\n [attr.aria-activedescendant]=\"focusedOptionId()\"\n autocomplete=\"off\"\n />\n </form>\n <i\n class=\"fas fa-search absolute right-2.5 top-2.5 text-grayscale-90\"\n aria-hidden=\"true\"\n ></i>\n </div>\n <button\n (click)=\"clearFilter()\"\n [attr.aria-label]=\"'platform.angular_components.clear_filter' | translate\"\n >\n <i\n class=\"fas fa-times flex items-center\"\n aria-hidden=\"true\"\n ></i>\n </button>\n </div>\n }\n\n <!-- Virtual scroll -->\n @if (virtualScroll() && filteredOptions().length > 10) {\n <cdk-virtual-scroll-viewport\n [itemSize]=\"virtualScrollItemSize()\"\n class=\"h-52 overflow-auto\"\n >\n <ng-container *cdkVirtualFor=\"let option of filteredOptions(); trackBy: trackById\">\n <s-select-option\n [id]=\"option.id\"\n [label]=\"getOptionLabel(option.data)\"\n [multiple]=\"multiple()\"\n [checkmark]=\"checkmark()\"\n [isSelected]=\"isOptionSelected(option)\"\n (selected)=\"selectItem(option)\"\n [isGrouper]=\"option.grouper ?? false\"\n [isFocused]=\"option.data === focusedItem()\"\n ></s-select-option>\n </ng-container>\n </cdk-virtual-scroll-viewport>\n }\n\n <!-- Normal list -->\n @if (!virtualScroll() || filteredOptions().length <= 10) {\n <ul class=\"max-h-52 overflow-auto\">\n @for (option of filteredOptions(); track option.id) {\n <s-select-option\n [id]=\"option.id\"\n [label]=\"getOptionLabel(option.data)\"\n [multiple]=\"multiple()\"\n [checkmark]=\"checkmark()\"\n [isSelected]=\"isOptionSelected(option)\"\n (selected)=\"selectItem(option)\"\n [isGrouper]=\"option.grouper ?? false\"\n [isFocused]=\"option.data === focusedItem()\"\n ></s-select-option>\n }\n </ul>\n }\n\n @if (filteredOptions().length === 0) {\n <span class=\"m-3 text-grayscale-60\">\n {{ emptyMessage() ?? 'platform.angular_components.no_records_found' | translate }}\n </span>\n }\n </div>\n</ng-template>\n\n", styles: [":host.ng-dirty.ng-invalid{.dropdown-container,.select-container{border-color:#c13018;outline:none}}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: ScrollingModule }, { kind: "directive", type: i2.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i2.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i2.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "component", type: SelectOptionComponent, selector: "s-select-option", inputs: ["id", "label", "multiple", "checkmark", "isGrouper", "isFocused", "isSelected"], outputs: ["isSelectedChange", "selected"] }, { kind: "component", type: CheckboxComponent, selector: "s-checkbox", inputs: ["disabled", "checked", "indeterminate", "label", "ariaLabel", "ariaLabelledBy"], outputs: ["disabledChange", "checkedChange"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i3.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i4.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i4.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }], animations: [
872
872
  trigger('visibilityChanged', [
873
873
  state('void', style({ opacity: 0, transform: 'scale(0.95)' })),
874
874
  transition(':enter', [
@@ -907,7 +907,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
907
907
  animate('500ms cubic-bezier(0.4, 0, 0.2, 1)', style({ opacity: 0, transform: 'scale(0.95)' })),
908
908
  ]),
909
909
  ]),
910
- ], template: "<div\n #containerDiv\n cdkOverlayOrigin\n #trigger=\"cdkOverlayOrigin\"\n class=\"select-container group flex h-[35px] w-full overflow-hidden rounded-[3px] border outline-1 outline-primary focus:outline\"\n [class.pointer-events-none]=\"disabled()\"\n [class.border-grayscale-20]=\"disabled()\"\n [class.bg-grayscale-5]=\"disabled()\"\n [class.pointer-events-auto]=\"!disabled()\"\n [class.border-grayscale-30]=\"!disabled()\"\n [class.bg-grayscale-0]=\"!disabled()\"\n [attr.aria-disabled]=\"disabled()\"\n [attr.aria-expanded]=\"showOptions()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-controls]=\"componentId + '-listbox'\"\n [attr.aria-owns]=\"showOptions() ? componentId + '-listbox' : null\"\n [attr.aria-activedescendant]=\"showOptions() ? focusedOptionId() : null\"\n role=\"combobox\"\n [id]=\"componentId + '-combobox'\"\n (click)=\"onContainerDivClick()\"\n (keydown)=\"onKeyDown($event)\"\n tabindex=\"0\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-labelledby]=\"resolvedAriaLabelledBy() || null\"\n>\n <span\n class=\"flex flex-grow select-none px-3 py-[7px]\"\n [class.text-grayscale-90]=\"!disabled() && !isClean()\"\n [class.text-grayscale-60]=\"!disabled() && isClean()\"\n [class.text-grayscale-30]=\"disabled()\"\n >\n {{ print() || placeholder() }}\n </span>\n\n @if (!disabled() && showClear() && !isClean()) {\n <button\n class=\"mx-3\"\n (click)=\"clear($event)\"\n [attr.aria-label]=\"'platform.angular_components.aria_clear_selection' | translate\"\n >\n <i\n class=\"fas fa-times flex items-center\"\n aria-hidden=\"true\"\n ></i>\n </button>\n }\n\n <div\n class=\"dropdown-container flex items-center border-l px-3 group-hover:bg-grayscale-10 group-focus:border-primary\"\n [class.border-grayscale-20]=\"disabled()\"\n [class.border-grayscale-30]=\"!disabled()\"\n >\n <i\n class=\"fas\"\n aria-hidden=\"true\"\n [class.text-grayscale-30]=\"disabled()\"\n [class.text-grayscale-90]=\"!disabled()\"\n [class.fa-caret-down]=\"!showOptions()\"\n [class.fa-caret-up]=\"showOptions()\"\n ></i>\n </div>\n</div>\n\n<ng-template\n #dropdownTemplate\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"showOptions()\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n (backdropClick)=\"showOptions.set(false)\"\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n (detach)=\"showOptions.set(false)\"\n>\n <div\n [id]=\"componentId + '-listbox'\"\n class=\"dropdown-body-class z-[1000] rounded-[3px] bg-grayscale-0 py-1 shadow-md\"\n (click)=\"$event.stopPropagation()\"\n [style.width.px]=\"containerDiv.offsetWidth\"\n [attr.aria-multiselectable]=\"multiple() ? true : null\"\n [@visibilityChanged]\n role=\"listbox\"\n >\n @if (filter()) {\n <div class=\"flex w-full items-center gap-3 px-3 py-1.5\">\n @if (multiple()) {\n <s-checkbox\n #selectAllCheckbox\n [checked]=\"allSelected()\"\n [indeterminate]=\"selectAllIsIndeterminate()\"\n (checkedChange)=\"toggleSelectAll()\"\n ></s-checkbox>\n }\n\n <div class=\"relative flex h-[35px] grow\">\n <form\n class=\"flex w-full grow\"\n [formGroup]=\"filterForm\"\n >\n <input\n #filterInput\n class=\"w-full grow rounded-[3px] border border-grayscale-30 pl-2.5 pr-7 outline-1 outline-primary\"\n type=\"text\"\n formControlName=\"filter\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"onFilterKeyDown($event)\"\n [attr.aria-label]=\"'platform.angular_components.filter_options' | translate\"\n [attr.aria-controls]=\"componentId + '-listbox'\"\n [attr.aria-activedescendant]=\"focusedOptionId()\"\n autocomplete=\"off\"\n />\n </form>\n <i\n class=\"fas fa-search absolute right-2.5 top-2.5 text-grayscale-90\"\n aria-hidden=\"true\"\n ></i>\n </div>\n <button\n (click)=\"clearFilter()\"\n [attr.aria-label]=\"'platform.angular_components.clear_filter' | translate\"\n >\n <i\n class=\"fas fa-times flex items-center\"\n aria-hidden=\"true\"\n ></i>\n </button>\n </div>\n }\n\n <!-- Virtual scroll -->\n @if (virtualScroll() && filteredOptions().length > 10) {\n <cdk-virtual-scroll-viewport\n [itemSize]=\"virtualScrollItemSize()\"\n class=\"h-52 overflow-auto\"\n >\n <ng-container *cdkVirtualFor=\"let option of filteredOptions(); trackBy: trackById\">\n <s-select-option\n [id]=\"option.id\"\n [label]=\"getOptionLabel(option.data)\"\n [multiple]=\"multiple()\"\n [checkmark]=\"checkmark()\"\n [isSelected]=\"isOptionSelected(option)\"\n (selected)=\"selectItem(option)\"\n [isGrouper]=\"option.grouper ?? false\"\n [isFocused]=\"option.data === focusedItem()\"\n ></s-select-option>\n </ng-container>\n </cdk-virtual-scroll-viewport>\n }\n\n <!-- Normal list -->\n @if (!virtualScroll() || filteredOptions().length <= 10) {\n <ul class=\"max-h-52 overflow-auto\">\n @for (option of filteredOptions(); track option.id) {\n <s-select-option\n [id]=\"option.id\"\n [label]=\"getOptionLabel(option.data)\"\n [multiple]=\"multiple()\"\n [checkmark]=\"checkmark()\"\n [isSelected]=\"isOptionSelected(option)\"\n (selected)=\"selectItem(option)\"\n [isGrouper]=\"option.grouper ?? false\"\n [isFocused]=\"option.data === focusedItem()\"\n ></s-select-option>\n }\n </ul>\n }\n\n @if (filteredOptions().length === 0) {\n <span class=\"m-3 text-grayscale-60\">\n {{ emptyMessage() ?? 'platform.angular_components.no_records_found' | translate }}\n </span>\n }\n </div>\n</ng-template>\n\n", styles: [":host.ng-dirty.ng-invalid{.dropdown-container,.select-container{border-color:#c13018;outline:none}}\n"] }]
910
+ ], template: "<div\n #containerDiv\n cdkOverlayOrigin\n #trigger=\"cdkOverlayOrigin\"\n class=\"select-container group flex h-[35px] w-full overflow-hidden rounded-[3px] border outline-1 outline-primary focus:outline\"\n [class.pointer-events-none]=\"disabled()\"\n [class.border-grayscale-20]=\"disabled()\"\n [class.bg-grayscale-5]=\"disabled()\"\n [class.pointer-events-auto]=\"!disabled()\"\n [class.border-grayscale-30]=\"!disabled()\"\n [class.bg-grayscale-0]=\"!disabled()\"\n [attr.aria-disabled]=\"disabled()\"\n [attr.aria-expanded]=\"showOptions()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-controls]=\"componentId + '-listbox'\"\n [attr.aria-owns]=\"showOptions() ? componentId + '-listbox' : null\"\n [attr.aria-activedescendant]=\"showOptions() ? focusedOptionId() : null\"\n role=\"combobox\"\n [id]=\"componentId + '-combobox'\"\n (click)=\"onContainerDivClick()\"\n (keydown)=\"onKeyDown($event)\"\n [attr.tabindex]=\"disabled() ? -1 : 0\"\n [attr.aria-label]=\"ariaLabel() || null\"\n [attr.aria-labelledby]=\"resolvedAriaLabelledBy() || null\"\n>\n <span\n class=\"flex flex-grow select-none px-3 py-[7px]\"\n [class.text-grayscale-90]=\"!disabled() && !isClean()\"\n [class.text-grayscale-60]=\"!disabled() && isClean()\"\n [class.text-grayscale-30]=\"disabled()\"\n >\n {{ print() || placeholder() }}\n </span>\n\n @if (!disabled() && showClear() && !isClean()) {\n <button\n class=\"mx-3\"\n (click)=\"clear($event)\"\n [attr.aria-label]=\"'platform.angular_components.aria_clear_selection' | translate\"\n >\n <i\n class=\"fas fa-times flex items-center\"\n aria-hidden=\"true\"\n ></i>\n </button>\n }\n\n <div\n class=\"dropdown-container flex items-center border-l px-3 group-hover:bg-grayscale-10 group-focus:border-primary\"\n [class.border-grayscale-20]=\"disabled()\"\n [class.border-grayscale-30]=\"!disabled()\"\n >\n <i\n class=\"fas\"\n aria-hidden=\"true\"\n [class.text-grayscale-30]=\"disabled()\"\n [class.text-grayscale-90]=\"!disabled()\"\n [class.fa-caret-down]=\"!showOptions()\"\n [class.fa-caret-up]=\"showOptions()\"\n ></i>\n </div>\n</div>\n\n<ng-template\n #dropdownTemplate\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"showOptions()\"\n [cdkConnectedOverlayHasBackdrop]=\"true\"\n (backdropClick)=\"showOptions.set(false)\"\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n (detach)=\"showOptions.set(false)\"\n>\n <div\n [id]=\"componentId + '-listbox'\"\n class=\"dropdown-body-class z-[1000] rounded-[3px] bg-grayscale-0 py-1 shadow-md\"\n (click)=\"$event.stopPropagation()\"\n [style.width.px]=\"containerDiv.offsetWidth\"\n [attr.aria-multiselectable]=\"multiple() ? true : null\"\n [@visibilityChanged]\n role=\"listbox\"\n >\n @if (filter()) {\n <div class=\"flex w-full items-center gap-3 px-3 py-1.5\">\n @if (multiple()) {\n <s-checkbox\n #selectAllCheckbox\n [checked]=\"allSelected()\"\n [indeterminate]=\"selectAllIsIndeterminate()\"\n (checkedChange)=\"toggleSelectAll()\"\n ></s-checkbox>\n }\n\n <div class=\"relative flex h-[35px] grow\">\n <form\n class=\"flex w-full grow\"\n [formGroup]=\"filterForm\"\n >\n <input\n #filterInput\n class=\"w-full grow rounded-[3px] border border-grayscale-30 pl-2.5 pr-7 outline-1 outline-primary\"\n type=\"text\"\n formControlName=\"filter\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"onFilterKeyDown($event)\"\n [attr.aria-label]=\"'platform.angular_components.filter_options' | translate\"\n [attr.aria-controls]=\"componentId + '-listbox'\"\n [attr.aria-activedescendant]=\"focusedOptionId()\"\n autocomplete=\"off\"\n />\n </form>\n <i\n class=\"fas fa-search absolute right-2.5 top-2.5 text-grayscale-90\"\n aria-hidden=\"true\"\n ></i>\n </div>\n <button\n (click)=\"clearFilter()\"\n [attr.aria-label]=\"'platform.angular_components.clear_filter' | translate\"\n >\n <i\n class=\"fas fa-times flex items-center\"\n aria-hidden=\"true\"\n ></i>\n </button>\n </div>\n }\n\n <!-- Virtual scroll -->\n @if (virtualScroll() && filteredOptions().length > 10) {\n <cdk-virtual-scroll-viewport\n [itemSize]=\"virtualScrollItemSize()\"\n class=\"h-52 overflow-auto\"\n >\n <ng-container *cdkVirtualFor=\"let option of filteredOptions(); trackBy: trackById\">\n <s-select-option\n [id]=\"option.id\"\n [label]=\"getOptionLabel(option.data)\"\n [multiple]=\"multiple()\"\n [checkmark]=\"checkmark()\"\n [isSelected]=\"isOptionSelected(option)\"\n (selected)=\"selectItem(option)\"\n [isGrouper]=\"option.grouper ?? false\"\n [isFocused]=\"option.data === focusedItem()\"\n ></s-select-option>\n </ng-container>\n </cdk-virtual-scroll-viewport>\n }\n\n <!-- Normal list -->\n @if (!virtualScroll() || filteredOptions().length <= 10) {\n <ul class=\"max-h-52 overflow-auto\">\n @for (option of filteredOptions(); track option.id) {\n <s-select-option\n [id]=\"option.id\"\n [label]=\"getOptionLabel(option.data)\"\n [multiple]=\"multiple()\"\n [checkmark]=\"checkmark()\"\n [isSelected]=\"isOptionSelected(option)\"\n (selected)=\"selectItem(option)\"\n [isGrouper]=\"option.grouper ?? false\"\n [isFocused]=\"option.data === focusedItem()\"\n ></s-select-option>\n }\n </ul>\n }\n\n @if (filteredOptions().length === 0) {\n <span class=\"m-3 text-grayscale-60\">\n {{ emptyMessage() ?? 'platform.angular_components.no_records_found' | translate }}\n </span>\n }\n </div>\n</ng-template>\n\n", styles: [":host.ng-dirty.ng-invalid{.dropdown-container,.select-container{border-color:#c13018;outline:none}}\n"] }]
911
911
  }], ctorParameters: () => [] });
912
912
 
913
913
  /**