cfc-ds
Version:
Design System do Conselho Federal de Contabilidade baseado no govbr-ds
531 lines • 89.5 kB
JavaScript
import { Component, EventEmitter, forwardRef, HostListener, Input, Output } from '@angular/core';
import { NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
import { SelectType } from '../../enums/select-type.enum';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@angular/flex-layout/flex";
import * as i3 from "@angular/flex-layout/extended";
export class SelectComponent {
renderer;
el;
cdr;
// Inputs
options = [];
id;
label;
placeholder = '';
labelInline = false;
multiSelect = false;
feedbackMessage;
feedbackState;
showSearchIcon = true;
showSelectAll = false;
required = false;
ariaLabel;
ariaDescribedBy;
disabled = false;
type = SelectType.default;
// Outputs
onChange = new EventEmitter();
onOpen = new EventEmitter();
onClose = new EventEmitter();
// Internal properties
inputId;
searchTerm = '';
selectedValues = [];
filteredOptions = [];
selectAllChecked = false;
isOptionsListVisible = false;
highlightedIndex = -1;
displayValue = '';
isTooltipVisible = false;
tooltipPosition = { top: 0, left: 0 };
// ControlValueAccessor properties
onModelChange = (_) => { };
onModelTouched = () => { };
constructor(renderer, el, cdr) {
this.renderer = renderer;
this.el = el;
this.cdr = cdr;
this.inputId = this.id || `select-${Math.random().toString(36).substring(2, 9)}`;
}
ngOnInit() {
if (this.required && this.ariaDescribedBy) {
this.ariaDescribedBy = `${this.ariaDescribedBy} feedback-${this.inputId}`;
}
else if (this.required) {
this.ariaDescribedBy = `feedback-${this.inputId}`;
}
}
ngAfterViewInit() {
// Garante que filteredOptions sempre começa com todas as opções disponíveis
this.filteredOptions = [...this.options];
this.updateDisplayValue();
this.cdr.detectChanges();
}
// Handle keyboard navigation
handleKeyDown(event) {
if (this.disabled)
return;
switch (event.key) {
case 'ArrowDown':
event.preventDefault();
if (!this.isOptionsListVisible) {
this.openOptionsList();
}
else {
this.highlightNextItem();
}
break;
case 'ArrowUp':
event.preventDefault();
if (!this.isOptionsListVisible) {
this.openOptionsList();
}
else {
this.highlightPreviousItem();
}
break;
case 'Enter':
if (this.isOptionsListVisible && this.highlightedIndex >= 0) {
event.preventDefault();
if (this.highlightedIndex === 0 && this.showSelectAll && this.multiSelect) {
this.toggleSelectAll();
}
else {
const adjustedIndex = this.showSelectAll && this.multiSelect ? this.highlightedIndex - 1 : this.highlightedIndex;
if (adjustedIndex >= 0 && adjustedIndex < this.filteredOptions.length) {
this.toggleSelection(this.filteredOptions[adjustedIndex]);
}
}
}
else if (!this.isOptionsListVisible) {
this.openOptionsList();
}
break;
case ' ': // Space key
if (this.isOptionsListVisible && this.highlightedIndex >= 0) {
event.preventDefault();
if (this.highlightedIndex === 0 && this.showSelectAll && this.multiSelect) {
this.toggleSelectAll();
}
else {
const adjustedIndex = this.showSelectAll && this.multiSelect ? this.highlightedIndex - 1 : this.highlightedIndex;
if (adjustedIndex >= 0 && adjustedIndex < this.filteredOptions.length) {
this.toggleSelection(this.filteredOptions[adjustedIndex]);
}
}
}
break;
case 'Escape':
if (this.isOptionsListVisible) {
event.preventDefault();
this.closeOptionsList();
}
break;
case 'Tab':
if (this.isOptionsListVisible) {
this.closeOptionsList();
}
break;
default:
// Para filtro por primeira letra quando as teclas são letras ou números
if (event.key.length === 1 && /[a-zA-Z0-9]/.test(event.key)) {
// Implementação para filtrar por primeira letra
this.filterByFirstLetter(event.key);
}
break;
}
}
handleItemKeyDown(event, option) {
if (this.disabled)
return;
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();
if (option === null && this.showSelectAll && this.multiSelect) {
this.toggleSelectAll();
}
else {
this.toggleSelection(option);
}
}
}
// Filter options by first letter
filterByFirstLetter(letter) {
if (this.disabled)
return;
letter = letter.toLowerCase();
// Find the first option that starts with the letter
const index = this.filteredOptions.findIndex(option => option.label.toLowerCase().startsWith(letter));
if (index >= 0) {
this.highlightedIndex = this.showSelectAll && this.multiSelect ? index + 1 : index;
// Scroll to the item
setTimeout(() => {
const listElement = this.el.nativeElement.querySelector('.options-list');
const optionElement = listElement?.querySelector(`li:nth-child(${this.highlightedIndex + 1})`);
if (listElement && optionElement) {
listElement.scrollTop = optionElement.offsetTop - listElement.offsetTop;
}
});
}
}
// Highlight navigation
highlightNextItem() {
if (this.disabled)
return;
const maxIndex = this.getOptionsLength() - 1;
if (this.highlightedIndex < maxIndex) {
this.highlightedIndex++;
this.scrollToHighlightedItem();
}
}
highlightPreviousItem() {
if (this.disabled)
return;
if (this.highlightedIndex > 0) {
this.highlightedIndex--;
this.scrollToHighlightedItem();
}
}
scrollToHighlightedItem() {
if (this.disabled)
return;
setTimeout(() => {
const listElement = this.el.nativeElement.querySelector('.options-list');
const optionElement = listElement?.querySelector(`li:nth-child(${this.highlightedIndex + 1})`);
if (listElement && optionElement) {
const optionTop = optionElement.offsetTop;
const optionBottom = optionTop + optionElement.offsetHeight;
const listTop = listElement.scrollTop;
const listBottom = listTop + listElement.offsetHeight;
if (optionTop < listTop) {
listElement.scrollTop = optionTop;
}
else if (optionBottom > listBottom) {
listElement.scrollTop = optionBottom - listElement.offsetHeight;
}
}
});
}
getOptionsLength() {
return this.filteredOptions.length + (this.showSelectAll && this.multiSelect ? 1 : 0);
}
// Open/close the options list
openOptionsList() {
if (this.disabled)
return;
// Resetar os filtros quando abrir a lista
if (this.searchTerm === '') {
this.filteredOptions = [...this.options];
}
this.isOptionsListVisible = true;
this.highlightedIndex = 0;
this.onOpen.emit();
this.cdr.detectChanges();
}
closeOptionsList() {
if (this.disabled)
return;
this.isOptionsListVisible = false;
this.highlightedIndex = -1;
this.onClose.emit();
}
toggleOptionsList() {
if (this.disabled)
return;
if (this.isOptionsListVisible) {
this.closeOptionsList();
}
else {
this.openOptionsList();
}
}
onInputFocus() {
if (this.disabled)
return;
this.openOptionsList();
this.onModelTouched();
}
// Selection logic
toggleSelection(option, event) {
if (this.disabled)
return;
// Se recebemos um evento, impedir a propagação padrão
if (event) {
event.preventDefault();
event.stopPropagation();
}
// Garantir que estamos trabalhando com o objeto correto
const targetOption = this.options.find(opt => opt.value === option.value);
if (!targetOption) {
console.warn('Option not found:', option);
return;
}
if (this.multiSelect) {
const index = this.selectedValues.findIndex(item => item.value === targetOption.value);
if (index > -1) {
// Remove do array de selecionados
this.selectedValues.splice(index, 1);
}
else {
// Adiciona ao array de selecionados
this.selectedValues.push(targetOption);
}
// Importante: force a detecção de mudanças após a alteração
this.updateSelectAllState();
this.cdr.detectChanges();
}
else {
this.selectedValues = [targetOption];
this.closeOptionsList();
}
this.updateDisplayValue();
// Notifica o FormControl
const valueToEmit = this.multiSelect ? this.selectedValues : (this.selectedValues.length > 0 ? this.selectedValues[0].value : null);
this.onModelChange(valueToEmit);
this.onModelTouched();
// Emite evento para componente pai
this.onChange.emit(this.selectedValues);
}
isOptionSelected(option) {
return this.selectedValues.some(item => item.value === option.value);
}
toggleSelectAll(event) {
if (this.disabled)
return;
if (event) {
event.preventDefault();
event.stopPropagation();
}
if (this.selectAllChecked) {
this.selectedValues = [];
this.selectAllChecked = false;
}
else {
this.selectedValues = [...this.filteredOptions];
this.selectAllChecked = true;
}
this.cdr.detectChanges(); // Force a detecção de mudanças
this.updateDisplayValue();
// Notifica o FormControl
this.onModelChange(this.selectedValues);
this.onModelTouched();
// Emite evento para componente pai
this.onChange.emit(this.selectedValues);
if (!this.multiSelect) {
this.closeOptionsList();
}
}
updateSelectAllState() {
if (this.disabled)
return;
if (this.filteredOptions.length === 0) {
this.selectAllChecked = false;
return;
}
if (this.selectedValues.length === 0) {
this.selectAllChecked = false;
}
else if (this.filteredOptions.every(option => this.selectedValues.some(selected => selected.value === option.value))) {
this.selectAllChecked = true;
}
else {
// Estado intermediário - alguns selecionados, mas não todos
this.selectAllChecked = false;
}
}
// Search functionality
onSearchChange(event) {
if (this.disabled)
return;
const target = event.target;
this.searchTerm = target.value.toLowerCase();
this.filteredOptions = this.options.filter(option => option.label.toLowerCase().includes(this.searchTerm));
// Reset highlight position
this.highlightedIndex = 0;
// Se não tiver a lista aberta, abre
if (!this.isOptionsListVisible) {
this.openOptionsList();
}
// Update select all state based on filtered options
this.updateSelectAllState();
}
// Display value formatting
updateDisplayValue() {
if (this.selectedValues.length === 0) {
this.displayValue = '';
return;
}
if (this.multiSelect) {
if (this.selectedValues.length === 1) {
// Quando há apenas um item selecionado
this.displayValue = this.selectedValues[0].label;
}
else {
// Quando há múltiplos itens: primeiro item + (número dos demais)
this.displayValue = `${this.selectedValues[0].label} + (${this.selectedValues.length - 1})`;
}
}
else {
// Para seleção única
this.displayValue = this.selectedValues[0].label;
}
}
// Click outside to close
onClick(event) {
const clickedInside = this.el.nativeElement.contains(event.target);
if (!clickedInside && this.isOptionsListVisible) {
this.closeOptionsList();
}
}
getFullSelectedText() {
if (this.selectedValues.length === 0) {
return '';
}
return this.selectedValues.map(v => v.label).join(', ');
}
showTooltip(event) {
if (this.disabled)
return;
if ((this.isTextTruncated() || this.selectedValues.length > 1) && this.selectedValues.length > 0) {
const containerElement = this.el.nativeElement.querySelector('.select-container');
const rect = containerElement.getBoundingClientRect();
// Calcula posição melhor
this.tooltipPosition = {
top: rect.height, // Logo abaixo do container
left: rect.width / 2 // Centralizado
};
this.isTooltipVisible = true;
this.cdr.detectChanges();
}
}
hideTooltip() {
this.isTooltipVisible = false;
}
isTextTruncated() {
const inputElement = this.el.nativeElement.querySelector('.select-input');
if (inputElement) {
// Certifique-se de que há um pequeno buffer para considerarmos truncado
return (inputElement.scrollWidth > inputElement.clientWidth + 2);
}
return false;
}
// Implementação ControlValueAccessor
writeValue(value) {
if (value === null || value === undefined) {
this.selectedValues = [];
}
else if (Array.isArray(value)) {
this.selectedValues = this.options.filter(option => value.some((val) => {
if (typeof val === 'object' && val !== null) {
return val.value === option.value;
}
else {
return val === option.value;
}
}));
}
else {
const selectedOption = this.options.find(option => option.value === value ||
(typeof value === 'object' && value !== null && JSON.stringify(option.value) === JSON.stringify(value)));
this.selectedValues = selectedOption ? [selectedOption] : [];
}
this.updateDisplayValue();
this.updateSelectAllState();
this.cdr.detectChanges();
}
registerOnChange(fn) {
this.onModelChange = fn;
}
registerOnTouched(fn) {
this.onModelTouched = fn;
}
setDisabledState(isDisabled) {
this.disabled = isDisabled;
if (isDisabled) {
// Ensure the dropdown is closed when disabled
this.isOptionsListVisible = false;
}
this.cdr.detectChanges();
}
// Implementação do Validator
validate(control) {
if (this.required) {
const value = control.value;
if (value === null || value === undefined ||
(Array.isArray(value) && value.length === 0) ||
value === '') {
return { required: true };
}
}
return null;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: SelectComponent, selector: "cfc-select", inputs: { options: "options", id: "id", label: "label", placeholder: "placeholder", labelInline: "labelInline", multiSelect: "multiSelect", feedbackMessage: "feedbackMessage", feedbackState: "feedbackState", showSearchIcon: "showSearchIcon", showSelectAll: "showSelectAll", required: "required", ariaLabel: "ariaLabel", ariaDescribedBy: "ariaDescribedBy", disabled: "disabled", type: "type" }, outputs: { onChange: "onChange", onOpen: "onOpen", onClose: "onClose" }, host: { listeners: { "document:click": "onClick($event)" } }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => SelectComponent),
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => SelectComponent),
multi: true
}
], ngImport: i0, template: "<div\r\n [fxLayout]=\"labelInline ? 'row' : 'column'\"\r\n [fxLayoutAlign]=\"labelInline ? 'center center' : ''\"\r\n [ngClass]=\"{'pagination-select': type === 'pagination'}\">\r\n\r\n <label\r\n *ngIf=\"label\"\r\n class=\"input-label\"\r\n [for]=\"inputId\"\r\n [class.required]=\"required\">\r\n {{ label }}\r\n </label>\r\n\r\n <div class=\"select-container\">\r\n <div\r\n class=\"input-with-icon\"\r\n [ngClass]=\"{'pagination-input': type === 'pagination'}\"\r\n [class.disabled]=\"disabled\"\r\n role=\"combobox\"\r\n [attr.aria-expanded]=\"isOptionsListVisible && !disabled\"\r\n [attr.aria-haspopup]=\"!disabled\"\r\n [attr.aria-owns]=\"'list-' + inputId\"\r\n [attr.aria-required]=\"required\"\r\n [attr.aria-disabled]=\"disabled\"\r\n (mouseenter)=\"!disabled && showTooltip($event)\"\r\n (mouseleave)=\"hideTooltip()\">\r\n <i class=\"fa fa-search search-icon\" *ngIf=\"showSearchIcon\" aria-hidden=\"true\"></i>\r\n <input\r\n [id]=\"inputId\"\r\n type=\"text\"\r\n [placeholder]=\"placeholder\"\r\n [attr.aria-label]=\"ariaLabel || label || 'Select'\"\r\n [attr.aria-describedby]=\"ariaDescribedBy\"\r\n [attr.aria-autocomplete]=\"'list'\"\r\n [attr.aria-controls]=\"'list-' + inputId\"\r\n [value]=\"displayValue\"\r\n [disabled]=\"disabled\"\r\n (input)=\"onSearchChange($event)\"\r\n (focus)=\"onInputFocus()\"\r\n (keydown)=\"handleKeyDown($event)\"\r\n class=\"select-input\"\r\n [class.has-search-icon]=\"showSearchIcon\"\r\n [class.disabled]=\"disabled\"\r\n [class.required]=\"required\" />\r\n <button\r\n type=\"button\"\r\n class=\"toggle-button\"\r\n tabindex=\"-1\"\r\n [disabled]=\"disabled\"\r\n (click)=\"toggleOptionsList()\"\r\n aria-hidden=\"true\">\r\n <i class=\"fa\" [ngClass]=\"isOptionsListVisible ? 'fa-caret-up' : 'fa-caret-down'\"></i>\r\n </button>\r\n </div>\r\n\r\n <!-- Tooltip customizado -->\r\n <div *ngIf=\"isTooltipVisible && !disabled\"\r\n class=\"custom-tooltip\"\r\n [style.top.px]=\"tooltipPosition.top\"\r\n [style.left.px]=\"tooltipPosition.left\">\r\n {{ getFullSelectedText() }}\r\n </div>\r\n\r\n <ul\r\n *ngIf=\"isOptionsListVisible && !disabled\"\r\n [id]=\"'list-' + inputId\"\r\n role=\"listbox\"\r\n [attr.aria-multiselectable]=\"multiSelect\"\r\n [attr.aria-labelledby]=\"inputId\"\r\n class=\"options-list\"\r\n [ngClass]=\"{'pagination-options': type === 'pagination'}\"\r\n tabindex=\"-1\">\r\n <li *ngIf=\"showSelectAll && multiSelect\"\r\n role=\"option\"\r\n class=\"select-all-option\"\r\n [class.selected]=\"selectAllChecked\"\r\n (click)=\"toggleSelectAll($event)\"\r\n (keydown)=\"handleItemKeyDown($event, null)\">\r\n <div class=\"option-content\">\r\n <div class=\"checkbox-wrapper\">\r\n <input\r\n type=\"checkbox\"\r\n [id]=\"'select-all-' + inputId\"\r\n [checked]=\"selectAllChecked\"\r\n tabindex=\"-1\"\r\n aria-hidden=\"true\" />\r\n <span class=\"checkbox-label\">\r\n {{ selectAllChecked ? 'Desselecionar todos' : 'Selecionar todos' }}\r\n </span>\r\n </div>\r\n </div>\r\n </li>\r\n <li *ngFor=\"let option of filteredOptions; let i = index\"\r\n role=\"option\"\r\n [id]=\"'option-' + inputId + '-' + i\"\r\n [attr.aria-selected]=\"isOptionSelected(option)\"\r\n [class.selected]=\"isOptionSelected(option)\"\r\n [class.highlighted]=\"highlightedIndex === i\"\r\n (click)=\"toggleSelection(option, $event)\"\r\n (keydown)=\"handleItemKeyDown($event, option)\">\r\n <div class=\"option-content\">\r\n <div class=\"checkbox-wrapper\" *ngIf=\"multiSelect\">\r\n <input\r\n type=\"checkbox\"\r\n [id]=\"'option-checkbox-' + inputId + '-' + i\"\r\n [checked]=\"isOptionSelected(option)\"\r\n tabindex=\"-1\"\r\n aria-hidden=\"true\"\r\n (click)=\"$event.stopPropagation()\" />\r\n <span class=\"checkbox-label\">{{ option.label }}</span>\r\n </div>\r\n <span *ngIf=\"!multiSelect\">{{ option.label }}</span>\r\n </div>\r\n </li>\r\n <li *ngIf=\"filteredOptions.length === 0\"\r\n class=\"empty-state\"\r\n role=\"option\"\r\n aria-disabled=\"true\">\r\n Nenhum item encontrado.\r\n </li>\r\n </ul>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"feedbackMessage\"\r\n [ngClass]=\"feedbackState\"\r\n [id]=\"'feedback-' + inputId\"\r\n aria-live=\"polite\">\r\n {{ feedbackMessage }}\r\n </div>\r\n</div>\r\n", styles: ["@charset \"UTF-8\";:host{width:100%;display:block}.select-container{position:relative;width:100%}.input-with-icon{position:relative;display:flex;align-items:center;border:1px solid #ccc;border-radius:4px;background-color:#fff;transition:border-color .2s,box-shadow .2s}.input-with-icon:hover{border-color:#999}.input-with-icon:focus-within{border-color:#007bff;box-shadow:0 0 0 2px #007bff40}.search-icon{position:absolute;left:12px;color:#666;pointer-events:none}.toggle-button{background:transparent;border:none;padding:0 12px;cursor:pointer;color:#666;font-size:16px;height:100%;display:flex;align-items:center;justify-content:center}.toggle-button:hover{color:#333}.select-input{flex:1;padding:10px 40px 10px 12px;border:none;border-radius:4px;font-size:16px;background:transparent;width:100%;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.select-input:focus{outline:none}.select-input.has-search-icon{padding-left:36px}.options-list{position:absolute;top:100%;left:0;right:0;max-height:250px;overflow-y:auto;margin:4px 0 0;padding:0;list-style:none;background:#fff;border-radius:4px;border:1px solid #ccc;z-index:1000;box-shadow:0 4px 12px #0000001a}.options-list li.selected{background-color:#e6f7ff}.checkbox-wrapper{display:flex;align-items:center;width:100%}.checkbox-label{margin-left:8px;cursor:pointer}.options-list li{cursor:pointer;display:flex;align-items:center;-webkit-user-select:none;user-select:none;width:100%}.options-list li:hover{background-color:#f5f5f5}.options-list li.selected{background-color:#007bff;color:#fff}.options-list li.selected .checkbox label{color:#fff}.options-list li.highlighted{background-color:#e8f0fe}.options-list li.selected.highlighted{background-color:#0069d9}.option-content{width:100%;padding:10px 12px;display:flex;align-items:center}.checkbox{display:flex;align-items:center}.checkbox input{margin-right:8px}.select-all-option{border-bottom:1px solid #eee;font-weight:600;background-color:#f9f9f9}.empty-state{padding:12px;text-align:center;color:#999;font-style:italic;cursor:default}.input-label{margin-bottom:6px;font-weight:500;color:#333}.input-label.required:after{content:\"*\";color:#dc3545;margin-left:4px}.error{color:#dc3545;font-size:14px;margin-top:4px}.warning{color:#ffc107;font-size:14px;margin-top:4px}.success{color:#28a745;font-size:14px;margin-top:4px}.custom-tooltip{position:absolute;background-color:#06c;color:#fff;padding:8px 12px;border-radius:4px;z-index:2000;max-width:300px;word-wrap:break-word;box-shadow:0 2px 8px #00000026;pointer-events:none;transition:opacity .2s;white-space:normal;transform:translate(-50%)}.custom-tooltip:after{content:\"\";position:absolute;top:-8px;left:50%;transform:translate(-50%);border-width:0 8px 8px;border-style:solid;border-color:transparent transparent #0066cc transparent}.pagination-select .pagination-input{height:36px;min-width:64px;border:transparent}.pagination-select .pagination-input:hover{background-color:#e8e8e8}.pagination-select .pagination-input .select-input{text-align:center;font-weight:500;padding:8px 24px 8px 12px}.pagination-select .pagination-input .toggle-button{padding:0 6px;position:absolute;right:0}.pagination-select .pagination-options{text-align:center}.pagination-select .pagination-options li{padding:8px;justify-content:center}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i2.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i3.DefaultClassDirective, selector: " [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]", inputs: ["ngClass", "ngClass.xs", "ngClass.sm", "ngClass.md", "ngClass.lg", "ngClass.xl", "ngClass.lt-sm", "ngClass.lt-md", "ngClass.lt-lg", "ngClass.lt-xl", "ngClass.gt-xs", "ngClass.gt-sm", "ngClass.gt-md", "ngClass.gt-lg"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SelectComponent, decorators: [{
type: Component,
args: [{ selector: 'cfc-select', providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => SelectComponent),
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => SelectComponent),
multi: true
}
], template: "<div\r\n [fxLayout]=\"labelInline ? 'row' : 'column'\"\r\n [fxLayoutAlign]=\"labelInline ? 'center center' : ''\"\r\n [ngClass]=\"{'pagination-select': type === 'pagination'}\">\r\n\r\n <label\r\n *ngIf=\"label\"\r\n class=\"input-label\"\r\n [for]=\"inputId\"\r\n [class.required]=\"required\">\r\n {{ label }}\r\n </label>\r\n\r\n <div class=\"select-container\">\r\n <div\r\n class=\"input-with-icon\"\r\n [ngClass]=\"{'pagination-input': type === 'pagination'}\"\r\n [class.disabled]=\"disabled\"\r\n role=\"combobox\"\r\n [attr.aria-expanded]=\"isOptionsListVisible && !disabled\"\r\n [attr.aria-haspopup]=\"!disabled\"\r\n [attr.aria-owns]=\"'list-' + inputId\"\r\n [attr.aria-required]=\"required\"\r\n [attr.aria-disabled]=\"disabled\"\r\n (mouseenter)=\"!disabled && showTooltip($event)\"\r\n (mouseleave)=\"hideTooltip()\">\r\n <i class=\"fa fa-search search-icon\" *ngIf=\"showSearchIcon\" aria-hidden=\"true\"></i>\r\n <input\r\n [id]=\"inputId\"\r\n type=\"text\"\r\n [placeholder]=\"placeholder\"\r\n [attr.aria-label]=\"ariaLabel || label || 'Select'\"\r\n [attr.aria-describedby]=\"ariaDescribedBy\"\r\n [attr.aria-autocomplete]=\"'list'\"\r\n [attr.aria-controls]=\"'list-' + inputId\"\r\n [value]=\"displayValue\"\r\n [disabled]=\"disabled\"\r\n (input)=\"onSearchChange($event)\"\r\n (focus)=\"onInputFocus()\"\r\n (keydown)=\"handleKeyDown($event)\"\r\n class=\"select-input\"\r\n [class.has-search-icon]=\"showSearchIcon\"\r\n [class.disabled]=\"disabled\"\r\n [class.required]=\"required\" />\r\n <button\r\n type=\"button\"\r\n class=\"toggle-button\"\r\n tabindex=\"-1\"\r\n [disabled]=\"disabled\"\r\n (click)=\"toggleOptionsList()\"\r\n aria-hidden=\"true\">\r\n <i class=\"fa\" [ngClass]=\"isOptionsListVisible ? 'fa-caret-up' : 'fa-caret-down'\"></i>\r\n </button>\r\n </div>\r\n\r\n <!-- Tooltip customizado -->\r\n <div *ngIf=\"isTooltipVisible && !disabled\"\r\n class=\"custom-tooltip\"\r\n [style.top.px]=\"tooltipPosition.top\"\r\n [style.left.px]=\"tooltipPosition.left\">\r\n {{ getFullSelectedText() }}\r\n </div>\r\n\r\n <ul\r\n *ngIf=\"isOptionsListVisible && !disabled\"\r\n [id]=\"'list-' + inputId\"\r\n role=\"listbox\"\r\n [attr.aria-multiselectable]=\"multiSelect\"\r\n [attr.aria-labelledby]=\"inputId\"\r\n class=\"options-list\"\r\n [ngClass]=\"{'pagination-options': type === 'pagination'}\"\r\n tabindex=\"-1\">\r\n <li *ngIf=\"showSelectAll && multiSelect\"\r\n role=\"option\"\r\n class=\"select-all-option\"\r\n [class.selected]=\"selectAllChecked\"\r\n (click)=\"toggleSelectAll($event)\"\r\n (keydown)=\"handleItemKeyDown($event, null)\">\r\n <div class=\"option-content\">\r\n <div class=\"checkbox-wrapper\">\r\n <input\r\n type=\"checkbox\"\r\n [id]=\"'select-all-' + inputId\"\r\n [checked]=\"selectAllChecked\"\r\n tabindex=\"-1\"\r\n aria-hidden=\"true\" />\r\n <span class=\"checkbox-label\">\r\n {{ selectAllChecked ? 'Desselecionar todos' : 'Selecionar todos' }}\r\n </span>\r\n </div>\r\n </div>\r\n </li>\r\n <li *ngFor=\"let option of filteredOptions; let i = index\"\r\n role=\"option\"\r\n [id]=\"'option-' + inputId + '-' + i\"\r\n [attr.aria-selected]=\"isOptionSelected(option)\"\r\n [class.selected]=\"isOptionSelected(option)\"\r\n [class.highlighted]=\"highlightedIndex === i\"\r\n (click)=\"toggleSelection(option, $event)\"\r\n (keydown)=\"handleItemKeyDown($event, option)\">\r\n <div class=\"option-content\">\r\n <div class=\"checkbox-wrapper\" *ngIf=\"multiSelect\">\r\n <input\r\n type=\"checkbox\"\r\n [id]=\"'option-checkbox-' + inputId + '-' + i\"\r\n [checked]=\"isOptionSelected(option)\"\r\n tabindex=\"-1\"\r\n aria-hidden=\"true\"\r\n (click)=\"$event.stopPropagation()\" />\r\n <span class=\"checkbox-label\">{{ option.label }}</span>\r\n </div>\r\n <span *ngIf=\"!multiSelect\">{{ option.label }}</span>\r\n </div>\r\n </li>\r\n <li *ngIf=\"filteredOptions.length === 0\"\r\n class=\"empty-state\"\r\n role=\"option\"\r\n aria-disabled=\"true\">\r\n Nenhum item encontrado.\r\n </li>\r\n </ul>\r\n </div>\r\n\r\n <div\r\n *ngIf=\"feedbackMessage\"\r\n [ngClass]=\"feedbackState\"\r\n [id]=\"'feedback-' + inputId\"\r\n aria-live=\"polite\">\r\n {{ feedbackMessage }}\r\n </div>\r\n</div>\r\n", styles: ["@charset \"UTF-8\";:host{width:100%;display:block}.select-container{position:relative;width:100%}.input-with-icon{position:relative;display:flex;align-items:center;border:1px solid #ccc;border-radius:4px;background-color:#fff;transition:border-color .2s,box-shadow .2s}.input-with-icon:hover{border-color:#999}.input-with-icon:focus-within{border-color:#007bff;box-shadow:0 0 0 2px #007bff40}.search-icon{position:absolute;left:12px;color:#666;pointer-events:none}.toggle-button{background:transparent;border:none;padding:0 12px;cursor:pointer;color:#666;font-size:16px;height:100%;display:flex;align-items:center;justify-content:center}.toggle-button:hover{color:#333}.select-input{flex:1;padding:10px 40px 10px 12px;border:none;border-radius:4px;font-size:16px;background:transparent;width:100%;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.select-input:focus{outline:none}.select-input.has-search-icon{padding-left:36px}.options-list{position:absolute;top:100%;left:0;right:0;max-height:250px;overflow-y:auto;margin:4px 0 0;padding:0;list-style:none;background:#fff;border-radius:4px;border:1px solid #ccc;z-index:1000;box-shadow:0 4px 12px #0000001a}.options-list li.selected{background-color:#e6f7ff}.checkbox-wrapper{display:flex;align-items:center;width:100%}.checkbox-label{margin-left:8px;cursor:pointer}.options-list li{cursor:pointer;display:flex;align-items:center;-webkit-user-select:none;user-select:none;width:100%}.options-list li:hover{background-color:#f5f5f5}.options-list li.selected{background-color:#007bff;color:#fff}.options-list li.selected .checkbox label{color:#fff}.options-list li.highlighted{background-color:#e8f0fe}.options-list li.selected.highlighted{background-color:#0069d9}.option-content{width:100%;padding:10px 12px;display:flex;align-items:center}.checkbox{display:flex;align-items:center}.checkbox input{margin-right:8px}.select-all-option{border-bottom:1px solid #eee;font-weight:600;background-color:#f9f9f9}.empty-state{padding:12px;text-align:center;color:#999;font-style:italic;cursor:default}.input-label{margin-bottom:6px;font-weight:500;color:#333}.input-label.required:after{content:\"*\";color:#dc3545;margin-left:4px}.error{color:#dc3545;font-size:14px;margin-top:4px}.warning{color:#ffc107;font-size:14px;margin-top:4px}.success{color:#28a745;font-size:14px;margin-top:4px}.custom-tooltip{position:absolute;background-color:#06c;color:#fff;padding:8px 12px;border-radius:4px;z-index:2000;max-width:300px;word-wrap:break-word;box-shadow:0 2px 8px #00000026;pointer-events:none;transition:opacity .2s;white-space:normal;transform:translate(-50%)}.custom-tooltip:after{content:\"\";position:absolute;top:-8px;left:50%;transform:translate(-50%);border-width:0 8px 8px;border-style:solid;border-color:transparent transparent #0066cc transparent}.pagination-select .pagination-input{height:36px;min-width:64px;border:transparent}.pagination-select .pagination-input:hover{background-color:#e8e8e8}.pagination-select .pagination-input .select-input{text-align:center;font-weight:500;padding:8px 24px 8px 12px}.pagination-select .pagination-input .toggle-button{padding:0 6px;position:absolute;right:0}.pagination-select .pagination-options{text-align:center}.pagination-select .pagination-options li{padding:8px;justify-content:center}\n"] }]
}], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }], propDecorators: { options: [{
type: Input
}], id: [{
type: Input
}], label: [{
type: Input
}], placeholder: [{
type: Input
}], labelInline: [{
type: Input
}], multiSelect: [{
type: Input
}], feedbackMessage: [{
type: Input
}], feedbackState: [{
type: Input
}], showSearchIcon: [{
type: Input
}], showSelectAll: [{
type: Input
}], required: [{
type: Input
}], ariaLabel: [{
type: Input
}], ariaDescribedBy: [{
type: Input
}], disabled: [{
type: Input
}], type: [{
type: Input
}], onChange: [{
type: Output
}], onOpen: [{
type: Output
}], onClose: [{
type: Output
}], onClick: [{
type: HostListener,
args: ['document:click', ['$event']]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NmYy1kcy9zcmMvbGliL2NvbXBvbmVudHMvc2VsZWN0L3NlbGVjdC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jZmMtZHMvc3JjL2xpYi9jb21wb25lbnRzL3NlbGVjdC9zZWxlY3QuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUdMLFNBQVMsRUFFVCxZQUFZLEVBQ1osVUFBVSxFQUNWLFlBQVksRUFDWixLQUFLLEVBRUwsTUFBTSxFQUdQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsYUFBYSxFQUFnRCxNQUFNLGdCQUFnQixDQUFDO0FBRXRJLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQTs7Ozs7QUFtQnpELE1BQU0sT0FBTyxlQUFlO0lBeUNoQjtJQUNBO0lBQ0E7SUExQ1YsU0FBUztJQUNBLE9BQU8sR0FBVSxFQUFFLENBQUM7SUFDcEIsRUFBRSxDQUFVO0lBQ1osS0FBSyxDQUFVO0lBQ2YsV0FBVyxHQUFZLEVBQUUsQ0FBQztJQUMxQixXQUFXLEdBQUcsS0FBSyxDQUFDO0lBQ3BCLFdBQVcsR0FBRyxLQUFLLENBQUM7SUFDcEIsZUFBZSxDQUFVO0lBQ3pCLGFBQWEsQ0FBZ0I7SUFDN0IsY0FBYyxHQUFZLElBQUksQ0FBQztJQUMvQixhQUFhLEdBQVksS0FBSyxDQUFDO0lBQy9CLFFBQVEsR0FBWSxLQUFLLENBQUM7SUFDMUIsU0FBUyxDQUFVO0lBQ25CLGVBQWUsQ0FBVTtJQUN6QixRQUFRLEdBQVksS0FBSyxDQUFDO0lBQzFCLElBQUksR0FBZSxVQUFVLENBQUMsT0FBTyxDQUFDO0lBRS9DLFVBQVU7SUFDQSxRQUFRLEdBQXdCLElBQUksWUFBWSxFQUFTLENBQUM7SUFDMUQsTUFBTSxH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