@seniorsistemas/angular-components 19.10.0 → 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.
Files changed (27) hide show
  1. package/dynamic-form/dynamic-form/form-field/configurations/fields/select-field.d.ts +6 -0
  2. package/esm2022/dynamic-form/dynamic-form/form-field/configurations/fields/select-field.mjs +1 -1
  3. package/esm2022/dynamic-form/dynamic-form/form-field/fields/select/select-field.component.mjs +3 -3
  4. package/esm2022/lib/locale/fallback.mjs +2 -1
  5. package/esm2022/locale/lib/locale/locale.service.mjs +7 -30
  6. package/esm2022/locale/lib/locale/options/locale-presets.mjs +199 -0
  7. package/esm2022/locale/public-api.mjs +2 -1
  8. package/esm2022/paginator/lib/paginator/paginator.component.mjs +2 -2
  9. package/esm2022/select/lib/select/components/select-option/select-option.component.mjs +6 -4
  10. package/esm2022/select/lib/select/select.component.mjs +41 -8
  11. package/fesm2022/seniorsistemas-angular-components-dynamic-form.mjs +2 -2
  12. package/fesm2022/seniorsistemas-angular-components-dynamic-form.mjs.map +1 -1
  13. package/fesm2022/seniorsistemas-angular-components-locale.mjs +203 -29
  14. package/fesm2022/seniorsistemas-angular-components-locale.mjs.map +1 -1
  15. package/fesm2022/seniorsistemas-angular-components-paginator.mjs +1 -1
  16. package/fesm2022/seniorsistemas-angular-components-paginator.mjs.map +1 -1
  17. package/fesm2022/seniorsistemas-angular-components-select.mjs +45 -10
  18. package/fesm2022/seniorsistemas-angular-components-select.mjs.map +1 -1
  19. package/fesm2022/seniorsistemas-angular-components.mjs +1 -0
  20. package/fesm2022/seniorsistemas-angular-components.mjs.map +1 -1
  21. package/locale/lib/locale/locale.service.d.ts +0 -3
  22. package/locale/lib/locale/options/locale-presets.d.ts +22 -0
  23. package/locale/public-api.d.ts +1 -0
  24. package/package.json +1 -1
  25. package/select/README.md +18 -0
  26. package/select/lib/select/components/select-option/select-option.component.d.ts +3 -1
  27. package/select/lib/select/select.component.d.ts +17 -2
@@ -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
- if (this.multiple()) {
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 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"] }]
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
  /**