ngx-sp-infra 6.22.8 → 6.22.9

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.
@@ -8011,28 +8011,50 @@ class LibComboboxReworkComponent {
8011
8011
  this._onChange(this.formatReturn(val)); // Notifica o FormControl sobre a mudança
8012
8012
  }
8013
8013
  }
8014
+ // Getter para quantidade de registros selecionados
8015
+ get selectedCount() {
8016
+ if (!this.multiple || !Array.isArray(this.value))
8017
+ return 0;
8018
+ return this.value.length;
8019
+ }
8014
8020
  displayValue() {
8015
8021
  if (!this.value)
8016
8022
  return '';
8017
- if (Array.isArray(this.value)) {
8018
- if (this.value.length === 0)
8019
- return '';
8020
- let extraSelected = 0;
8021
- this.value.forEach((e, index) => {
8022
- if (index >= 2)
8023
- extraSelected++;
8024
- });
8025
- // Filtra o valor para exibir até dois valores selecionados, se passar disso mostra "e +{n} selecionado(s)"
8026
- return this.value.map((e, index) => {
8027
- if (index < 2)
8028
- return this.displayWith(e);
8029
- return null;
8030
- })
8031
- .filter(e => e !== null)
8032
- .join(', ') + (extraSelected > 0 ? ` e +${extraSelected} selecionado(s)` : '');
8023
+ if (this.multiple) {
8024
+ if (Array.isArray(this.value) && this.value.length === this.list.length) {
8025
+ return `Todas ${this.list.length} opções marcadas`;
8026
+ }
8027
+ else if (this.showCountBadge && Array.isArray(this.value)) {
8028
+ return this.value
8029
+ .slice(0, 2)
8030
+ .map(v => this.displayWith(v))
8031
+ .join(', ');
8032
+ }
8033
+ else if (Array.isArray(this.value)) {
8034
+ if (this.value.length === 0)
8035
+ return '';
8036
+ let extraSelected = 0;
8037
+ this.value.forEach((e, index) => {
8038
+ if (index >= 2)
8039
+ extraSelected++;
8040
+ });
8041
+ // Filtra o valor para exibir até dois valores selecionados, se passar disso mostra "e +{n} selecionado(s)"
8042
+ return this.value.map((e, index) => {
8043
+ if (index < 2)
8044
+ return this.displayWith(e);
8045
+ return null;
8046
+ })
8047
+ .filter(e => e !== null)
8048
+ .join(', ') + (extraSelected > 0 ? ` e +${extraSelected} selecionado(s)` : '');
8049
+ }
8033
8050
  }
8034
8051
  return this.displayWith(this.value);
8035
8052
  }
8053
+ getItemProperty(item, property) {
8054
+ if (item === null || item === undefined || typeof item !== 'object')
8055
+ return undefined;
8056
+ return item[property];
8057
+ }
8036
8058
  // #endregion PUBLIC
8037
8059
  // #endregion ==========> PROPERTIES <==========
8038
8060
  constructor(_cdr, _elementRef) {
@@ -8055,6 +8077,7 @@ class LibComboboxReworkComponent {
8055
8077
  this.innerFilter = true;
8056
8078
  this.customLabel = "LABEL";
8057
8079
  this.customValue = "ID";
8080
+ this.showCountBadge = false;
8058
8081
  this.selectionChange = new EventEmitter();
8059
8082
  this.filterChange = new EventEmitter();
8060
8083
  this.filterButtonClick = new EventEmitter();
@@ -8320,13 +8343,13 @@ class LibComboboxReworkComponent {
8320
8343
  this._cdr.markForCheck();
8321
8344
  }
8322
8345
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: LibComboboxReworkComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
8323
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: LibComboboxReworkComponent, isStandalone: true, selector: "lib-combobox-rework", inputs: { list: "list", placeholder: "placeholder", searchPlaceholder: "searchPlaceholder", noResultsText: "noResultsText", disabled: "disabled", multiple: "multiple", innerFilter: "innerFilter", customLabel: "customLabel", customValue: "customValue" }, outputs: { selectionChange: "selectionChange", filterChange: "filterChange", filterButtonClick: "filterButtonClick" }, host: { listeners: { "window:resize": "onResize($event)" } }, providers: [
8346
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: LibComboboxReworkComponent, isStandalone: true, selector: "lib-combobox-rework", inputs: { list: "list", placeholder: "placeholder", searchPlaceholder: "searchPlaceholder", noResultsText: "noResultsText", disabled: "disabled", multiple: "multiple", innerFilter: "innerFilter", customLabel: "customLabel", customValue: "customValue", showCountBadge: "showCountBadge" }, outputs: { selectionChange: "selectionChange", filterChange: "filterChange", filterButtonClick: "filterButtonClick" }, host: { listeners: { "window:resize": "onResize($event)" } }, providers: [
8324
8347
  {
8325
8348
  provide: NG_VALUE_ACCESSOR,
8326
8349
  useExisting: forwardRef(() => LibComboboxReworkComponent),
8327
8350
  multi: true
8328
8351
  }
8329
- ], queries: [{ propertyName: "optionTemplate", first: true, predicate: ["optionTemplate"], descendants: true, read: TemplateRef }, { propertyName: "leftButtonTemplate", first: true, predicate: ["leftButtonTemplate"], descendants: true, read: TemplateRef }, { propertyName: "rightButtonTemplate", first: true, predicate: ["rightButtonTemplate"], descendants: true, read: TemplateRef }], viewQueries: [{ propertyName: "toggleButton", first: true, predicate: ["toggleButton"], descendants: true, static: true }, { propertyName: "dropdownMenu", first: true, predicate: ["dropdownMenu"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"reusable-combobox input-group\" [class.show]=\"isOpen\" (focusout)=\"onBlurOutside($event)\" >\n @if (leftButtonTemplate) { <ng-container *ngTemplateOutlet=\"leftButtonTemplate\"></ng-container> }\n\n <div class=\"dropdown w-100\">\n\n <input #toggleButton id=\"toggle-button\" class=\"form-select d-flex align-items-center text-start w-100 overflow-hidden text-truncate glb-cursor-pointer\" data-bs-toggle=\"dropdown\"\n data-bs-auto-close=\"outside\" [attr.aria-expanded]=\"isOpen\" [attr.aria-haspopup]=\"true\" [attr.aria-label]=\"placeholder\" [class.disabled]=\"disabled\"\n [class.is-invalid]=\"invalid\" (click)=\"toggleDropdown()\" [value]=\"displayValue()\" [placeholder]=\"placeholder\" readonly\n [ngClass]=\"{\n 'rounded-start-0': leftButtonTemplate,\n 'rounded-end-0': rightButtonTemplate,\n }\" />\n\n <div #dropdownMenu class=\"dropdown-menu p-2 w-100\" [class.show]=\"isOpen\" style=\"max-height: 320px; overflow-y: auto;\" >\n <div class=\"sticky-header rounded p-3\">\n <div class=\"dropdown-search input-group\">\n <input class=\"form-control form-control-sm\" type=\"search\" [placeholder]=\"searchPlaceholder\" [formControl]=\"searchControl\" aria-label=\"Pesquisar op\u00E7\u00F5es\" (keyup.enter)=\"filterButtonClick.emit(searchControl.value)\" />\n <button class=\"btn btn-sm btn-primary\" type=\"button\" (click)=\"filterButtonClick.emit(searchControl.value)\"> <lib-icon iconName=\"lupa\" iconSize=\"medium-small\" /> </button>\n </div>\n \n @if (multiple && selectedValues?.length) {\n <div class=\"d-flex flex-row gap-2 flex-wrap my-2\">\n <span *ngFor=\"let value of selectedValues; trackBy: trackByFn\" class=\"px-3 badge rounded-pill text-primary bg-primary-subtle\">\n {{ value[customLabel] }} <lib-icon class=\"glb-cursor-pointer\" iconName=\"fechar\" iconSize=\"small\" (click)=\"select(value, true)\" />\n </span>\n </div>\n }\n </div>\n\n <!-- Se utilizar o filtro interno utiliza a propriedade de lista filteredItems$, caso contr\u00E1rio usa a pr\u00F3pria list pois ela ser\u00E1 filtrada pelo componente pai -->\n <ng-container *ngIf=\"(innerFilter ? (filteredItems$ | async) : list) as items\">\n @if (items.length === 0) { <div class=\"py-2 px-3 text-muted small\">{{ noResultsText }}</div> }\n\n @if (value !== '' && value !== null) {\n <button type=\"button\" class=\"dropdown-item d-flex align-items-center\" (click)=\"writeValue(null)\">\n <span class=\"fw-bold\">Limpar {{ multiple ? 'op\u00E7\u00F5es selecionadas' : 'op\u00E7\u00E3o selecionada' }}</span>\n </button>\n }\n\n <button *ngFor=\"let item of items; trackBy: trackByFn\" class=\"dropdown-item d-flex align-items-center\" type=\"button\"\n (click)=\"select(item, true)\" [attr.aria-selected]=\"isSelected(item)\" >\n\n @if (optionTemplate) {\n <ng-container *ngTemplateOutlet=\"optionTemplate; context: { $implicit: item, selected: isSelected(item) }\"></ng-container>\n }\n @else {\n <div class=\"w-100 original\">\n <div class=\"d-flex justify-content-between\">\n <div [ngClass]=\"{ 'text-primary fw-bold': isSelected(item) }\">\n <!-- Se o valor do ID e do LABEL for vazio exibe apenas um risquinho para identificar que h\u00E1 uma op\u00E7\u00E3o ali -->\n @if ((item[customLabel] ?? item[customValue]) === '') {\n <span class=\"fst-italic text-muted\">Nenhum t\u00EDtulo informado para esta op\u00E7\u00E3o</span>\n }\n @else {\n {{ (item[customLabel] ?? item[customValue]) }}\n }\n </div>\n </div>\n </div>\n }\n </button>\n </ng-container>\n </div>\n </div>\n\n @if (rightButtonTemplate) { <ng-container *ngTemplateOutlet=\"rightButtonTemplate\"></ng-container> }\n</div>", styles: [".reusable-combobox{position:relative;display:flex;flex-wrap:nowrap;width:100%;max-width:100%}.reusable-combobox #toggle-button{box-sizing:border-box}.reusable-combobox .dropdown-menu{width:100%;box-shadow:0 6px 18px #00000014;border-radius:.5rem}.reusable-combobox .sticky-header{position:sticky;top:0;z-index:10;background:#f1f5f9;box-shadow:0 2px 4px #00000014}.reusable-combobox .dropdown-item{cursor:pointer;border-radius:6px;transition:all .3s ease}.reusable-combobox .dropdown-item:hover:not(:focus){background-color:#f1f5f9}.reusable-combobox.compact .dropdown-menu{max-height:200px}.bg-primary-subtle{background-color:#d1dfe7!important}::-webkit-scrollbar{width:4px;background:transparent}::-webkit-scrollbar-thumb{background:#bbb;border-radius:16px}.disabled{background-color:#e9ecef!important}.dropdown-item{min-height:32px!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1$6.AsyncPipe, name: "async" }, { kind: "ngmodule", type: FormsModule }, { 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: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: LibIconsComponent, selector: "lib-icon", inputs: ["iconName", "iconColor", "iconSize", "iconFill"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8352
+ ], queries: [{ propertyName: "optionTemplate", first: true, predicate: ["optionTemplate"], descendants: true, read: TemplateRef }, { propertyName: "leftButtonTemplate", first: true, predicate: ["leftButtonTemplate"], descendants: true, read: TemplateRef }, { propertyName: "rightButtonTemplate", first: true, predicate: ["rightButtonTemplate"], descendants: true, read: TemplateRef }], viewQueries: [{ propertyName: "toggleButton", first: true, predicate: ["toggleButton"], descendants: true, static: true }, { propertyName: "dropdownMenu", first: true, predicate: ["dropdownMenu"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"reusable-combobox input-group\" [class.show]=\"isOpen\" (focusout)=\"onBlurOutside($event)\" >\n @if (leftButtonTemplate) { <ng-container *ngTemplateOutlet=\"leftButtonTemplate\"></ng-container> }\n\n <div class=\"dropdown w-100\">\n\n <div class=\"position-relative\">\n <input #toggleButton id=\"toggle-button\" class=\"form-select d-flex align-items-center text-start w-100 overflow-hidden text-truncate glb-cursor-pointer\" data-bs-toggle=\"dropdown\"\n data-bs-auto-close=\"outside\" [attr.aria-expanded]=\"isOpen\" [attr.aria-haspopup]=\"true\" [attr.aria-label]=\"placeholder\" [class.disabled]=\"disabled\"\n [class.is-invalid]=\"invalid\" (click)=\"toggleDropdown()\" [value]=\"displayValue()\" [placeholder]=\"placeholder\" readonly\n [class.with-selection-badge]=\"showCountBadge && multiple && selectedCount > 0\"\n [ngClass]=\"{\n 'rounded-start-0': leftButtonTemplate,\n 'rounded-end-0': rightButtonTemplate,\n }\" />\n\n @if (showCountBadge && multiple && selectedCount > 0) { <span class=\"selection-count-badge\" [tooltip]=\"'Total de ' + selectedCount + ' registros selecionados'\"> {{ selectedCount }} </span> }\n </div>\n\n\n <div #dropdownMenu class=\"dropdown-menu p-2 w-100\" [class.show]=\"isOpen\" style=\"max-height: 400px; overflow-y: auto;\" >\n <div class=\"sticky-header rounded p-3\">\n <div class=\"dropdown-search input-group\">\n <input class=\"form-control form-control-sm\" type=\"search\" [placeholder]=\"searchPlaceholder\" [formControl]=\"searchControl\" aria-label=\"Pesquisar op\u00E7\u00F5es\" (keyup.enter)=\"filterButtonClick.emit(searchControl.value)\" />\n <button class=\"btn btn-sm btn-primary\" type=\"button\" (click)=\"filterButtonClick.emit(searchControl.value)\"> <lib-icon iconName=\"lupa\" iconSize=\"medium-small\" /> </button>\n </div>\n\n @if (multiple && selectedValues?.length) {\n <div class=\"selected-options-badges d-flex flex-row gap-2 mt-2 py-2 overflow-x-scroll\">\n @for (value of selectedValues; track $index) {\n <span class=\"px-3 badge rounded-pill text-primary-emphasis bg-primary-subtle\">\n {{ getItemProperty(value, customLabel) }} <lib-icon class=\"glb-cursor-pointer\" iconName=\"fechar\" iconSize=\"small\" (click)=\"select(value, true)\" />\n </span>\n }\n </div>\n }\n </div>\n\n <!-- Se utilizar o filtro interno utiliza a propriedade de lista filteredItems$, caso contr\u00E1rio usa a pr\u00F3pria list pois ela ser\u00E1 filtrada pelo componente pai -->\n @let filteredItems = innerFilter ? (filteredItems$ | async) : list;\n @if (filteredItems) {\n @if (filteredItems.length === 0) { <div class=\"py-2 px-3 text-muted small\">{{ noResultsText }}</div> }\n\n @if (value !== '' && value !== null) {\n <button type=\"button\" class=\"dropdown-item d-flex align-items-center my-2 py-2 border-bottom border-secondary-subtle rounded-bottom-0\" (click)=\"writeValue(null)\"\n tooltip=\"Limpa todas as op\u00E7\u00F5es selecionadas\">\n <span class=\"fw-bold\">Limpar {{ multiple ? 'op\u00E7\u00F5es selecionadas' : 'op\u00E7\u00E3o selecionada' }}</span>\n </button>\n }\n @else if (multiple) {\n <button type=\"button\" class=\"dropdown-item d-flex align-items-center my-2 py-2 border-bottom border-secondary-subtle rounded-bottom-0\" (click)=\"writeValue(list)\" tooltip=\"Seleciona todas as op\u00E7\u00F5es dispon\u00EDveis\">\n <span class=\"fw-bold\">Selecionar tudo ({{ list.length }} op\u00E7\u00F5es)</span>\n </button>\n }\n\n @for (item of filteredItems; track item) {\n <button class=\"dropdown-item d-flex align-items-center\" type=\"button\"\n (click)=\"select(item, true)\" [attr.aria-selected]=\"isSelected(item)\" >\n\n @if (optionTemplate) {\n <ng-container *ngTemplateOutlet=\"optionTemplate; context: { $implicit: item, selected: isSelected(item) }\"></ng-container>\n }\n @else {\n <div class=\"w-100 original\">\n <div class=\"d-flex justify-content-between\">\n <div [ngClass]=\"{ 'text-primary fw-bold': isSelected(item) }\">\n <!-- Se o valor do ID e do LABEL for vazio exibe apenas um risquinho para identificar que h\u00E1 uma op\u00E7\u00E3o ali -->\n @if ((getItemProperty(item, customLabel) ?? getItemProperty(item, customValue)) === '') {\n <span class=\"fst-italic text-muted\">Nenhum t\u00EDtulo informado para esta op\u00E7\u00E3o</span>\n }\n @else {\n {{ (getItemProperty(item, customLabel) ?? getItemProperty(item, customValue)) }}\n }\n </div>\n </div>\n </div>\n }\n </button>\n }\n }\n </div>\n </div>\n\n @if (rightButtonTemplate) { <ng-container *ngTemplateOutlet=\"rightButtonTemplate\"></ng-container> }\n</div>", styles: [".reusable-combobox{position:relative;display:flex;flex-wrap:nowrap;width:100%;max-width:100%}.reusable-combobox #toggle-button{box-sizing:border-box}.reusable-combobox .selection-count-badge{position:absolute;top:50%;right:2.75rem;transform:translateY(-50%);min-width:24px;height:24px;padding:0 8px;display:flex;align-items:center;justify-content:center;border-radius:6px;background-color:#dce1e6;color:#495057;font-size:.75rem;font-weight:600;pointer-events:none}.reusable-combobox .with-selection-badge{padding-right:5rem!important}.reusable-combobox .dropdown-menu{width:100%;box-shadow:0 6px 18px #00000014;border-radius:.5rem}.reusable-combobox .sticky-header{position:sticky;top:0;z-index:10;background:#f1f5f9;box-shadow:0 2px 4px #00000014}.reusable-combobox .dropdown-item{cursor:pointer;border-radius:6px;transition:all .3s ease}.reusable-combobox .dropdown-item:hover:not(:focus){background-color:#f1f5f9}.reusable-combobox.compact .dropdown-menu{max-height:350px}::-webkit-scrollbar{width:4px;background:transparent}::-webkit-scrollbar-thumb{background:var(--bs-secondary);border-radius:16px}.disabled{background-color:#e9ecef!important}.dropdown-item{min-height:32px!important}.selected-options-badges::-webkit-scrollbar{height:3px;background:var(--bs-primary-bg-subtle)}.selected-options-badges::-webkit-scrollbar-thumb{background:var(--bs-primary);border-radius:8px;height:3px;cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1$6.AsyncPipe, name: "async" }, { kind: "ngmodule", type: FormsModule }, { 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: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: LibIconsComponent, selector: "lib-icon", inputs: ["iconName", "iconColor", "iconSize", "iconFill"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i1$4.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8330
8353
  }
8331
8354
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: LibComboboxReworkComponent, decorators: [{
8332
8355
  type: Component,
@@ -8334,14 +8357,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
8334
8357
  CommonModule,
8335
8358
  FormsModule,
8336
8359
  ReactiveFormsModule,
8337
- LibIconsComponent
8360
+ LibIconsComponent,
8361
+ TooltipModule
8338
8362
  ], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
8339
8363
  {
8340
8364
  provide: NG_VALUE_ACCESSOR,
8341
8365
  useExisting: forwardRef(() => LibComboboxReworkComponent),
8342
8366
  multi: true
8343
8367
  }
8344
- ], template: "<div class=\"reusable-combobox input-group\" [class.show]=\"isOpen\" (focusout)=\"onBlurOutside($event)\" >\n @if (leftButtonTemplate) { <ng-container *ngTemplateOutlet=\"leftButtonTemplate\"></ng-container> }\n\n <div class=\"dropdown w-100\">\n\n <input #toggleButton id=\"toggle-button\" class=\"form-select d-flex align-items-center text-start w-100 overflow-hidden text-truncate glb-cursor-pointer\" data-bs-toggle=\"dropdown\"\n data-bs-auto-close=\"outside\" [attr.aria-expanded]=\"isOpen\" [attr.aria-haspopup]=\"true\" [attr.aria-label]=\"placeholder\" [class.disabled]=\"disabled\"\n [class.is-invalid]=\"invalid\" (click)=\"toggleDropdown()\" [value]=\"displayValue()\" [placeholder]=\"placeholder\" readonly\n [ngClass]=\"{\n 'rounded-start-0': leftButtonTemplate,\n 'rounded-end-0': rightButtonTemplate,\n }\" />\n\n <div #dropdownMenu class=\"dropdown-menu p-2 w-100\" [class.show]=\"isOpen\" style=\"max-height: 320px; overflow-y: auto;\" >\n <div class=\"sticky-header rounded p-3\">\n <div class=\"dropdown-search input-group\">\n <input class=\"form-control form-control-sm\" type=\"search\" [placeholder]=\"searchPlaceholder\" [formControl]=\"searchControl\" aria-label=\"Pesquisar op\u00E7\u00F5es\" (keyup.enter)=\"filterButtonClick.emit(searchControl.value)\" />\n <button class=\"btn btn-sm btn-primary\" type=\"button\" (click)=\"filterButtonClick.emit(searchControl.value)\"> <lib-icon iconName=\"lupa\" iconSize=\"medium-small\" /> </button>\n </div>\n \n @if (multiple && selectedValues?.length) {\n <div class=\"d-flex flex-row gap-2 flex-wrap my-2\">\n <span *ngFor=\"let value of selectedValues; trackBy: trackByFn\" class=\"px-3 badge rounded-pill text-primary bg-primary-subtle\">\n {{ value[customLabel] }} <lib-icon class=\"glb-cursor-pointer\" iconName=\"fechar\" iconSize=\"small\" (click)=\"select(value, true)\" />\n </span>\n </div>\n }\n </div>\n\n <!-- Se utilizar o filtro interno utiliza a propriedade de lista filteredItems$, caso contr\u00E1rio usa a pr\u00F3pria list pois ela ser\u00E1 filtrada pelo componente pai -->\n <ng-container *ngIf=\"(innerFilter ? (filteredItems$ | async) : list) as items\">\n @if (items.length === 0) { <div class=\"py-2 px-3 text-muted small\">{{ noResultsText }}</div> }\n\n @if (value !== '' && value !== null) {\n <button type=\"button\" class=\"dropdown-item d-flex align-items-center\" (click)=\"writeValue(null)\">\n <span class=\"fw-bold\">Limpar {{ multiple ? 'op\u00E7\u00F5es selecionadas' : 'op\u00E7\u00E3o selecionada' }}</span>\n </button>\n }\n\n <button *ngFor=\"let item of items; trackBy: trackByFn\" class=\"dropdown-item d-flex align-items-center\" type=\"button\"\n (click)=\"select(item, true)\" [attr.aria-selected]=\"isSelected(item)\" >\n\n @if (optionTemplate) {\n <ng-container *ngTemplateOutlet=\"optionTemplate; context: { $implicit: item, selected: isSelected(item) }\"></ng-container>\n }\n @else {\n <div class=\"w-100 original\">\n <div class=\"d-flex justify-content-between\">\n <div [ngClass]=\"{ 'text-primary fw-bold': isSelected(item) }\">\n <!-- Se o valor do ID e do LABEL for vazio exibe apenas um risquinho para identificar que h\u00E1 uma op\u00E7\u00E3o ali -->\n @if ((item[customLabel] ?? item[customValue]) === '') {\n <span class=\"fst-italic text-muted\">Nenhum t\u00EDtulo informado para esta op\u00E7\u00E3o</span>\n }\n @else {\n {{ (item[customLabel] ?? item[customValue]) }}\n }\n </div>\n </div>\n </div>\n }\n </button>\n </ng-container>\n </div>\n </div>\n\n @if (rightButtonTemplate) { <ng-container *ngTemplateOutlet=\"rightButtonTemplate\"></ng-container> }\n</div>", styles: [".reusable-combobox{position:relative;display:flex;flex-wrap:nowrap;width:100%;max-width:100%}.reusable-combobox #toggle-button{box-sizing:border-box}.reusable-combobox .dropdown-menu{width:100%;box-shadow:0 6px 18px #00000014;border-radius:.5rem}.reusable-combobox .sticky-header{position:sticky;top:0;z-index:10;background:#f1f5f9;box-shadow:0 2px 4px #00000014}.reusable-combobox .dropdown-item{cursor:pointer;border-radius:6px;transition:all .3s ease}.reusable-combobox .dropdown-item:hover:not(:focus){background-color:#f1f5f9}.reusable-combobox.compact .dropdown-menu{max-height:200px}.bg-primary-subtle{background-color:#d1dfe7!important}::-webkit-scrollbar{width:4px;background:transparent}::-webkit-scrollbar-thumb{background:#bbb;border-radius:16px}.disabled{background-color:#e9ecef!important}.dropdown-item{min-height:32px!important}\n"] }]
8368
+ ], template: "<div class=\"reusable-combobox input-group\" [class.show]=\"isOpen\" (focusout)=\"onBlurOutside($event)\" >\n @if (leftButtonTemplate) { <ng-container *ngTemplateOutlet=\"leftButtonTemplate\"></ng-container> }\n\n <div class=\"dropdown w-100\">\n\n <div class=\"position-relative\">\n <input #toggleButton id=\"toggle-button\" class=\"form-select d-flex align-items-center text-start w-100 overflow-hidden text-truncate glb-cursor-pointer\" data-bs-toggle=\"dropdown\"\n data-bs-auto-close=\"outside\" [attr.aria-expanded]=\"isOpen\" [attr.aria-haspopup]=\"true\" [attr.aria-label]=\"placeholder\" [class.disabled]=\"disabled\"\n [class.is-invalid]=\"invalid\" (click)=\"toggleDropdown()\" [value]=\"displayValue()\" [placeholder]=\"placeholder\" readonly\n [class.with-selection-badge]=\"showCountBadge && multiple && selectedCount > 0\"\n [ngClass]=\"{\n 'rounded-start-0': leftButtonTemplate,\n 'rounded-end-0': rightButtonTemplate,\n }\" />\n\n @if (showCountBadge && multiple && selectedCount > 0) { <span class=\"selection-count-badge\" [tooltip]=\"'Total de ' + selectedCount + ' registros selecionados'\"> {{ selectedCount }} </span> }\n </div>\n\n\n <div #dropdownMenu class=\"dropdown-menu p-2 w-100\" [class.show]=\"isOpen\" style=\"max-height: 400px; overflow-y: auto;\" >\n <div class=\"sticky-header rounded p-3\">\n <div class=\"dropdown-search input-group\">\n <input class=\"form-control form-control-sm\" type=\"search\" [placeholder]=\"searchPlaceholder\" [formControl]=\"searchControl\" aria-label=\"Pesquisar op\u00E7\u00F5es\" (keyup.enter)=\"filterButtonClick.emit(searchControl.value)\" />\n <button class=\"btn btn-sm btn-primary\" type=\"button\" (click)=\"filterButtonClick.emit(searchControl.value)\"> <lib-icon iconName=\"lupa\" iconSize=\"medium-small\" /> </button>\n </div>\n\n @if (multiple && selectedValues?.length) {\n <div class=\"selected-options-badges d-flex flex-row gap-2 mt-2 py-2 overflow-x-scroll\">\n @for (value of selectedValues; track $index) {\n <span class=\"px-3 badge rounded-pill text-primary-emphasis bg-primary-subtle\">\n {{ getItemProperty(value, customLabel) }} <lib-icon class=\"glb-cursor-pointer\" iconName=\"fechar\" iconSize=\"small\" (click)=\"select(value, true)\" />\n </span>\n }\n </div>\n }\n </div>\n\n <!-- Se utilizar o filtro interno utiliza a propriedade de lista filteredItems$, caso contr\u00E1rio usa a pr\u00F3pria list pois ela ser\u00E1 filtrada pelo componente pai -->\n @let filteredItems = innerFilter ? (filteredItems$ | async) : list;\n @if (filteredItems) {\n @if (filteredItems.length === 0) { <div class=\"py-2 px-3 text-muted small\">{{ noResultsText }}</div> }\n\n @if (value !== '' && value !== null) {\n <button type=\"button\" class=\"dropdown-item d-flex align-items-center my-2 py-2 border-bottom border-secondary-subtle rounded-bottom-0\" (click)=\"writeValue(null)\"\n tooltip=\"Limpa todas as op\u00E7\u00F5es selecionadas\">\n <span class=\"fw-bold\">Limpar {{ multiple ? 'op\u00E7\u00F5es selecionadas' : 'op\u00E7\u00E3o selecionada' }}</span>\n </button>\n }\n @else if (multiple) {\n <button type=\"button\" class=\"dropdown-item d-flex align-items-center my-2 py-2 border-bottom border-secondary-subtle rounded-bottom-0\" (click)=\"writeValue(list)\" tooltip=\"Seleciona todas as op\u00E7\u00F5es dispon\u00EDveis\">\n <span class=\"fw-bold\">Selecionar tudo ({{ list.length }} op\u00E7\u00F5es)</span>\n </button>\n }\n\n @for (item of filteredItems; track item) {\n <button class=\"dropdown-item d-flex align-items-center\" type=\"button\"\n (click)=\"select(item, true)\" [attr.aria-selected]=\"isSelected(item)\" >\n\n @if (optionTemplate) {\n <ng-container *ngTemplateOutlet=\"optionTemplate; context: { $implicit: item, selected: isSelected(item) }\"></ng-container>\n }\n @else {\n <div class=\"w-100 original\">\n <div class=\"d-flex justify-content-between\">\n <div [ngClass]=\"{ 'text-primary fw-bold': isSelected(item) }\">\n <!-- Se o valor do ID e do LABEL for vazio exibe apenas um risquinho para identificar que h\u00E1 uma op\u00E7\u00E3o ali -->\n @if ((getItemProperty(item, customLabel) ?? getItemProperty(item, customValue)) === '') {\n <span class=\"fst-italic text-muted\">Nenhum t\u00EDtulo informado para esta op\u00E7\u00E3o</span>\n }\n @else {\n {{ (getItemProperty(item, customLabel) ?? getItemProperty(item, customValue)) }}\n }\n </div>\n </div>\n </div>\n }\n </button>\n }\n }\n </div>\n </div>\n\n @if (rightButtonTemplate) { <ng-container *ngTemplateOutlet=\"rightButtonTemplate\"></ng-container> }\n</div>", styles: [".reusable-combobox{position:relative;display:flex;flex-wrap:nowrap;width:100%;max-width:100%}.reusable-combobox #toggle-button{box-sizing:border-box}.reusable-combobox .selection-count-badge{position:absolute;top:50%;right:2.75rem;transform:translateY(-50%);min-width:24px;height:24px;padding:0 8px;display:flex;align-items:center;justify-content:center;border-radius:6px;background-color:#dce1e6;color:#495057;font-size:.75rem;font-weight:600;pointer-events:none}.reusable-combobox .with-selection-badge{padding-right:5rem!important}.reusable-combobox .dropdown-menu{width:100%;box-shadow:0 6px 18px #00000014;border-radius:.5rem}.reusable-combobox .sticky-header{position:sticky;top:0;z-index:10;background:#f1f5f9;box-shadow:0 2px 4px #00000014}.reusable-combobox .dropdown-item{cursor:pointer;border-radius:6px;transition:all .3s ease}.reusable-combobox .dropdown-item:hover:not(:focus){background-color:#f1f5f9}.reusable-combobox.compact .dropdown-menu{max-height:350px}::-webkit-scrollbar{width:4px;background:transparent}::-webkit-scrollbar-thumb{background:var(--bs-secondary);border-radius:16px}.disabled{background-color:#e9ecef!important}.dropdown-item{min-height:32px!important}.selected-options-badges::-webkit-scrollbar{height:3px;background:var(--bs-primary-bg-subtle)}.selected-options-badges::-webkit-scrollbar-thumb{background:var(--bs-primary);border-radius:8px;height:3px;cursor:pointer}\n"] }]
8345
8369
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }], propDecorators: { list: [{
8346
8370
  type: Input,
8347
8371
  args: [{ required: true }]
@@ -8361,6 +8385,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImpo
8361
8385
  type: Input
8362
8386
  }], customValue: [{
8363
8387
  type: Input
8388
+ }], showCountBadge: [{
8389
+ type: Input
8364
8390
  }], optionTemplate: [{
8365
8391
  type: ContentChild,
8366
8392
  args: ["optionTemplate", { read: TemplateRef, static: false }]