@seniorsistemas/angular-components 19.10.0-develop-ef29acb7 → 19.10.1-develop-5b6fdad4
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.
- package/dynamic-form/dynamic-form/form-field/configurations/fields/select-field.d.ts +6 -0
- package/esm2022/dynamic-form/dynamic-form/form-field/configurations/fields/select-field.mjs +1 -1
- package/esm2022/dynamic-form/dynamic-form/form-field/fields/select/select-field.component.mjs +3 -3
- package/esm2022/lib/locale/fallback.mjs +2 -1
- package/esm2022/paginator/lib/paginator/paginator.component.mjs +2 -2
- package/esm2022/select/lib/select/components/select-option/select-option.component.mjs +6 -4
- package/esm2022/select/lib/select/select.component.mjs +41 -8
- package/fesm2022/seniorsistemas-angular-components-dynamic-form.mjs +2 -2
- package/fesm2022/seniorsistemas-angular-components-dynamic-form.mjs.map +1 -1
- package/fesm2022/seniorsistemas-angular-components-paginator.mjs +1 -1
- package/fesm2022/seniorsistemas-angular-components-paginator.mjs.map +1 -1
- package/fesm2022/seniorsistemas-angular-components-select.mjs +45 -10
- package/fesm2022/seniorsistemas-angular-components-select.mjs.map +1 -1
- package/fesm2022/seniorsistemas-angular-components.mjs +1 -0
- package/fesm2022/seniorsistemas-angular-components.mjs.map +1 -1
- package/package.json +1 -1
- package/select/README.md +18 -0
- package/select/lib/select/components/select-option/select-option.component.d.ts +3 -1
- package/select/lib/select/select.component.d.ts +17 -2
|
@@ -155,7 +155,7 @@ class PaginatorComponent {
|
|
|
155
155
|
this.requestedPage.set(pageIndex);
|
|
156
156
|
}
|
|
157
157
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PaginatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
158
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: PaginatorComponent, isStandalone: true, selector: "s-paginator", inputs: { totalRecords: { classPropertyName: "totalRecords", publicName: "totalRecords", isSignal: true, isRequired: true, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, rowsPerPageOptions: { classPropertyName: "rowsPerPageOptions", publicName: "rowsPerPageOptions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rows: "rowsChange", pageChange: "pageChange" }, ngImport: i0, template: "<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 [class.rounded-l-medium]=\"$first\"\n [class.rounded-r-medium]=\"$last\"\n (sInteractiveContent)=\"activatedButton(btn)\"\n [attr.disabled]=\"btn.disabled || (btn.validate && btn.validate()) ? '' : null\"\n [attr.aria-label]=\"ariaLabelKey | translate: { page: btn.pageIndex }\"\n [attr.aria-current]=\"active ? 'page' : null\"\n class=\"group h-[30px] w-8 hover:bg-grayscale-20 hover:text-grayscale-100 disabled:hover:bg-[transparent] disabled:hover:text-criticality-blue focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-[var(--s-focus-ring-color,#0090ff)]\"\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", dependencies: [{ kind: "directive", type: InteractiveContentDirective, selector: "[sInteractiveContent]", inputs: ["focusable", "disabled", "stopPropagation"], outputs: ["sInteractiveContent"] }, { kind: "component", type: SelectComponent, selector: "s-select", inputs: ["placeholder", "multiple", "options", "optionLabel", "optionValue", "showClear", "filter", "checkmark", "checkIconClass", "filterBy", "group", "virtualScroll", "virtualScrollItemSize", "emptyMessage", "disabled", "showOptions", "ariaLabel", "ariaLabelledBy"], outputs: ["disabledChange", "showOptionsChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] });
|
|
158
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: PaginatorComponent, isStandalone: true, selector: "s-paginator", inputs: { totalRecords: { classPropertyName: "totalRecords", publicName: "totalRecords", isSignal: true, isRequired: true, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, rowsPerPageOptions: { classPropertyName: "rowsPerPageOptions", publicName: "rowsPerPageOptions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rows: "rowsChange", pageChange: "pageChange" }, ngImport: i0, template: "<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 [class.rounded-l-medium]=\"$first\"\n [class.rounded-r-medium]=\"$last\"\n (sInteractiveContent)=\"activatedButton(btn)\"\n [attr.disabled]=\"btn.disabled || (btn.validate && btn.validate()) ? '' : null\"\n [attr.aria-label]=\"ariaLabelKey | translate: { page: btn.pageIndex }\"\n [attr.aria-current]=\"active ? 'page' : null\"\n class=\"group h-[30px] w-8 hover:bg-grayscale-20 hover:text-grayscale-100 disabled:hover:bg-[transparent] disabled:hover:text-criticality-blue focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-[var(--s-focus-ring-color,#0090ff)]\"\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", dependencies: [{ kind: "directive", type: InteractiveContentDirective, selector: "[sInteractiveContent]", inputs: ["focusable", "disabled", "stopPropagation"], outputs: ["sInteractiveContent"] }, { kind: "component", type: SelectComponent, selector: "s-select", inputs: ["placeholder", "multiple", "options", "optionLabel", "optionValue", "showClear", "filter", "checkmark", "checkIconClass", "filterBy", "group", "virtualScroll", "virtualScrollItemSize", "emptyMessage", "disabled", "readonly", "showOptions", "ariaLabel", "ariaLabelledBy"], outputs: ["disabledChange", "showOptionsChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] });
|
|
159
159
|
}
|
|
160
160
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PaginatorComponent, decorators: [{
|
|
161
161
|
type: Component,
|
|
@@ -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 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 [class.rounded-l-medium]=\"$first\"\n [class.rounded-r-medium]=\"$last\"\n (sInteractiveContent)=\"activatedButton(btn)\"\n [attr.disabled]=\"btn.disabled || (btn.validate && btn.validate()) ? '' : null\"\n [attr.aria-label]=\"ariaLabelKey | translate: { page: btn.pageIndex }\"\n [attr.aria-current]=\"active ? 'page' : null\"\n class=\"group h-[30px] w-8 hover:bg-grayscale-20 hover:text-grayscale-100 disabled:hover:bg-[transparent] disabled:hover:text-criticality-blue focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-[var(--s-focus-ring-color,#0090ff)]\"\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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"}
|
|
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 [class.rounded-l-medium]=\"$first\"\n [class.rounded-r-medium]=\"$last\"\n (sInteractiveContent)=\"activatedButton(btn)\"\n [attr.disabled]=\"btn.disabled || (btn.validate && btn.validate()) ? '' : null\"\n [attr.aria-label]=\"ariaLabelKey | translate: { page: btn.pageIndex }\"\n [attr.aria-current]=\"active ? 'page' : null\"\n class=\"group h-[30px] w-8 hover:bg-grayscale-20 hover:text-grayscale-100 disabled:hover:bg-[transparent] disabled:hover:text-criticality-blue focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-[var(--s-focus-ring-color,#0090ff)]\"\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":";;;;;;;;;AAQA;;;;;;;;;;;;;;AAcG;MAOU,kBAAkB,CAAA;;AAE3B,IAAA,YAAY,GAAG,KAAK,CAAC,QAAQ,EAAU,CAAC;;AAExC,IAAA,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC;;AAEjB,IAAA,kBAAkB,GAAG,KAAK,CAAW,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;;IAE7D,UAAU,GAAG,MAAM,EAAc,CAAC;AAEjB,IAAA,iBAAiB,GAAG,MAAM,CAAC,MAAK;AAC7C,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;AACpC,QAAA,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YACjB,IAAI;AACJ,YAAA,SAAS,EAAE,UAAU;AACrB,YAAA,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;AACjB,YAAA,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI;AAC5B,SAAA,CAAC,CAAC;AACP,KAAC,CAAC,CAAC;IACc,gBAAgB,GAAG,CAAC,CAAC;AACrB,IAAA,eAAe,GAAG,QAAQ,CAAC,MAAK;QAC7C,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;QAC5C,OAAO,YAAY,IAAI,CAAC,CAAC;AAC7B,KAAC,CAAC,CAAC;AAEc,IAAA,WAAW,GAAG,QAAQ,CAAC,MAAK;QACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;AACxC,QAAA,OAAO,QAAQ,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;AACzC,KAAC,CAAC,CAAC;AAEc,IAAA,aAAa,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;;AAExB,IAAA,WAAW,GAAG,QAAQ,CAAC,MAAK;AAC3C,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC;AAC/C,QAAA,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AAChE,KAAC,CAAC,CAAC;AAEO,IAAA,OAAO,GAAG,QAAQ,CAAC,MAAK;QAC9B,MAAM,qBAAqB,GAA8B,EAAE,CAAC;AAC5D,QAAA,MAAM,cAAc,GAAG,IAAI,CAAC,gBAAgB,CAAC;AAC7C,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC;AAC9C,QAAA,MAAM,UAAU,GAAG,WAAW,GAAG,MAAM,CAAC;AACxC,QAAA,IAAI,SAAS,GAAG,UAAU,GAAG,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC;AAChD,QAAA,MAAM,QAAQ,GAAG,SAAS,GAAG,cAAc,GAAG,CAAC,CAAC;QAChD,MAAM,2BAA2B,GAAG,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAEjE,IAAI,2BAA2B,EAAE;YAC7B,MAAM,IAAI,GAAG,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;AAC1C,YAAA,MAAM,kBAAkB,GAAG,SAAS,GAAG,IAAI,IAAI,CAAC,CAAC;YACjD,IAAI,kBAAkB,EAAE;AACpB,gBAAA,SAAS,GAAG,SAAS,GAAG,IAAI,CAAC;aAChC;SACJ;AACD,QAAA,MAAM,OAAO,GAAG,2BAA2B,GAAG,IAAI,CAAC,UAAU,EAAE,GAAG,QAAQ,CAAC;AAE3E,QAAA,KAAK,IAAI,CAAC,GAAG,SAAS,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC,EAAE,EAAE;YACvC,qBAAqB,CAAC,IAAI,CAAC;AACvB,gBAAA,OAAO,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAmB,CAAC;AAC1D,gBAAA,SAAS,EAAE,CAAC;AACf,aAAA,CAAC,CAAC;SACN;QAED,OAAO;AACH,YAAA,IAAI,CAAC,iBAAiB;AACtB,YAAA,IAAI,CAAC,oBAAoB;AACzB,YAAA,GAAG,qBAAqB;AACxB,YAAA,IAAI,CAAC,gBAAgB;AACrB,YAAA,IAAI,CAAC,gBAAgB;SACxB,CAAC;AACN,KAAC,CAAC,CAAC;AAEc,IAAA,iBAAiB,GAA4B;QAC1D,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;AACpC,QAAA,IAAI,EAAE,sBAAsB;AAC5B,QAAA,YAAY,EAAE,6CAA6C;AAC3D,QAAA,QAAQ,EAAE,QAAQ,CAAC,MAAK;AACpB,YAAA,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;AACnC,SAAC,CAAC;KACL,CAAC;AAEe,IAAA,oBAAoB,GAA4B;QAC7D,OAAO,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;AACvC,QAAA,IAAI,EAAE,mBAAmB;AACzB,QAAA,YAAY,EAAE,gDAAgD;AAC9D,QAAA,QAAQ,EAAE,QAAQ,CAAC,MAAK;AACpB,YAAA,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;AACnC,SAAC,CAAC;KACL,CAAC;AAEe,IAAA,gBAAgB,GAA4B;QACzD,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;AACnC,QAAA,IAAI,EAAE,qBAAqB;AAC3B,QAAA,YAAY,EAAE,4CAA4C;AAC1D,QAAA,QAAQ,EAAE,QAAQ,CAAC,MAAK;AACpB,YAAA,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;AAC/B,SAAC,CAAC;KACL,CAAC;AAEe,IAAA,gBAAgB,GAA4B;QACzD,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;AACnC,QAAA,IAAI,EAAE,oBAAoB;AAC1B,QAAA,YAAY,EAAE,4CAA4C;AAC1D,QAAA,QAAQ,EAAE,QAAQ,CAAC,MAAK;AACpB,YAAA,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;AAC/B,SAAC,CAAC;KACL,CAAC;AAEM,IAAA,UAAU,GAAG,QAAQ,CAAC,MAAK;AAC/B,QAAA,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;AACxD,KAAC,CAAC,CAAC;IAEI,WAAW,GAAA;AACd,QAAA,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,CAAC;KACpC;IAES,iBAAiB,GAAA;AACvB,QAAA,IAAI,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,EAAE;AAC1B,YAAA,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;SACpB;KACJ;AAES,IAAA,eAAe,CAAC,MAA+B,EAAA;AACrD,QAAA,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;KAC1B;IAEO,WAAW,GAAA;AACf,QAAA,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;KACpB;IAEO,UAAU,GAAA;AACd,QAAA,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE;YACrB,OAAO;SACV;QACD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC;KACzC;IAEO,cAAc,GAAA;AAClB,QAAA,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE;YACzB,OAAO;SACV;QACD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC;KACzC;IAEO,UAAU,GAAA;QACd,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;KACpC;AAEO,IAAA,QAAQ,CAAC,SAAiB,EAAA;AAC9B,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;KACrC;wGAvJQ,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;4FAAlB,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,kBAAA,EAAA,EAAA,iBAAA,EAAA,oBAAA,EAAA,UAAA,EAAA,oBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,IAAA,EAAA,YAAA,EAAA,UAAA,EAAA,YAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EC7B/B,6vFAwDA,ED9Bc,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,2BAA2B,0JAAE,eAAe,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,aAAA,EAAA,UAAA,EAAA,SAAA,EAAA,aAAA,EAAA,aAAA,EAAA,WAAA,EAAA,QAAA,EAAA,WAAA,EAAA,gBAAA,EAAA,UAAA,EAAA,OAAA,EAAA,eAAA,EAAA,uBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,UAAA,EAAA,aAAA,EAAA,WAAA,EAAA,gBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,gBAAA,EAAA,mBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAE,WAAW,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,qDAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,SAAA,EAAA,gBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAE,eAAe,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,EAAA,CAAA,aAAA,EAAA,IAAA,EAAA,WAAA,EAAA,CAAA,EAAA,CAAA,CAAA;;4FAG3E,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAN9B,SAAS;+BACI,aAAa,EAAA,UAAA,EACX,IAAI,EAAA,OAAA,EACP,CAAC,2BAA2B,EAAE,eAAe,EAAE,WAAW,EAAE,eAAe,CAAC,EAAA,QAAA,EAAA,6vFAAA,EAAA,CAAA;;;AE1BzF;;AAEG;;;;"}
|
|
@@ -21,6 +21,8 @@ class SelectOptionComponent {
|
|
|
21
21
|
checkmark = input.required();
|
|
22
22
|
isGrouper = input.required();
|
|
23
23
|
isFocused = input.required();
|
|
24
|
+
/** @description Modo somente leitura: a opção não responde a clique/teclado e não exibe hover. @default false */
|
|
25
|
+
readonly = input(false);
|
|
24
26
|
isSelected = model.required();
|
|
25
27
|
/** @description Classe do ícone de checkmark exibido quando a opção está selecionada. @default 'far fa-check' */
|
|
26
28
|
checkIconClass = input('far fa-check');
|
|
@@ -48,13 +50,13 @@ class SelectOptionComponent {
|
|
|
48
50
|
setsize = input(null);
|
|
49
51
|
selected = output();
|
|
50
52
|
onClick() {
|
|
51
|
-
if (this.isGrouper()) {
|
|
53
|
+
if (this.isGrouper() || this.readonly()) {
|
|
52
54
|
return;
|
|
53
55
|
}
|
|
54
56
|
this.selected.emit();
|
|
55
57
|
}
|
|
56
58
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SelectOptionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
57
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SelectOptionComponent, isStandalone: true, selector: "s-select-option", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: true, transformFunction: null }, checkmark: { classPropertyName: "checkmark", publicName: "checkmark", isSignal: true, isRequired: true, transformFunction: null }, isGrouper: { classPropertyName: "isGrouper", publicName: "isGrouper", isSignal: true, isRequired: true, transformFunction: null }, isFocused: { classPropertyName: "isFocused", publicName: "isFocused", isSignal: true, isRequired: true, transformFunction: null }, isSelected: { classPropertyName: "isSelected", publicName: "isSelected", isSignal: true, isRequired: true, transformFunction: null }, checkIconClass: { classPropertyName: "checkIconClass", publicName: "checkIconClass", isSignal: true, isRequired: false, transformFunction: null }, groupAnnouncement: { classPropertyName: "groupAnnouncement", publicName: "groupAnnouncement", isSignal: true, isRequired: false, transformFunction: null }, posinset: { classPropertyName: "posinset", publicName: "posinset", isSignal: true, isRequired: false, transformFunction: null }, setsize: { classPropertyName: "setsize", publicName: "setsize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { isSelected: "isSelectedChange", selected: "selected" }, host: { attributes: { "role": "presentation" } }, ngImport: i0, template: "<div\n [attr.id]=\"id()\"\n [attr.role]=\"isGrouper() ? 'presentation' : 'option'\"\n [attr.aria-selected]=\"isGrouper() ? null : isSelected()\"\n [attr.aria-describedby]=\"groupAnnouncement() ? id() + '-group' : null\"\n [attr.aria-posinset]=\"isGrouper() ? null : posinset()\"\n [attr.aria-setsize]=\"isGrouper() ? null : setsize()\"\n class=\"flex select-none items-center gap-3 px-3 py-2\"\n [class.hover:bg-grayscale-10]=\"!isGrouper()\"\n [class.bg-grayscale-10]=\"!isGrouper() && isFocused()\"\n (click)=\"onClick()\"\n (keydown.enter)=\"onClick()\"\n (keydown.space)=\"onClick(); $event.preventDefault()\"\n>\n @if (!isGrouper() && checkmark() && !multiple() && isSelected()) {\n <i\n class=\"text-grayscale-60\"\n [class]=\"checkIconClass()\"\n aria-hidden=\"true\"\n ></i>\n }\n\n @if (!isGrouper() && multiple()) {\n <!-- aria-hidden: puramente visual \u2014 o clique borbulha pro (click) do pr\u00F3prio option acima,\n e o estado de sele\u00E7\u00E3o j\u00E1 \u00E9 comunicado pelo aria-selected do option. Sem isso, esse\n checkbox aninhado (sem aria-label, com seu pr\u00F3prio aria-checked independente) era um\n segundo objeto de acessibilidade \"concorrente\" anunciando o mesmo estado \u2014 reportado\n via NVDA: o leitor de tela anunciava esse checkbox (sem nome/posi\u00E7\u00E3o pr\u00F3pria) antes\n da op\u00E7\u00E3o correta ser anunciada. -->\n <s-checkbox\n [checked]=\"isSelected()\"\n aria-hidden=\"true\"\n ></s-checkbox>\n }\n <span\n [class]=\"isSelected() ? 'text-[#428BCA]' : 'text-grayscale-90'\"\n [class.font-bold]=\"isGrouper()\"\n >\n {{ label() }}\n </span>\n\n @if (groupAnnouncement()) {\n <!-- aria-hidden pra n\u00E3o entrar no nome acess\u00EDvel da op\u00E7\u00E3o (computado a partir do\n conte\u00FAdo de texto vis\u00EDvel) \u2014 o `aria-describedby` acima ainda consegue ler seu\n texto normalmente, j\u00E1 que essa leitura ignora deliberadamente o aria-hidden do\n elemento referenciado. Sem isso, o texto seria anunciado duas vezes (uma como\n parte do nome, outra como descri\u00E7\u00E3o). -->\n <span\n class=\"sr-only\"\n [id]=\"id() + '-group'\"\n aria-hidden=\"true\"\n >{{ groupAnnouncement() }}</span>\n }\n</div>\n\n", dependencies: [{ kind: "component", type: CheckboxComponent, selector: "s-checkbox", inputs: ["disabled", "checked", "indeterminate", "label", "ariaLabel", "ariaLabelledBy"], outputs: ["disabledChange", "checkedChange"] }] });
|
|
59
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SelectOptionComponent, isStandalone: true, selector: "s-select-option", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: true, transformFunction: null }, checkmark: { classPropertyName: "checkmark", publicName: "checkmark", isSignal: true, isRequired: true, transformFunction: null }, isGrouper: { classPropertyName: "isGrouper", publicName: "isGrouper", isSignal: true, isRequired: true, transformFunction: null }, isFocused: { classPropertyName: "isFocused", publicName: "isFocused", isSignal: true, isRequired: true, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, isSelected: { classPropertyName: "isSelected", publicName: "isSelected", isSignal: true, isRequired: true, transformFunction: null }, checkIconClass: { classPropertyName: "checkIconClass", publicName: "checkIconClass", isSignal: true, isRequired: false, transformFunction: null }, groupAnnouncement: { classPropertyName: "groupAnnouncement", publicName: "groupAnnouncement", isSignal: true, isRequired: false, transformFunction: null }, posinset: { classPropertyName: "posinset", publicName: "posinset", isSignal: true, isRequired: false, transformFunction: null }, setsize: { classPropertyName: "setsize", publicName: "setsize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { isSelected: "isSelectedChange", selected: "selected" }, host: { attributes: { "role": "presentation" } }, ngImport: i0, template: "<div\n [attr.id]=\"id()\"\n [attr.role]=\"isGrouper() ? 'presentation' : 'option'\"\n [attr.aria-selected]=\"isGrouper() ? null : isSelected()\"\n [attr.aria-disabled]=\"!isGrouper() && readonly() ? true : null\"\n [attr.aria-describedby]=\"groupAnnouncement() ? id() + '-group' : null\"\n [attr.aria-posinset]=\"isGrouper() ? null : posinset()\"\n [attr.aria-setsize]=\"isGrouper() ? null : setsize()\"\n class=\"flex select-none items-center gap-3 px-3 py-2\"\n [class.hover:bg-grayscale-10]=\"!isGrouper() && !readonly()\"\n [class.bg-grayscale-10]=\"!isGrouper() && isFocused()\"\n (click)=\"onClick()\"\n (keydown.enter)=\"onClick()\"\n (keydown.space)=\"onClick(); $event.preventDefault()\"\n>\n @if (!isGrouper() && checkmark() && !multiple() && isSelected()) {\n <i\n class=\"text-grayscale-60\"\n [class]=\"checkIconClass()\"\n aria-hidden=\"true\"\n ></i>\n }\n\n @if (!isGrouper() && multiple()) {\n <!-- aria-hidden: puramente visual \u2014 o clique borbulha pro (click) do pr\u00F3prio option acima,\n e o estado de sele\u00E7\u00E3o j\u00E1 \u00E9 comunicado pelo aria-selected do option. Sem isso, esse\n checkbox aninhado (sem aria-label, com seu pr\u00F3prio aria-checked independente) era um\n segundo objeto de acessibilidade \"concorrente\" anunciando o mesmo estado \u2014 reportado\n via NVDA: o leitor de tela anunciava esse checkbox (sem nome/posi\u00E7\u00E3o pr\u00F3pria) antes\n da op\u00E7\u00E3o correta ser anunciada. -->\n <s-checkbox\n [checked]=\"isSelected()\"\n aria-hidden=\"true\"\n ></s-checkbox>\n }\n <span\n [class]=\"isSelected() ? 'text-[#428BCA]' : 'text-grayscale-90'\"\n [class.font-bold]=\"isGrouper()\"\n >\n {{ label() }}\n </span>\n\n @if (groupAnnouncement()) {\n <!-- aria-hidden pra n\u00E3o entrar no nome acess\u00EDvel da op\u00E7\u00E3o (computado a partir do\n conte\u00FAdo de texto vis\u00EDvel) \u2014 o `aria-describedby` acima ainda consegue ler seu\n texto normalmente, j\u00E1 que essa leitura ignora deliberadamente o aria-hidden do\n elemento referenciado. Sem isso, o texto seria anunciado duas vezes (uma como\n parte do nome, outra como descri\u00E7\u00E3o). -->\n <span\n class=\"sr-only\"\n [id]=\"id() + '-group'\"\n aria-hidden=\"true\"\n >{{ groupAnnouncement() }}</span>\n }\n</div>\n\n", dependencies: [{ kind: "component", type: CheckboxComponent, selector: "s-checkbox", inputs: ["disabled", "checked", "indeterminate", "label", "ariaLabel", "ariaLabelledBy"], outputs: ["disabledChange", "checkedChange"] }] });
|
|
58
60
|
}
|
|
59
61
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SelectOptionComponent, decorators: [{
|
|
60
62
|
type: Component,
|
|
@@ -64,7 +66,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
64
66
|
// e o role="option" do template interno (ver WAI-ARIA APG: wrappers entre um
|
|
65
67
|
// role pai e um role filho precisam de role="presentation"/"none").
|
|
66
68
|
role: 'presentation',
|
|
67
|
-
}, template: "<div\n [attr.id]=\"id()\"\n [attr.role]=\"isGrouper() ? 'presentation' : 'option'\"\n [attr.aria-selected]=\"isGrouper() ? null : isSelected()\"\n [attr.aria-describedby]=\"groupAnnouncement() ? id() + '-group' : null\"\n [attr.aria-posinset]=\"isGrouper() ? null : posinset()\"\n [attr.aria-setsize]=\"isGrouper() ? null : setsize()\"\n class=\"flex select-none items-center gap-3 px-3 py-2\"\n [class.hover:bg-grayscale-10]=\"!isGrouper()\"\n [class.bg-grayscale-10]=\"!isGrouper() && isFocused()\"\n (click)=\"onClick()\"\n (keydown.enter)=\"onClick()\"\n (keydown.space)=\"onClick(); $event.preventDefault()\"\n>\n @if (!isGrouper() && checkmark() && !multiple() && isSelected()) {\n <i\n class=\"text-grayscale-60\"\n [class]=\"checkIconClass()\"\n aria-hidden=\"true\"\n ></i>\n }\n\n @if (!isGrouper() && multiple()) {\n <!-- aria-hidden: puramente visual \u2014 o clique borbulha pro (click) do pr\u00F3prio option acima,\n e o estado de sele\u00E7\u00E3o j\u00E1 \u00E9 comunicado pelo aria-selected do option. Sem isso, esse\n checkbox aninhado (sem aria-label, com seu pr\u00F3prio aria-checked independente) era um\n segundo objeto de acessibilidade \"concorrente\" anunciando o mesmo estado \u2014 reportado\n via NVDA: o leitor de tela anunciava esse checkbox (sem nome/posi\u00E7\u00E3o pr\u00F3pria) antes\n da op\u00E7\u00E3o correta ser anunciada. -->\n <s-checkbox\n [checked]=\"isSelected()\"\n aria-hidden=\"true\"\n ></s-checkbox>\n }\n <span\n [class]=\"isSelected() ? 'text-[#428BCA]' : 'text-grayscale-90'\"\n [class.font-bold]=\"isGrouper()\"\n >\n {{ label() }}\n </span>\n\n @if (groupAnnouncement()) {\n <!-- aria-hidden pra n\u00E3o entrar no nome acess\u00EDvel da op\u00E7\u00E3o (computado a partir do\n conte\u00FAdo de texto vis\u00EDvel) \u2014 o `aria-describedby` acima ainda consegue ler seu\n texto normalmente, j\u00E1 que essa leitura ignora deliberadamente o aria-hidden do\n elemento referenciado. Sem isso, o texto seria anunciado duas vezes (uma como\n parte do nome, outra como descri\u00E7\u00E3o). -->\n <span\n class=\"sr-only\"\n [id]=\"id() + '-group'\"\n aria-hidden=\"true\"\n >{{ groupAnnouncement() }}</span>\n }\n</div>\n\n" }]
|
|
69
|
+
}, template: "<div\n [attr.id]=\"id()\"\n [attr.role]=\"isGrouper() ? 'presentation' : 'option'\"\n [attr.aria-selected]=\"isGrouper() ? null : isSelected()\"\n [attr.aria-disabled]=\"!isGrouper() && readonly() ? true : null\"\n [attr.aria-describedby]=\"groupAnnouncement() ? id() + '-group' : null\"\n [attr.aria-posinset]=\"isGrouper() ? null : posinset()\"\n [attr.aria-setsize]=\"isGrouper() ? null : setsize()\"\n class=\"flex select-none items-center gap-3 px-3 py-2\"\n [class.hover:bg-grayscale-10]=\"!isGrouper() && !readonly()\"\n [class.bg-grayscale-10]=\"!isGrouper() && isFocused()\"\n (click)=\"onClick()\"\n (keydown.enter)=\"onClick()\"\n (keydown.space)=\"onClick(); $event.preventDefault()\"\n>\n @if (!isGrouper() && checkmark() && !multiple() && isSelected()) {\n <i\n class=\"text-grayscale-60\"\n [class]=\"checkIconClass()\"\n aria-hidden=\"true\"\n ></i>\n }\n\n @if (!isGrouper() && multiple()) {\n <!-- aria-hidden: puramente visual \u2014 o clique borbulha pro (click) do pr\u00F3prio option acima,\n e o estado de sele\u00E7\u00E3o j\u00E1 \u00E9 comunicado pelo aria-selected do option. Sem isso, esse\n checkbox aninhado (sem aria-label, com seu pr\u00F3prio aria-checked independente) era um\n segundo objeto de acessibilidade \"concorrente\" anunciando o mesmo estado \u2014 reportado\n via NVDA: o leitor de tela anunciava esse checkbox (sem nome/posi\u00E7\u00E3o pr\u00F3pria) antes\n da op\u00E7\u00E3o correta ser anunciada. -->\n <s-checkbox\n [checked]=\"isSelected()\"\n aria-hidden=\"true\"\n ></s-checkbox>\n }\n <span\n [class]=\"isSelected() ? 'text-[#428BCA]' : 'text-grayscale-90'\"\n [class.font-bold]=\"isGrouper()\"\n >\n {{ label() }}\n </span>\n\n @if (groupAnnouncement()) {\n <!-- aria-hidden pra n\u00E3o entrar no nome acess\u00EDvel da op\u00E7\u00E3o (computado a partir do\n conte\u00FAdo de texto vis\u00EDvel) \u2014 o `aria-describedby` acima ainda consegue ler seu\n texto normalmente, j\u00E1 que essa leitura ignora deliberadamente o aria-hidden do\n elemento referenciado. Sem isso, o texto seria anunciado duas vezes (uma como\n parte do nome, outra como descri\u00E7\u00E3o). -->\n <span\n class=\"sr-only\"\n [id]=\"id() + '-group'\"\n aria-hidden=\"true\"\n >{{ groupAnnouncement() }}</span>\n }\n</div>\n\n" }]
|
|
68
70
|
}] });
|
|
69
71
|
|
|
70
72
|
/**
|
|
@@ -118,6 +120,14 @@ class SelectComponent {
|
|
|
118
120
|
emptyMessage = input(null);
|
|
119
121
|
/** @description Controla o estado desabilitado do componente via two-way binding. @default false */
|
|
120
122
|
disabled = model(false);
|
|
123
|
+
/**
|
|
124
|
+
* @description Habilita o modo somente leitura. O usuário continua podendo abrir e fechar a
|
|
125
|
+
* lista (por mouse ou teclado) e ver quais opções estão selecionadas, mas não consegue
|
|
126
|
+
* selecionar, desmarcar nem limpar opções. Diferente de `disabled`, o campo permanece
|
|
127
|
+
* focável e é anunciado por leitores de tela como não editável (`aria-readonly`). Quando
|
|
128
|
+
* `disabled` também está ativo, prevalece o comportamento de `disabled`. @default false
|
|
129
|
+
*/
|
|
130
|
+
readonly = input(false);
|
|
121
131
|
/** @description Controla a visibilidade do painel de opções via two-way binding. @default false */
|
|
122
132
|
showOptions = model(false);
|
|
123
133
|
/** @description Label de acessibilidade do componente. @default '' */
|
|
@@ -478,7 +488,9 @@ class SelectComponent {
|
|
|
478
488
|
// caso contrário, vai direto para o input de filtro.
|
|
479
489
|
// O foco é movido após a renderização do overlay.
|
|
480
490
|
afterNextRender(() => {
|
|
481
|
-
|
|
491
|
+
// Em somente leitura o checkbox "Selecionar todos" fica desabilitado
|
|
492
|
+
// (não focável), então o foco inicial vai direto pro input de filtro.
|
|
493
|
+
if (this.multiple() && !this.readonly()) {
|
|
482
494
|
const checkboxHost = this._selectAllCheckbox()?.nativeElement;
|
|
483
495
|
const focusable = checkboxHost?.querySelector('[tabindex]');
|
|
484
496
|
focusable?.focus();
|
|
@@ -497,6 +509,7 @@ class SelectComponent {
|
|
|
497
509
|
* Seleciona um item no componente de seleção.
|
|
498
510
|
* @param item O item a ser selecionado ou desmarcado.
|
|
499
511
|
* Se o componente estiver desabilitado, a função retorna imediatamente.
|
|
512
|
+
* Em modo somente leitura, não altera o valor e apenas anuncia que o campo não é editável.
|
|
500
513
|
* No modo múltiplo, adiciona ou remove o item da lista de valores selecionados.
|
|
501
514
|
* No modo simples, define o item como valor selecionado e fecha o dropdown.
|
|
502
515
|
* Sempre notifica as mudanças e marca o componente como tocado.
|
|
@@ -505,6 +518,10 @@ class SelectComponent {
|
|
|
505
518
|
if (this.disabled()) {
|
|
506
519
|
return;
|
|
507
520
|
}
|
|
521
|
+
if (this.readonly()) {
|
|
522
|
+
this._announceReadonly();
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
508
525
|
const optionValue = this.optionValue();
|
|
509
526
|
if (this.multiple()) {
|
|
510
527
|
const store = [...this.values()];
|
|
@@ -543,6 +560,14 @@ class SelectComponent {
|
|
|
543
560
|
}
|
|
544
561
|
this._onTouched();
|
|
545
562
|
}
|
|
563
|
+
/**
|
|
564
|
+
* Anuncia via `LiveAnnouncer` que o campo é somente leitura. Chamado quando o usuário tenta
|
|
565
|
+
* alterar a seleção — sem isso, Enter/Espaço numa opção seria um no-op silencioso para quem
|
|
566
|
+
* usa leitor de tela.
|
|
567
|
+
*/
|
|
568
|
+
_announceReadonly() {
|
|
569
|
+
void this._liveAnnouncer.announce(this._translateService.instant('platform.angular_components.select_readonly_cannot_change'), 'polite');
|
|
570
|
+
}
|
|
546
571
|
/**
|
|
547
572
|
* Anuncia via `LiveAnnouncer` a opção selecionada/desmarcada. Necessário porque, na prática,
|
|
548
573
|
* nem todo navegador/leitor de tela anuncia sozinho a mudança de `aria-selected` da opção
|
|
@@ -558,7 +583,7 @@ class SelectComponent {
|
|
|
558
583
|
}
|
|
559
584
|
/**
|
|
560
585
|
* Limpa o valor selecionado no componente select.
|
|
561
|
-
* Se o componente estiver desabilitado, não executa nenhuma ação.
|
|
586
|
+
* Se o componente estiver desabilitado ou somente leitura, não executa nenhuma ação.
|
|
562
587
|
* Para seleção múltipla, remove todos os valores selecionados e notifica a alteração.
|
|
563
588
|
* Para seleção única, define o valor como nulo e notifica a alteração.
|
|
564
589
|
* Fecha o dropdown e marca o componente como "tocado".
|
|
@@ -566,7 +591,7 @@ class SelectComponent {
|
|
|
566
591
|
* @param event Evento do mouse que acionou a limpeza da seleção.
|
|
567
592
|
*/
|
|
568
593
|
clear(event) {
|
|
569
|
-
if (this.disabled()) {
|
|
594
|
+
if (this.disabled() || this.readonly()) {
|
|
570
595
|
return;
|
|
571
596
|
}
|
|
572
597
|
if (this.multiple()) {
|
|
@@ -841,6 +866,12 @@ class SelectComponent {
|
|
|
841
866
|
* @returns `true` se a opção estiver selecionada, caso contrário `false`.
|
|
842
867
|
*/
|
|
843
868
|
isOptionSelected(option) {
|
|
869
|
+
// No modo simples a seleção fica em `value()`; `values()` só é usado no modo múltiplo.
|
|
870
|
+
// Sem isso, a opção escolhida nunca aparecia marcada ao reabrir a lista (o que importa
|
|
871
|
+
// principalmente no modo somente leitura, cujo objetivo é consultar o que está selecionado).
|
|
872
|
+
if (!this.multiple()) {
|
|
873
|
+
return this.value()?.id === option.id;
|
|
874
|
+
}
|
|
844
875
|
return (this.values().find((o) => {
|
|
845
876
|
return o === option;
|
|
846
877
|
}) !== undefined);
|
|
@@ -852,7 +883,11 @@ class SelectComponent {
|
|
|
852
883
|
* Após a alteração, notifica a mudança de valor.
|
|
853
884
|
*/
|
|
854
885
|
toggleSelectAll() {
|
|
855
|
-
if (!this.multiple()) {
|
|
886
|
+
if (!this.multiple() || this.disabled()) {
|
|
887
|
+
return;
|
|
888
|
+
}
|
|
889
|
+
if (this.readonly()) {
|
|
890
|
+
this._announceReadonly();
|
|
856
891
|
return;
|
|
857
892
|
}
|
|
858
893
|
const options = this.filteredOptions().filter((option) => !option.grouper);
|
|
@@ -1124,13 +1159,13 @@ class SelectComponent {
|
|
|
1124
1159
|
}
|
|
1125
1160
|
}
|
|
1126
1161
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1127
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SelectComponent, isStandalone: true, selector: "s-select", inputs: { placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, optionLabel: { classPropertyName: "optionLabel", publicName: "optionLabel", isSignal: true, isRequired: false, transformFunction: null }, optionValue: { classPropertyName: "optionValue", publicName: "optionValue", isSignal: true, isRequired: false, transformFunction: null }, showClear: { classPropertyName: "showClear", publicName: "showClear", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, checkmark: { classPropertyName: "checkmark", publicName: "checkmark", isSignal: true, isRequired: false, transformFunction: null }, checkIconClass: { classPropertyName: "checkIconClass", publicName: "checkIconClass", isSignal: true, isRequired: false, transformFunction: null }, filterBy: { classPropertyName: "filterBy", publicName: "filterBy", isSignal: true, isRequired: false, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: false, transformFunction: null }, virtualScroll: { classPropertyName: "virtualScroll", publicName: "virtualScroll", isSignal: true, isRequired: false, transformFunction: null }, virtualScrollItemSize: { classPropertyName: "virtualScrollItemSize", publicName: "virtualScrollItemSize", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, showOptions: { classPropertyName: "showOptions", publicName: "showOptions", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledBy: { classPropertyName: "ariaLabelledBy", publicName: "ariaLabelledBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { disabled: "disabledChange", showOptions: "showOptionsChange" }, host: { listeners: { "window:resize": "onWindowResize($event)" } }, providers: [
|
|
1162
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SelectComponent, isStandalone: true, selector: "s-select", inputs: { placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, optionLabel: { classPropertyName: "optionLabel", publicName: "optionLabel", isSignal: true, isRequired: false, transformFunction: null }, optionValue: { classPropertyName: "optionValue", publicName: "optionValue", isSignal: true, isRequired: false, transformFunction: null }, showClear: { classPropertyName: "showClear", publicName: "showClear", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, checkmark: { classPropertyName: "checkmark", publicName: "checkmark", isSignal: true, isRequired: false, transformFunction: null }, checkIconClass: { classPropertyName: "checkIconClass", publicName: "checkIconClass", isSignal: true, isRequired: false, transformFunction: null }, filterBy: { classPropertyName: "filterBy", publicName: "filterBy", isSignal: true, isRequired: false, transformFunction: null }, group: { classPropertyName: "group", publicName: "group", isSignal: true, isRequired: false, transformFunction: null }, virtualScroll: { classPropertyName: "virtualScroll", publicName: "virtualScroll", isSignal: true, isRequired: false, transformFunction: null }, virtualScrollItemSize: { classPropertyName: "virtualScrollItemSize", publicName: "virtualScrollItemSize", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, showOptions: { classPropertyName: "showOptions", publicName: "showOptions", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledBy: { classPropertyName: "ariaLabelledBy", publicName: "ariaLabelledBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { disabled: "disabledChange", showOptions: "showOptionsChange" }, host: { listeners: { "window:resize": "onWindowResize($event)" } }, providers: [
|
|
1128
1163
|
{
|
|
1129
1164
|
provide: NG_VALUE_ACCESSOR,
|
|
1130
1165
|
useExisting: forwardRef(() => SelectComponent),
|
|
1131
1166
|
multi: true,
|
|
1132
1167
|
},
|
|
1133
|
-
], 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, read: ElementRef, isSignal: true }, { propertyName: "_dropdownPanel", first: true, predicate: ["dropdownPanel"], 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-medium border outline-2 outline-[var(--s-focus-ring-color,#0090ff)] outline-offset-[-2px] focus-visible: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-[10px] 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 (keydown)=\"$event.stopPropagation()\"\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 w-9 shrink-0 items-center justify-center border-l group-hover:bg-grayscale-5\"\n [class.border-grayscale-20]=\"disabled()\"\n [class.border-grayscale-30]=\"!disabled()\"\n >\n <i\n class=\"fas text-base\"\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)=\"_closeDropdown()\"\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n (attach)=\"_syncPanelWidth()\"\n (detach)=\"_closeDropdown()\"\n>\n <div\n #dropdownPanel\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]=\"panelWidth()\"\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 [ariaLabel]=\"selectAllCheckboxAriaLabel()\"\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 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-[var(--s-focus-ring-color,#0090ff)]\"\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 (keydown)=\"onClearFilterButtonKeyDown($event)\"\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 role=\"presentation\"\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 [checkIconClass]=\"checkIconClass()\"\n [isSelected]=\"isOptionSelected(option)\"\n (selected)=\"selectItem(option)\"\n [isGrouper]=\"option.grouper ?? false\"\n [isFocused]=\"option.data === focusedItem()\"\n [groupAnnouncement]=\"groupAnnouncementFor(option.id)\"\n [posinset]=\"optionPosinsetFor(option.id)\"\n [setsize]=\"optionSetsizeFor(option.id)\"\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\n class=\"max-h-52 overflow-auto\"\n role=\"presentation\"\n >\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 [checkIconClass]=\"checkIconClass()\"\n [isSelected]=\"isOptionSelected(option)\"\n (selected)=\"selectItem(option)\"\n [isGrouper]=\"option.grouper ?? false\"\n [isFocused]=\"option.data === focusedItem()\"\n [groupAnnouncement]=\"groupAnnouncementFor(option.id)\"\n [posinset]=\"optionPosinsetFor(option.id)\"\n [setsize]=\"optionSetsizeFor(option.id)\"\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 .select-container:not(:focus-within){&,.dropdown-container{border-color:#c13018}}\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", "checkIconClass", "groupAnnouncement", "posinset", "setsize"], 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: [
|
|
1168
|
+
], 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, read: ElementRef, isSignal: true }, { propertyName: "_dropdownPanel", first: true, predicate: ["dropdownPanel"], 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-medium border outline-2 outline-[var(--s-focus-ring-color,#0090ff)] outline-offset-[-2px] focus-visible:outline\"\n [class.pointer-events-none]=\"disabled()\"\n [class.border-grayscale-20]=\"disabled() || readonly()\"\n [class.bg-grayscale-5]=\"disabled()\"\n [class.pointer-events-auto]=\"!disabled()\"\n [class.border-grayscale-30]=\"!disabled() && !readonly()\"\n [class.bg-grayscale-0]=\"!disabled()\"\n [attr.aria-disabled]=\"disabled()\"\n [attr.aria-readonly]=\"readonly() && !disabled() ? true : null\"\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-[10px] 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() && !readonly() && showClear() && !isClean()) {\n <button\n class=\"mx-3\"\n (click)=\"clear($event)\"\n (keydown)=\"$event.stopPropagation()\"\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 w-9 shrink-0 items-center justify-center border-l\"\n [class.group-hover:bg-grayscale-5]=\"!readonly()\"\n [class.border-grayscale-20]=\"disabled() || readonly()\"\n [class.border-grayscale-30]=\"!disabled() && !readonly()\"\n >\n <i\n class=\"fas text-base\"\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)=\"_closeDropdown()\"\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n (attach)=\"_syncPanelWidth()\"\n (detach)=\"_closeDropdown()\"\n>\n <div\n #dropdownPanel\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]=\"panelWidth()\"\n [attr.aria-multiselectable]=\"multiple() ? true : null\"\n [attr.aria-readonly]=\"readonly() ? 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 [disabled]=\"readonly()\"\n [ariaLabel]=\"selectAllCheckboxAriaLabel()\"\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 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-[var(--s-focus-ring-color,#0090ff)]\"\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 (keydown)=\"onClearFilterButtonKeyDown($event)\"\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 role=\"presentation\"\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 [readonly]=\"readonly()\"\n [checkmark]=\"checkmark()\"\n [checkIconClass]=\"checkIconClass()\"\n [isSelected]=\"isOptionSelected(option)\"\n (selected)=\"selectItem(option)\"\n [isGrouper]=\"option.grouper ?? false\"\n [isFocused]=\"option.data === focusedItem()\"\n [groupAnnouncement]=\"groupAnnouncementFor(option.id)\"\n [posinset]=\"optionPosinsetFor(option.id)\"\n [setsize]=\"optionSetsizeFor(option.id)\"\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\n class=\"max-h-52 overflow-auto\"\n role=\"presentation\"\n >\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 [readonly]=\"readonly()\"\n [checkmark]=\"checkmark()\"\n [checkIconClass]=\"checkIconClass()\"\n [isSelected]=\"isOptionSelected(option)\"\n (selected)=\"selectItem(option)\"\n [isGrouper]=\"option.grouper ?? false\"\n [isFocused]=\"option.data === focusedItem()\"\n [groupAnnouncement]=\"groupAnnouncementFor(option.id)\"\n [posinset]=\"optionPosinsetFor(option.id)\"\n [setsize]=\"optionSetsizeFor(option.id)\"\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 .select-container:not(:focus-within){&,.dropdown-container{border-color:#c13018}}\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", "readonly", "isSelected", "checkIconClass", "groupAnnouncement", "posinset", "setsize"], 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: [
|
|
1134
1169
|
trigger('visibilityChanged', [
|
|
1135
1170
|
state('void', style({ opacity: 0, transform: 'scale(0.95)' })),
|
|
1136
1171
|
transition(':enter', [
|
|
@@ -1169,7 +1204,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
1169
1204
|
animate('500ms cubic-bezier(0.4, 0, 0.2, 1)', style({ opacity: 0, transform: 'scale(0.95)' })),
|
|
1170
1205
|
]),
|
|
1171
1206
|
]),
|
|
1172
|
-
], template: "<div\n #containerDiv\n cdkOverlayOrigin\n #trigger=\"cdkOverlayOrigin\"\n class=\"select-container group flex h-[35px] w-full overflow-hidden rounded-medium border outline-2 outline-[var(--s-focus-ring-color,#0090ff)] outline-offset-[-2px] focus-visible: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-[10px] 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 (keydown)=\"$event.stopPropagation()\"\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 w-9 shrink-0 items-center justify-center border-l
|
|
1207
|
+
], template: "<div\n #containerDiv\n cdkOverlayOrigin\n #trigger=\"cdkOverlayOrigin\"\n class=\"select-container group flex h-[35px] w-full overflow-hidden rounded-medium border outline-2 outline-[var(--s-focus-ring-color,#0090ff)] outline-offset-[-2px] focus-visible:outline\"\n [class.pointer-events-none]=\"disabled()\"\n [class.border-grayscale-20]=\"disabled() || readonly()\"\n [class.bg-grayscale-5]=\"disabled()\"\n [class.pointer-events-auto]=\"!disabled()\"\n [class.border-grayscale-30]=\"!disabled() && !readonly()\"\n [class.bg-grayscale-0]=\"!disabled()\"\n [attr.aria-disabled]=\"disabled()\"\n [attr.aria-readonly]=\"readonly() && !disabled() ? true : null\"\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-[10px] 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() && !readonly() && showClear() && !isClean()) {\n <button\n class=\"mx-3\"\n (click)=\"clear($event)\"\n (keydown)=\"$event.stopPropagation()\"\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 w-9 shrink-0 items-center justify-center border-l\"\n [class.group-hover:bg-grayscale-5]=\"!readonly()\"\n [class.border-grayscale-20]=\"disabled() || readonly()\"\n [class.border-grayscale-30]=\"!disabled() && !readonly()\"\n >\n <i\n class=\"fas text-base\"\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)=\"_closeDropdown()\"\n cdkConnectedOverlayBackdropClass=\"cdk-overlay-transparent-backdrop\"\n (attach)=\"_syncPanelWidth()\"\n (detach)=\"_closeDropdown()\"\n>\n <div\n #dropdownPanel\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]=\"panelWidth()\"\n [attr.aria-multiselectable]=\"multiple() ? true : null\"\n [attr.aria-readonly]=\"readonly() ? 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 [disabled]=\"readonly()\"\n [ariaLabel]=\"selectAllCheckboxAriaLabel()\"\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 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-[var(--s-focus-ring-color,#0090ff)]\"\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 (keydown)=\"onClearFilterButtonKeyDown($event)\"\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 role=\"presentation\"\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 [readonly]=\"readonly()\"\n [checkmark]=\"checkmark()\"\n [checkIconClass]=\"checkIconClass()\"\n [isSelected]=\"isOptionSelected(option)\"\n (selected)=\"selectItem(option)\"\n [isGrouper]=\"option.grouper ?? false\"\n [isFocused]=\"option.data === focusedItem()\"\n [groupAnnouncement]=\"groupAnnouncementFor(option.id)\"\n [posinset]=\"optionPosinsetFor(option.id)\"\n [setsize]=\"optionSetsizeFor(option.id)\"\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\n class=\"max-h-52 overflow-auto\"\n role=\"presentation\"\n >\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 [readonly]=\"readonly()\"\n [checkmark]=\"checkmark()\"\n [checkIconClass]=\"checkIconClass()\"\n [isSelected]=\"isOptionSelected(option)\"\n (selected)=\"selectItem(option)\"\n [isGrouper]=\"option.grouper ?? false\"\n [isFocused]=\"option.data === focusedItem()\"\n [groupAnnouncement]=\"groupAnnouncementFor(option.id)\"\n [posinset]=\"optionPosinsetFor(option.id)\"\n [setsize]=\"optionSetsizeFor(option.id)\"\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 .select-container:not(:focus-within){&,.dropdown-container{border-color:#c13018}}\n"] }]
|
|
1173
1208
|
}], ctorParameters: () => [] });
|
|
1174
1209
|
|
|
1175
1210
|
/**
|