@neural-ui/core 1.6.1 → 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/neural-ui-core-accordion.mjs +7 -11
- package/fesm2022/neural-ui-core-accordion.mjs.map +1 -1
- package/fesm2022/neural-ui-core-alert.mjs +14 -25
- package/fesm2022/neural-ui-core-alert.mjs.map +1 -1
- package/fesm2022/neural-ui-core-autocomplete.mjs +28 -53
- package/fesm2022/neural-ui-core-autocomplete.mjs.map +1 -1
- package/fesm2022/neural-ui-core-avatar.mjs +13 -23
- package/fesm2022/neural-ui-core-avatar.mjs.map +1 -1
- package/fesm2022/neural-ui-core-badge.mjs +9 -15
- package/fesm2022/neural-ui-core-badge.mjs.map +1 -1
- package/fesm2022/neural-ui-core-block-ui.mjs +11 -16
- package/fesm2022/neural-ui-core-block-ui.mjs.map +1 -1
- package/fesm2022/neural-ui-core-breadcrumb.mjs +6 -8
- package/fesm2022/neural-ui-core-breadcrumb.mjs.map +1 -1
- package/fesm2022/neural-ui-core-button.mjs +16 -29
- package/fesm2022/neural-ui-core-button.mjs.map +1 -1
- package/fesm2022/neural-ui-core-calendar.mjs +20 -37
- package/fesm2022/neural-ui-core-calendar.mjs.map +1 -1
- package/fesm2022/neural-ui-core-card.mjs +8 -13
- package/fesm2022/neural-ui-core-card.mjs.map +1 -1
- package/fesm2022/neural-ui-core-chart.mjs +24 -45
- package/fesm2022/neural-ui-core-chart.mjs.map +1 -1
- package/fesm2022/neural-ui-core-checkbox.mjs +9 -15
- package/fesm2022/neural-ui-core-checkbox.mjs.map +1 -1
- package/fesm2022/neural-ui-core-chip.mjs +13 -23
- package/fesm2022/neural-ui-core-chip.mjs.map +1 -1
- package/fesm2022/neural-ui-core-code-block.mjs +17 -31
- package/fesm2022/neural-ui-core-code-block.mjs.map +1 -1
- package/fesm2022/neural-ui-core-color-picker.mjs +11 -19
- package/fesm2022/neural-ui-core-color-picker.mjs.map +1 -1
- package/fesm2022/neural-ui-core-command-palette.mjs +11 -16
- package/fesm2022/neural-ui-core-command-palette.mjs.map +1 -1
- package/fesm2022/neural-ui-core-confirm-dialog.mjs +6 -6
- package/fesm2022/neural-ui-core-confirm-dialog.mjs.map +1 -1
- package/fesm2022/neural-ui-core-context-menu.mjs +9 -12
- package/fesm2022/neural-ui-core-context-menu.mjs.map +1 -1
- package/fesm2022/neural-ui-core-dashboard-grid.mjs +7 -11
- package/fesm2022/neural-ui-core-dashboard-grid.mjs.map +1 -1
- package/fesm2022/neural-ui-core-date-input.mjs +57 -111
- package/fesm2022/neural-ui-core-date-input.mjs.map +1 -1
- package/fesm2022/neural-ui-core-divider.mjs +5 -7
- package/fesm2022/neural-ui-core-divider.mjs.map +1 -1
- package/fesm2022/neural-ui-core-empty-state.mjs +8 -13
- package/fesm2022/neural-ui-core-empty-state.mjs.map +1 -1
- package/fesm2022/neural-ui-core-filter-bar.mjs +11 -19
- package/fesm2022/neural-ui-core-filter-bar.mjs.map +1 -1
- package/fesm2022/neural-ui-core-icon.mjs +7 -11
- package/fesm2022/neural-ui-core-icon.mjs.map +1 -1
- package/fesm2022/neural-ui-core-image-gallery.mjs +13 -23
- package/fesm2022/neural-ui-core-image-gallery.mjs.map +1 -1
- package/fesm2022/neural-ui-core-image-viewer.mjs +14 -22
- package/fesm2022/neural-ui-core-image-viewer.mjs.map +1 -1
- package/fesm2022/neural-ui-core-input-otp.mjs +11 -19
- package/fesm2022/neural-ui-core-input-otp.mjs.map +1 -1
- package/fesm2022/neural-ui-core-input.mjs +35 -67
- package/fesm2022/neural-ui-core-input.mjs.map +1 -1
- package/fesm2022/neural-ui-core-kanban.mjs +9 -15
- package/fesm2022/neural-ui-core-kanban.mjs.map +1 -1
- package/fesm2022/neural-ui-core-knob.mjs +22 -41
- package/fesm2022/neural-ui-core-knob.mjs.map +1 -1
- package/fesm2022/neural-ui-core-meter-group.mjs +13 -23
- package/fesm2022/neural-ui-core-meter-group.mjs.map +1 -1
- package/fesm2022/neural-ui-core-modal.mjs +11 -16
- package/fesm2022/neural-ui-core-modal.mjs.map +1 -1
- package/fesm2022/neural-ui-core-multiselect.mjs +39 -72
- package/fesm2022/neural-ui-core-multiselect.mjs.map +1 -1
- package/fesm2022/neural-ui-core-nav.mjs +13 -22
- package/fesm2022/neural-ui-core-nav.mjs.map +1 -1
- package/fesm2022/neural-ui-core-notification-center.mjs +9 -12
- package/fesm2022/neural-ui-core-notification-center.mjs.map +1 -1
- package/fesm2022/neural-ui-core-number-input.mjs +19 -35
- package/fesm2022/neural-ui-core-number-input.mjs.map +1 -1
- package/fesm2022/neural-ui-core-pagination.mjs +9 -15
- package/fesm2022/neural-ui-core-pagination.mjs.map +1 -1
- package/fesm2022/neural-ui-core-popover.mjs +14 -22
- package/fesm2022/neural-ui-core-popover.mjs.map +1 -1
- package/fesm2022/neural-ui-core-progress-bar.mjs +11 -19
- package/fesm2022/neural-ui-core-progress-bar.mjs.map +1 -1
- package/fesm2022/neural-ui-core-radio.mjs +15 -24
- package/fesm2022/neural-ui-core-radio.mjs.map +1 -1
- package/fesm2022/neural-ui-core-rating.mjs +8 -13
- package/fesm2022/neural-ui-core-rating.mjs.map +1 -1
- package/fesm2022/neural-ui-core-rich-text-editor.mjs +28 -53
- package/fesm2022/neural-ui-core-rich-text-editor.mjs.map +1 -1
- package/fesm2022/neural-ui-core-scheduler-gantt.mjs +22 -41
- package/fesm2022/neural-ui-core-scheduler-gantt.mjs.map +1 -1
- package/fesm2022/neural-ui-core-select.mjs +43 -77
- package/fesm2022/neural-ui-core-select.mjs.map +1 -1
- package/fesm2022/neural-ui-core-sidebar.mjs +12 -21
- package/fesm2022/neural-ui-core-sidebar.mjs.map +1 -1
- package/fesm2022/neural-ui-core-skeleton.mjs +7 -11
- package/fesm2022/neural-ui-core-skeleton.mjs.map +1 -1
- package/fesm2022/neural-ui-core-slider.mjs +13 -23
- package/fesm2022/neural-ui-core-slider.mjs.map +1 -1
- package/fesm2022/neural-ui-core-spinner.mjs +10 -17
- package/fesm2022/neural-ui-core-spinner.mjs.map +1 -1
- package/fesm2022/neural-ui-core-split-button.mjs +15 -27
- package/fesm2022/neural-ui-core-split-button.mjs.map +1 -1
- package/fesm2022/neural-ui-core-splitter.mjs +6 -9
- package/fesm2022/neural-ui-core-splitter.mjs.map +1 -1
- package/fesm2022/neural-ui-core-stats-card.mjs +11 -19
- package/fesm2022/neural-ui-core-stats-card.mjs.map +1 -1
- package/fesm2022/neural-ui-core-stepper.mjs +8 -13
- package/fesm2022/neural-ui-core-stepper.mjs.map +1 -1
- package/fesm2022/neural-ui-core-switch.mjs +9 -15
- package/fesm2022/neural-ui-core-switch.mjs.map +1 -1
- package/fesm2022/neural-ui-core-table.mjs +124 -242
- package/fesm2022/neural-ui-core-table.mjs.map +1 -1
- package/fesm2022/neural-ui-core-tabs.mjs +18 -30
- package/fesm2022/neural-ui-core-tabs.mjs.map +1 -1
- package/fesm2022/neural-ui-core-textarea.mjs +23 -43
- package/fesm2022/neural-ui-core-textarea.mjs.map +1 -1
- package/fesm2022/neural-ui-core-timeline-grid.mjs +12 -21
- package/fesm2022/neural-ui-core-timeline-grid.mjs.map +1 -1
- package/fesm2022/neural-ui-core-timeline.mjs +4 -5
- package/fesm2022/neural-ui-core-timeline.mjs.map +1 -1
- package/fesm2022/neural-ui-core-toast.mjs +8 -10
- package/fesm2022/neural-ui-core-toast.mjs.map +1 -1
- package/fesm2022/neural-ui-core-toggle-button-group.mjs +10 -17
- package/fesm2022/neural-ui-core-toggle-button-group.mjs.map +1 -1
- package/fesm2022/neural-ui-core-toolbar.mjs +8 -13
- package/fesm2022/neural-ui-core-toolbar.mjs.map +1 -1
- package/fesm2022/neural-ui-core-tooltip.mjs +11 -16
- package/fesm2022/neural-ui-core-tooltip.mjs.map +1 -1
- package/fesm2022/neural-ui-core-tree-table.mjs +30 -57
- package/fesm2022/neural-ui-core-tree-table.mjs.map +1 -1
- package/fesm2022/neural-ui-core-tree.mjs +17 -31
- package/fesm2022/neural-ui-core-tree.mjs.map +1 -1
- package/fesm2022/neural-ui-core-uploader.mjs +47 -91
- package/fesm2022/neural-ui-core-uploader.mjs.map +1 -1
- package/fesm2022/neural-ui-core-url-state.mjs +5 -7
- package/fesm2022/neural-ui-core-url-state.mjs.map +1 -1
- package/fesm2022/neural-ui-core-virtual-list.mjs +19 -32
- package/fesm2022/neural-ui-core-virtual-list.mjs.map +1 -1
- package/package.json +6 -6
|
@@ -15,14 +15,11 @@ import { DomSanitizer } from '@angular/platform-browser';
|
|
|
15
15
|
class NeuAccordionComponent {
|
|
16
16
|
_sanitizer = inject(DomSanitizer);
|
|
17
17
|
/** Lista de paneles / Panel list */
|
|
18
|
-
items = input([], /*
|
|
19
|
-
...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
18
|
+
items = input([], ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
20
19
|
/** Permite varios paneles abiertos a la vez / Allows multiple panels open at once */
|
|
21
|
-
multiple = input(false, /*
|
|
22
|
-
...(ngDevMode ? [{ debugName: "multiple" }] : /* istanbul ignore next */ []));
|
|
20
|
+
multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple" }] : /* istanbul ignore next */ []));
|
|
23
21
|
/** Borde exterior alrededor del accordion / Outer border around the accordion */
|
|
24
|
-
bordered = input(true, /*
|
|
25
|
-
...(ngDevMode ? [{ debugName: "bordered" }] : /* istanbul ignore next */ []));
|
|
22
|
+
bordered = input(true, ...(ngDevMode ? [{ debugName: "bordered" }] : /* istanbul ignore next */ []));
|
|
26
23
|
/** Emite el id del panel al abrirse/cerrarse / Emits the panel id on open/close */
|
|
27
24
|
panelToggle = output();
|
|
28
25
|
/**
|
|
@@ -31,8 +28,7 @@ class NeuAccordionComponent {
|
|
|
31
28
|
* Después se vuelve un signal mutable independiente (no se resetea al cambiar items).
|
|
32
29
|
*/
|
|
33
30
|
_expandedInit = false;
|
|
34
|
-
_expanded = signal(new Set(), /*
|
|
35
|
-
...(ngDevMode ? [{ debugName: "_expanded" }] : /* istanbul ignore next */ []));
|
|
31
|
+
_expanded = signal(new Set(), ...(ngDevMode ? [{ debugName: "_expanded" }] : /* istanbul ignore next */ []));
|
|
36
32
|
constructor() {
|
|
37
33
|
// Inicialización única desde items.expanded (equivalente a linkedSignal source+computation)
|
|
38
34
|
effect(() => {
|
|
@@ -64,8 +60,8 @@ class NeuAccordionComponent {
|
|
|
64
60
|
this._expanded.set(current);
|
|
65
61
|
this.panelToggle.emit({ id, expanded: willExpand });
|
|
66
62
|
}
|
|
67
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
68
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
63
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuAccordionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
64
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: NeuAccordionComponent, isStandalone: true, selector: "neu-accordion", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, bordered: { classPropertyName: "bordered", publicName: "bordered", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { panelToggle: "panelToggle" }, ngImport: i0, template: `
|
|
69
65
|
<div class="neu-accordion" [class.neu-accordion--bordered]="bordered()">
|
|
70
66
|
@for (item of items(); track item.id) {
|
|
71
67
|
<div
|
|
@@ -111,7 +107,7 @@ class NeuAccordionComponent {
|
|
|
111
107
|
</div>
|
|
112
108
|
`, isInline: true, styles: [".neu-accordion{width:100%;font-family:var(--neu-font-sans)}.neu-accordion--bordered{border:1.5px solid var(--neu-border);border-radius:var(--neu-radius-lg);overflow:hidden}.neu-accordion__item{border-bottom:1.5px solid var(--neu-border)}.neu-accordion__item:last-child{border-bottom:none}.neu-accordion__item--disabled{opacity:.45;pointer-events:none}.neu-accordion__header{width:100%;display:flex;align-items:center;justify-content:space-between;gap:var(--neu-space-4);padding:var(--neu-space-4) var(--neu-space-5);background:var(--neu-surface);border:none;cursor:pointer;font-family:var(--neu-font-sans);text-align:left;transition:background var(--neu-transition);outline:none}.neu-accordion__header:hover{background:var(--neu-surface-2)}.neu-accordion__header:focus-visible{outline:2px solid var(--neu-primary);outline-offset:-2px}.neu-accordion__title{font-size:var(--neu-text-base);font-weight:600;color:var(--neu-text)}.neu-accordion__chevron{display:inline-flex;flex-shrink:0;color:var(--neu-text-muted);transition:transform .25s cubic-bezier(.4,0,.2,1)}.neu-accordion__item--expanded .neu-accordion__chevron{transform:rotate(180deg)}.neu-accordion__panel{display:grid;grid-template-rows:0fr;transition:grid-template-rows .28s cubic-bezier(.4,0,.2,1)}.neu-accordion__item--expanded .neu-accordion__panel{grid-template-rows:1fr}.neu-accordion__body{overflow:hidden;font-size:var(--neu-text-sm);color:var(--neu-text-muted);line-height:1.7;padding:0;transition:padding .28s cubic-bezier(.4,0,.2,1)}.neu-accordion__item--expanded .neu-accordion__body{padding:var(--neu-space-4) var(--neu-space-5);padding-top:0}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
113
109
|
}
|
|
114
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
110
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuAccordionComponent, decorators: [{
|
|
115
111
|
type: Component,
|
|
116
112
|
args: [{ selector: 'neu-accordion', imports: [], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
117
113
|
<div class="neu-accordion" [class.neu-accordion--bordered]="bordered()">
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neural-ui-core-accordion.mjs","sources":["../../../../projects/ui-core/accordion/neu-accordion.component.ts","../../../../projects/ui-core/accordion/neural-ui-core-accordion.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n effect,\n inject,\n input,\n output,\n SecurityContext,\n signal,\n untracked,\n} from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\n\nexport interface NeuAccordionItem {\n /** ID único del panel / Unique panel ID */\n id: string;\n /** Título del encabezado / Header title */\n title: string;\n /** Contenido del cuerpo (HTML o texto plano) / Body content (HTML or plain text) */\n content: string;\n /** Inicia expandido / Starts expanded */\n expanded?: boolean;\n /** Deshabilita este panel / Disables this panel */\n disabled?: boolean;\n}\n\n/**\n * NeuralUI Accordion Component\n *\n * Paneles expandibles / colapsables con animación suave.\n * Soporta modo múltiple (varios abiertos a la vez) o exclusivo. / Supports multiple (several open at once) or exclusive mode.\n *\n * Uso:\n * <neu-accordion [items]=\"items\" />\n * <neu-accordion [items]=\"items\" [multiple]=\"true\" />\n */\n@Component({\n selector: 'neu-accordion',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"neu-accordion\" [class.neu-accordion--bordered]=\"bordered()\">\n @for (item of items(); track item.id) {\n <div\n class=\"neu-accordion__item\"\n [class.neu-accordion__item--expanded]=\"isExpanded(item.id)\"\n [class.neu-accordion__item--disabled]=\"item.disabled\"\n >\n <button\n class=\"neu-accordion__header\"\n type=\"button\"\n [id]=\"'neu-acc-btn-' + item.id\"\n [attr.aria-expanded]=\"isExpanded(item.id)\"\n [attr.aria-controls]=\"'neu-acc-panel-' + item.id\"\n [disabled]=\"item.disabled\"\n (click)=\"toggle(item.id)\"\n >\n <span class=\"neu-accordion__title\">{{ item.title }}</span>\n <span class=\"neu-accordion__chevron\" aria-hidden=\"true\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </span>\n </button>\n <div\n class=\"neu-accordion__panel\"\n [id]=\"'neu-acc-panel-' + item.id\"\n role=\"region\"\n [attr.aria-labelledby]=\"'neu-acc-btn-' + item.id\"\n >\n <div class=\"neu-accordion__body\" [innerHTML]=\"sanitize(item.content)\"></div>\n </div>\n </div>\n }\n </div>\n `,\n styleUrl: './neu-accordion.component.scss',\n})\nexport class NeuAccordionComponent {\n private readonly _sanitizer = inject(DomSanitizer);\n\n /** Lista de paneles / Panel list */\n items = input<NeuAccordionItem[]>([]);\n\n /** Permite varios paneles abiertos a la vez / Allows multiple panels open at once */\n multiple = input<boolean>(false);\n\n /** Borde exterior alrededor del accordion / Outer border around the accordion */\n bordered = input<boolean>(true);\n\n /** Emite el id del panel al abrirse/cerrarse / Emits the panel id on open/close */\n panelToggle = output<{ id: string; expanded: boolean }>();\n\n /**\n * Set de IDs actualmente expandidos.\n * Se inicializa desde los ítems con `expanded: true` en el primer render.\n * Después se vuelve un signal mutable independiente (no se resetea al cambiar items).\n */\n private _expandedInit = false;\n private readonly _expanded = signal<Set<string>>(new Set());\n\n constructor() {\n // Inicialización única desde items.expanded (equivalente a linkedSignal source+computation)\n effect(() => {\n const items = this.items();\n untracked(() => {\n if (!this._expandedInit) {\n this._expanded.set(new Set(items.filter((i) => i.expanded).map((i) => i.id)));\n this._expandedInit = true;\n }\n });\n });\n }\n\n readonly isExpanded = (id: string) => this._expanded().has(id);\n\n sanitize(html: string): SafeHtml {\n return this._sanitizer.sanitize(SecurityContext.HTML, html) ?? '';\n }\n\n toggle(id: string): void {\n const current = new Set(this._expanded());\n const willExpand = !current.has(id);\n\n if (!this.multiple()) {\n current.clear();\n }\n\n if (willExpand) {\n current.add(id);\n } else {\n current.delete(id);\n }\n\n this._expanded.set(current);\n this.panelToggle.emit({ id, expanded: willExpand });\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":";;;;AA2BA;;;;;;;;;AASG;MAqDU,qBAAqB,CAAA;AACf,IAAA,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC;;
|
|
1
|
+
{"version":3,"file":"neural-ui-core-accordion.mjs","sources":["../../../../projects/ui-core/accordion/neu-accordion.component.ts","../../../../projects/ui-core/accordion/neural-ui-core-accordion.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n effect,\n inject,\n input,\n output,\n SecurityContext,\n signal,\n untracked,\n} from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\n\nexport interface NeuAccordionItem {\n /** ID único del panel / Unique panel ID */\n id: string;\n /** Título del encabezado / Header title */\n title: string;\n /** Contenido del cuerpo (HTML o texto plano) / Body content (HTML or plain text) */\n content: string;\n /** Inicia expandido / Starts expanded */\n expanded?: boolean;\n /** Deshabilita este panel / Disables this panel */\n disabled?: boolean;\n}\n\n/**\n * NeuralUI Accordion Component\n *\n * Paneles expandibles / colapsables con animación suave.\n * Soporta modo múltiple (varios abiertos a la vez) o exclusivo. / Supports multiple (several open at once) or exclusive mode.\n *\n * Uso:\n * <neu-accordion [items]=\"items\" />\n * <neu-accordion [items]=\"items\" [multiple]=\"true\" />\n */\n@Component({\n selector: 'neu-accordion',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"neu-accordion\" [class.neu-accordion--bordered]=\"bordered()\">\n @for (item of items(); track item.id) {\n <div\n class=\"neu-accordion__item\"\n [class.neu-accordion__item--expanded]=\"isExpanded(item.id)\"\n [class.neu-accordion__item--disabled]=\"item.disabled\"\n >\n <button\n class=\"neu-accordion__header\"\n type=\"button\"\n [id]=\"'neu-acc-btn-' + item.id\"\n [attr.aria-expanded]=\"isExpanded(item.id)\"\n [attr.aria-controls]=\"'neu-acc-panel-' + item.id\"\n [disabled]=\"item.disabled\"\n (click)=\"toggle(item.id)\"\n >\n <span class=\"neu-accordion__title\">{{ item.title }}</span>\n <span class=\"neu-accordion__chevron\" aria-hidden=\"true\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </span>\n </button>\n <div\n class=\"neu-accordion__panel\"\n [id]=\"'neu-acc-panel-' + item.id\"\n role=\"region\"\n [attr.aria-labelledby]=\"'neu-acc-btn-' + item.id\"\n >\n <div class=\"neu-accordion__body\" [innerHTML]=\"sanitize(item.content)\"></div>\n </div>\n </div>\n }\n </div>\n `,\n styleUrl: './neu-accordion.component.scss',\n})\nexport class NeuAccordionComponent {\n private readonly _sanitizer = inject(DomSanitizer);\n\n /** Lista de paneles / Panel list */\n items = input<NeuAccordionItem[]>([]);\n\n /** Permite varios paneles abiertos a la vez / Allows multiple panels open at once */\n multiple = input<boolean>(false);\n\n /** Borde exterior alrededor del accordion / Outer border around the accordion */\n bordered = input<boolean>(true);\n\n /** Emite el id del panel al abrirse/cerrarse / Emits the panel id on open/close */\n panelToggle = output<{ id: string; expanded: boolean }>();\n\n /**\n * Set de IDs actualmente expandidos.\n * Se inicializa desde los ítems con `expanded: true` en el primer render.\n * Después se vuelve un signal mutable independiente (no se resetea al cambiar items).\n */\n private _expandedInit = false;\n private readonly _expanded = signal<Set<string>>(new Set());\n\n constructor() {\n // Inicialización única desde items.expanded (equivalente a linkedSignal source+computation)\n effect(() => {\n const items = this.items();\n untracked(() => {\n if (!this._expandedInit) {\n this._expanded.set(new Set(items.filter((i) => i.expanded).map((i) => i.id)));\n this._expandedInit = true;\n }\n });\n });\n }\n\n readonly isExpanded = (id: string) => this._expanded().has(id);\n\n sanitize(html: string): SafeHtml {\n return this._sanitizer.sanitize(SecurityContext.HTML, html) ?? '';\n }\n\n toggle(id: string): void {\n const current = new Set(this._expanded());\n const willExpand = !current.has(id);\n\n if (!this.multiple()) {\n current.clear();\n }\n\n if (willExpand) {\n current.add(id);\n } else {\n current.delete(id);\n }\n\n this._expanded.set(current);\n this.panelToggle.emit({ id, expanded: willExpand });\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
|
|
@@ -19,35 +19,25 @@ let _seq = 0;
|
|
|
19
19
|
*/
|
|
20
20
|
class NeuAlertComponent {
|
|
21
21
|
/** Tipo semántico / Semantic type */
|
|
22
|
-
type = input('info', /*
|
|
23
|
-
...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
|
|
22
|
+
type = input('info', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
|
|
24
23
|
/** Título opcional sobre el mensaje / Optional title above message */
|
|
25
|
-
title = input('', /*
|
|
26
|
-
...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
24
|
+
title = input('', ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
27
25
|
/** Icono personalizado. Vacío = usa el icono por defecto del tipo / Custom icon. Empty = use default type icon */
|
|
28
|
-
icon = input('', /*
|
|
29
|
-
...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
|
|
26
|
+
icon = input('', ...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
|
|
30
27
|
/** Muestra el icono / Shows the icon */
|
|
31
|
-
showIcon = input(true, /*
|
|
32
|
-
...(ngDevMode ? [{ debugName: "showIcon" }] : /* istanbul ignore next */ []));
|
|
28
|
+
showIcon = input(true, ...(ngDevMode ? [{ debugName: "showIcon" }] : /* istanbul ignore next */ []));
|
|
33
29
|
/** Permite cerrarse / Can be dismissed */
|
|
34
|
-
closable = input(false, /*
|
|
35
|
-
...(ngDevMode ? [{ debugName: "closable" }] : /* istanbul ignore next */ []));
|
|
30
|
+
closable = input(false, ...(ngDevMode ? [{ debugName: "closable" }] : /* istanbul ignore next */ []));
|
|
36
31
|
/** Variante outline (sin fondo sólido) / Outline variant (no solid background) */
|
|
37
|
-
outline = input(false, /*
|
|
38
|
-
...(ngDevMode ? [{ debugName: "outline" }] : /* istanbul ignore next */ []));
|
|
32
|
+
outline = input(false, ...(ngDevMode ? [{ debugName: "outline" }] : /* istanbul ignore next */ []));
|
|
39
33
|
/** Aria-label para el botón de cierre / Aria-label for the close button */
|
|
40
|
-
closeLabel = input('Cerrar alerta', /*
|
|
41
|
-
...(ngDevMode ? [{ debugName: "closeLabel" }] : /* istanbul ignore next */ []));
|
|
34
|
+
closeLabel = input('Cerrar alerta', ...(ngDevMode ? [{ debugName: "closeLabel" }] : /* istanbul ignore next */ []));
|
|
42
35
|
/** Emitido cuando se descarta la alerta / Emitted when the alert is dismissed */
|
|
43
36
|
closed = output();
|
|
44
37
|
_id = `neu-alert-${++_seq}`;
|
|
45
|
-
_dismissed = signal(false, /*
|
|
46
|
-
...(ngDevMode ? [{ debugName: "
|
|
47
|
-
|
|
48
|
-
...(ngDevMode ? [{ debugName: "_resolvedIcon" }] : /* istanbul ignore next */ []));
|
|
49
|
-
liveRegion = computed(() => (this.type() === 'error' ? 'assertive' : 'polite'), /* @ts-ignore */
|
|
50
|
-
...(ngDevMode ? [{ debugName: "liveRegion" }] : /* istanbul ignore next */ []));
|
|
38
|
+
_dismissed = signal(false, ...(ngDevMode ? [{ debugName: "_dismissed" }] : /* istanbul ignore next */ []));
|
|
39
|
+
_resolvedIcon = computed(() => this.icon() || DEFAULT_ICONS[this.type()], ...(ngDevMode ? [{ debugName: "_resolvedIcon" }] : /* istanbul ignore next */ []));
|
|
40
|
+
liveRegion = computed(() => (this.type() === 'error' ? 'assertive' : 'polite'), ...(ngDevMode ? [{ debugName: "liveRegion" }] : /* istanbul ignore next */ []));
|
|
51
41
|
hostClasses = computed(() => ({
|
|
52
42
|
'neu-alert': true,
|
|
53
43
|
[`neu-alert--${this.type()}`]: true,
|
|
@@ -55,14 +45,13 @@ class NeuAlertComponent {
|
|
|
55
45
|
'neu-alert--closable': this.closable(),
|
|
56
46
|
'neu-alert--with-icon': this.showIcon(),
|
|
57
47
|
'neu-alert--dismissed': this._dismissed(),
|
|
58
|
-
}), /*
|
|
59
|
-
...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
|
|
48
|
+
}), ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
|
|
60
49
|
dismiss() {
|
|
61
50
|
this._dismissed.set(true);
|
|
62
51
|
this.closed.emit();
|
|
63
52
|
}
|
|
64
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
65
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
53
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuAlertComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
54
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: NeuAlertComponent, isStandalone: true, selector: "neu-alert", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, showIcon: { classPropertyName: "showIcon", publicName: "showIcon", isSignal: true, isRequired: false, transformFunction: null }, closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, outline: { classPropertyName: "outline", publicName: "outline", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, host: { attributes: { "role": "alert" }, properties: { "class": "hostClasses()", "attr.aria-live": "liveRegion()" } }, ngImport: i0, template: `
|
|
66
55
|
@if (!_dismissed()) {
|
|
67
56
|
@if (showIcon()) {
|
|
68
57
|
<span class="neu-alert__icon" aria-hidden="true">{{ _resolvedIcon() }}</span>
|
|
@@ -89,7 +78,7 @@ class NeuAlertComponent {
|
|
|
89
78
|
}
|
|
90
79
|
`, isInline: true, styles: ["@charset \"UTF-8\";.neu-alert{display:flex;align-items:flex-start;gap:10px;padding:12px 16px;border-radius:var(--neu-radius-md, 8px);border:1px solid transparent;font-size:.875rem;line-height:1.5;position:relative}.neu-alert--dismissed{display:none}.neu-alert--info{background:var(--neu-alert-info-bg, #eff6ff);border-color:var(--neu-alert-info-border, #bfdbfe);color:var(--neu-alert-info-text, #1d4ed8)}.neu-alert--success{background:var(--neu-alert-success-bg, #f0fdf4);border-color:var(--neu-alert-success-border, #bbf7d0);color:var(--neu-alert-success-text, #15803d)}.neu-alert--warning{background:var(--neu-alert-warning-bg, #fffbeb);border-color:var(--neu-alert-warning-border, #fde68a);color:var(--neu-alert-warning-text, #b45309)}.neu-alert--error{background:var(--neu-alert-error-bg, #fef2f2);border-color:var(--neu-alert-error-border, #fecaca);color:var(--neu-alert-error-text, #b91c1c)}.neu-alert--outline{background:transparent}.neu-alert__icon{flex-shrink:0;font-size:1.1em;line-height:1.5;font-style:normal}.neu-alert__body{flex:1;min-width:0}.neu-alert__title{display:block;font-weight:600;margin-bottom:2px}.neu-alert__content{opacity:.9}.neu-alert__close{all:unset;cursor:pointer;flex-shrink:0;font-size:1.1rem;line-height:1;opacity:.6;transition:opacity .15s;padding:2px 4px;border-radius:var(--neu-radius-sm, 4px)}.neu-alert__close:hover{opacity:1;background:var(--neu-alert-dismiss-hover-bg)}.neu-alert__close:focus-visible{outline:2px solid var(--neu-focus-ring, #0ea5e9);outline-offset:1px;opacity:1}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
91
80
|
}
|
|
92
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
81
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuAlertComponent, decorators: [{
|
|
93
82
|
type: Component,
|
|
94
83
|
args: [{ selector: 'neu-alert', imports: [], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: { '[class]': 'hostClasses()', role: 'alert', '[attr.aria-live]': 'liveRegion()' }, template: `
|
|
95
84
|
@if (!_dismissed()) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neural-ui-core-alert.mjs","sources":["../../../../projects/ui-core/alert/neu-alert.component.ts","../../../../projects/ui-core/alert/neural-ui-core-alert.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n output,\n signal,\n} from '@angular/core';\n\nexport type NeuAlertType = 'info' | 'success' | 'warning' | 'error';\n\n/** Icono por defecto para cada tipo */\nconst DEFAULT_ICONS: Record<NeuAlertType, string> = {\n info: 'ℹ',\n success: '✓',\n warning: '⚠',\n error: '✕',\n};\n\nlet _seq = 0;\n\n/**\n * NeuralUI Alert Component\n *\n * Mensaje de alerta contextual con soporte de icono personalizado, slot de acciones y cierre.\n *\n * Uso: <neu-alert type=\"success\">Operación completada</neu-alert>\n * <neu-alert type=\"error\" [closable]=\"true\" (closed)=\"onClosed()\">Error de red</neu-alert>\n */\n@Component({\n selector: 'neu-alert',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { '[class]': 'hostClasses()', role: 'alert', '[attr.aria-live]': 'liveRegion()' },\n template: `\n @if (!_dismissed()) {\n @if (showIcon()) {\n <span class=\"neu-alert__icon\" aria-hidden=\"true\">{{ _resolvedIcon() }}</span>\n }\n <div class=\"neu-alert__body\">\n @if (title()) {\n <strong class=\"neu-alert__title\">{{ title() }}</strong>\n }\n <div class=\"neu-alert__content\">\n <ng-content />\n </div>\n <ng-content select=\"[neu-alert-actions]\" />\n </div>\n @if (closable()) {\n <button\n class=\"neu-alert__close\"\n type=\"button\"\n [attr.aria-label]=\"closeLabel()\"\n (click)=\"dismiss()\"\n >\n ×\n </button>\n }\n }\n `,\n styleUrl: './neu-alert.component.scss',\n})\nexport class NeuAlertComponent {\n /** Tipo semántico / Semantic type */\n readonly type = input<NeuAlertType>('info');\n\n /** Título opcional sobre el mensaje / Optional title above message */\n readonly title = input<string>('');\n\n /** Icono personalizado. Vacío = usa el icono por defecto del tipo / Custom icon. Empty = use default type icon */\n readonly icon = input<string>('');\n\n /** Muestra el icono / Shows the icon */\n readonly showIcon = input<boolean>(true);\n\n /** Permite cerrarse / Can be dismissed */\n readonly closable = input<boolean>(false);\n\n /** Variante outline (sin fondo sólido) / Outline variant (no solid background) */\n readonly outline = input<boolean>(false);\n\n /** Aria-label para el botón de cierre / Aria-label for the close button */\n readonly closeLabel = input<string>('Cerrar alerta');\n\n /** Emitido cuando se descarta la alerta / Emitted when the alert is dismissed */\n readonly closed = output<void>();\n\n readonly _id = `neu-alert-${++_seq}`;\n readonly _dismissed = signal(false);\n\n readonly _resolvedIcon = computed(() => this.icon() || DEFAULT_ICONS[this.type()]);\n\n readonly liveRegion = computed(() => (this.type() === 'error' ? 'assertive' : 'polite'));\n\n readonly hostClasses = computed(() => ({\n 'neu-alert': true,\n [`neu-alert--${this.type()}`]: true,\n 'neu-alert--outline': this.outline(),\n 'neu-alert--closable': this.closable(),\n 'neu-alert--with-icon': this.showIcon(),\n 'neu-alert--dismissed': this._dismissed(),\n }));\n\n dismiss(): void {\n this._dismissed.set(true);\n this.closed.emit();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":";;;AAYA;AACA,MAAM,aAAa,GAAiC;AAClD,IAAA,IAAI,EAAE,GAAG;AACT,IAAA,OAAO,EAAE,GAAG;AACZ,IAAA,OAAO,EAAE,GAAG;AACZ,IAAA,KAAK,EAAE,GAAG;CACX;AAED,IAAI,IAAI,GAAG,CAAC;AAEZ;;;;;;;AAOG;MAmCU,iBAAiB,CAAA;;
|
|
1
|
+
{"version":3,"file":"neural-ui-core-alert.mjs","sources":["../../../../projects/ui-core/alert/neu-alert.component.ts","../../../../projects/ui-core/alert/neural-ui-core-alert.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n output,\n signal,\n} from '@angular/core';\n\nexport type NeuAlertType = 'info' | 'success' | 'warning' | 'error';\n\n/** Icono por defecto para cada tipo */\nconst DEFAULT_ICONS: Record<NeuAlertType, string> = {\n info: 'ℹ',\n success: '✓',\n warning: '⚠',\n error: '✕',\n};\n\nlet _seq = 0;\n\n/**\n * NeuralUI Alert Component\n *\n * Mensaje de alerta contextual con soporte de icono personalizado, slot de acciones y cierre.\n *\n * Uso: <neu-alert type=\"success\">Operación completada</neu-alert>\n * <neu-alert type=\"error\" [closable]=\"true\" (closed)=\"onClosed()\">Error de red</neu-alert>\n */\n@Component({\n selector: 'neu-alert',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { '[class]': 'hostClasses()', role: 'alert', '[attr.aria-live]': 'liveRegion()' },\n template: `\n @if (!_dismissed()) {\n @if (showIcon()) {\n <span class=\"neu-alert__icon\" aria-hidden=\"true\">{{ _resolvedIcon() }}</span>\n }\n <div class=\"neu-alert__body\">\n @if (title()) {\n <strong class=\"neu-alert__title\">{{ title() }}</strong>\n }\n <div class=\"neu-alert__content\">\n <ng-content />\n </div>\n <ng-content select=\"[neu-alert-actions]\" />\n </div>\n @if (closable()) {\n <button\n class=\"neu-alert__close\"\n type=\"button\"\n [attr.aria-label]=\"closeLabel()\"\n (click)=\"dismiss()\"\n >\n ×\n </button>\n }\n }\n `,\n styleUrl: './neu-alert.component.scss',\n})\nexport class NeuAlertComponent {\n /** Tipo semántico / Semantic type */\n readonly type = input<NeuAlertType>('info');\n\n /** Título opcional sobre el mensaje / Optional title above message */\n readonly title = input<string>('');\n\n /** Icono personalizado. Vacío = usa el icono por defecto del tipo / Custom icon. Empty = use default type icon */\n readonly icon = input<string>('');\n\n /** Muestra el icono / Shows the icon */\n readonly showIcon = input<boolean>(true);\n\n /** Permite cerrarse / Can be dismissed */\n readonly closable = input<boolean>(false);\n\n /** Variante outline (sin fondo sólido) / Outline variant (no solid background) */\n readonly outline = input<boolean>(false);\n\n /** Aria-label para el botón de cierre / Aria-label for the close button */\n readonly closeLabel = input<string>('Cerrar alerta');\n\n /** Emitido cuando se descarta la alerta / Emitted when the alert is dismissed */\n readonly closed = output<void>();\n\n readonly _id = `neu-alert-${++_seq}`;\n readonly _dismissed = signal(false);\n\n readonly _resolvedIcon = computed(() => this.icon() || DEFAULT_ICONS[this.type()]);\n\n readonly liveRegion = computed(() => (this.type() === 'error' ? 'assertive' : 'polite'));\n\n readonly hostClasses = computed(() => ({\n 'neu-alert': true,\n [`neu-alert--${this.type()}`]: true,\n 'neu-alert--outline': this.outline(),\n 'neu-alert--closable': this.closable(),\n 'neu-alert--with-icon': this.showIcon(),\n 'neu-alert--dismissed': this._dismissed(),\n }));\n\n dismiss(): void {\n this._dismissed.set(true);\n this.closed.emit();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
|
|
@@ -23,32 +23,21 @@ let _seq = 0;
|
|
|
23
23
|
*/
|
|
24
24
|
class NeuAutocompleteComponent {
|
|
25
25
|
// ── Inputs / Outputs ────────────────────────────────────────────
|
|
26
|
-
options = input([], /*
|
|
27
|
-
...(ngDevMode ? [{ debugName: "
|
|
28
|
-
|
|
29
|
-
...(ngDevMode ? [{ debugName: "
|
|
30
|
-
|
|
31
|
-
...(ngDevMode ? [{ debugName: "
|
|
32
|
-
|
|
33
|
-
...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
|
|
34
|
-
errorMessage = input('', /* @ts-ignore */
|
|
35
|
-
...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
|
|
36
|
-
emptyLabel = input('Sin resultados', /* @ts-ignore */
|
|
37
|
-
...(ngDevMode ? [{ debugName: "emptyLabel" }] : /* istanbul ignore next */ []));
|
|
38
|
-
minLength = input(0, /* @ts-ignore */
|
|
39
|
-
...(ngDevMode ? [{ debugName: "minLength" }] : /* istanbul ignore next */ []));
|
|
26
|
+
options = input([], ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
27
|
+
placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
28
|
+
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
29
|
+
hint = input('', ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
|
|
30
|
+
errorMessage = input('', ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
|
|
31
|
+
emptyLabel = input('Sin resultados', ...(ngDevMode ? [{ debugName: "emptyLabel" }] : /* istanbul ignore next */ []));
|
|
32
|
+
minLength = input(0, ...(ngDevMode ? [{ debugName: "minLength" }] : /* istanbul ignore next */ []));
|
|
40
33
|
/** Muestra el label como flotante (true) o estático encima del campo (false) / Shows the label as floating (true) or static above the field (false) */
|
|
41
|
-
floatingLabel = input(false, /*
|
|
42
|
-
...(ngDevMode ? [{ debugName: "floatingLabel" }] : /* istanbul ignore next */ []));
|
|
34
|
+
floatingLabel = input(false, ...(ngDevMode ? [{ debugName: "floatingLabel" }] : /* istanbul ignore next */ []));
|
|
43
35
|
/** Tamaño del campo: 'sm' = 36px | 'md' = 48px | 'lg' = 56px / Field size */
|
|
44
|
-
size = input('md', /*
|
|
45
|
-
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
36
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
46
37
|
/** Habilita scroll virtual para listas largas / Enables virtual scrolling for large result lists */
|
|
47
|
-
virtualScroll = input(false, /*
|
|
48
|
-
...(ngDevMode ? [{ debugName: "virtualScroll" }] : /* istanbul ignore next */ []));
|
|
38
|
+
virtualScroll = input(false, ...(ngDevMode ? [{ debugName: "virtualScroll" }] : /* istanbul ignore next */ []));
|
|
49
39
|
/** Número de resultados visibles en el viewport virtual / Number of visible results in the virtual viewport */
|
|
50
|
-
virtualScrollVisibleItems = input(8, /*
|
|
51
|
-
...(ngDevMode ? [{ debugName: "virtualScrollVisibleItems" }] : /* istanbul ignore next */ []));
|
|
40
|
+
virtualScrollVisibleItems = input(8, ...(ngDevMode ? [{ debugName: "virtualScrollVisibleItems" }] : /* istanbul ignore next */ []));
|
|
52
41
|
/** Emitido al seleccionar una opción / Emitted when an option is selected */
|
|
53
42
|
optionSelected = output();
|
|
54
43
|
/** Emitido al cambiar el texto del input / Emitted on query change */
|
|
@@ -56,20 +45,13 @@ class NeuAutocompleteComponent {
|
|
|
56
45
|
// ── Internal state ───────────────────────────────────────────────
|
|
57
46
|
_id = `neu-autocomplete-${++_seq}`;
|
|
58
47
|
_listId = `${this._id}-list`;
|
|
59
|
-
_query = signal('', /*
|
|
60
|
-
...(ngDevMode ? [{ debugName: "
|
|
61
|
-
|
|
62
|
-
...(ngDevMode ? [{ debugName: "
|
|
63
|
-
|
|
64
|
-
...(ngDevMode ? [{ debugName: "
|
|
65
|
-
|
|
66
|
-
...(ngDevMode ? [{ debugName: "_cvaDisabled" }] : /* istanbul ignore next */ []));
|
|
67
|
-
_focused = signal(false, /* @ts-ignore */
|
|
68
|
-
...(ngDevMode ? [{ debugName: "_focused" }] : /* istanbul ignore next */ []));
|
|
69
|
-
_viewport = viewChild(CdkVirtualScrollViewport, /* @ts-ignore */
|
|
70
|
-
...(ngDevMode ? [{ debugName: "_viewport" }] : /* istanbul ignore next */ []));
|
|
71
|
-
overlayWidth = signal(null, /* @ts-ignore */
|
|
72
|
-
...(ngDevMode ? [{ debugName: "overlayWidth" }] : /* istanbul ignore next */ []));
|
|
48
|
+
_query = signal('', ...(ngDevMode ? [{ debugName: "_query" }] : /* istanbul ignore next */ []));
|
|
49
|
+
_isOpen = signal(false, ...(ngDevMode ? [{ debugName: "_isOpen" }] : /* istanbul ignore next */ []));
|
|
50
|
+
_activeIndex = signal(-1, ...(ngDevMode ? [{ debugName: "_activeIndex" }] : /* istanbul ignore next */ []));
|
|
51
|
+
_cvaDisabled = signal(false, ...(ngDevMode ? [{ debugName: "_cvaDisabled" }] : /* istanbul ignore next */ []));
|
|
52
|
+
_focused = signal(false, ...(ngDevMode ? [{ debugName: "_focused" }] : /* istanbul ignore next */ []));
|
|
53
|
+
_viewport = viewChild(CdkVirtualScrollViewport, ...(ngDevMode ? [{ debugName: "_viewport" }] : /* istanbul ignore next */ []));
|
|
54
|
+
overlayWidth = signal(null, ...(ngDevMode ? [{ debugName: "overlayWidth" }] : /* istanbul ignore next */ []));
|
|
73
55
|
_viewportMargin = 16;
|
|
74
56
|
overlayPositions = [
|
|
75
57
|
{
|
|
@@ -116,15 +98,12 @@ class NeuAutocompleteComponent {
|
|
|
116
98
|
if (q.length < this.minLength())
|
|
117
99
|
return [];
|
|
118
100
|
return this.options().filter((o) => o.label.toLowerCase().includes(q));
|
|
119
|
-
}, /*
|
|
120
|
-
...(ngDevMode ? [{ debugName: "_filtered" }] : /* istanbul ignore next */ []));
|
|
101
|
+
}, ...(ngDevMode ? [{ debugName: "_filtered" }] : /* istanbul ignore next */ []));
|
|
121
102
|
_activeId = computed(() => {
|
|
122
103
|
const i = this._activeIndex();
|
|
123
104
|
return i >= 0 ? this._optionId(i) : null;
|
|
124
|
-
}, /*
|
|
125
|
-
...(ngDevMode ? [{ debugName: "
|
|
126
|
-
hasError = computed(() => !!this.errorMessage(), /* @ts-ignore */
|
|
127
|
-
...(ngDevMode ? [{ debugName: "hasError" }] : /* istanbul ignore next */ []));
|
|
105
|
+
}, ...(ngDevMode ? [{ debugName: "_activeId" }] : /* istanbul ignore next */ []));
|
|
106
|
+
hasError = computed(() => !!this.errorMessage(), ...(ngDevMode ? [{ debugName: "hasError" }] : /* istanbul ignore next */ []));
|
|
128
107
|
describedBy = computed(() => {
|
|
129
108
|
if (this.hasError()) {
|
|
130
109
|
return `${this._id}-error`;
|
|
@@ -133,8 +112,7 @@ class NeuAutocompleteComponent {
|
|
|
133
112
|
return `${this._id}-hint`;
|
|
134
113
|
}
|
|
135
114
|
return null;
|
|
136
|
-
}, /*
|
|
137
|
-
...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
|
|
115
|
+
}, ...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
|
|
138
116
|
resultsAnnouncement = computed(() => {
|
|
139
117
|
const query = this._query().trim();
|
|
140
118
|
if (!query || !this._isOpen()) {
|
|
@@ -145,8 +123,7 @@ class NeuAutocompleteComponent {
|
|
|
145
123
|
return this.emptyLabel();
|
|
146
124
|
}
|
|
147
125
|
return total === 1 ? '1 resultado disponible' : `${total} resultados disponibles`;
|
|
148
|
-
}, /*
|
|
149
|
-
...(ngDevMode ? [{ debugName: "resultsAnnouncement" }] : /* istanbul ignore next */ []));
|
|
126
|
+
}, ...(ngDevMode ? [{ debugName: "resultsAnnouncement" }] : /* istanbul ignore next */ []));
|
|
150
127
|
virtualScrollItemSize = computed(() => {
|
|
151
128
|
switch (this.size()) {
|
|
152
129
|
case 'sm':
|
|
@@ -156,10 +133,8 @@ class NeuAutocompleteComponent {
|
|
|
156
133
|
default:
|
|
157
134
|
return 40;
|
|
158
135
|
}
|
|
159
|
-
}, /*
|
|
160
|
-
...(ngDevMode ? [{ debugName: "
|
|
161
|
-
virtualViewportHeight = computed(() => `${this.virtualScrollVisibleItems() * this.virtualScrollItemSize()}px`, /* @ts-ignore */
|
|
162
|
-
...(ngDevMode ? [{ debugName: "virtualViewportHeight" }] : /* istanbul ignore next */ []));
|
|
136
|
+
}, ...(ngDevMode ? [{ debugName: "virtualScrollItemSize" }] : /* istanbul ignore next */ []));
|
|
137
|
+
virtualViewportHeight = computed(() => `${this.virtualScrollVisibleItems() * this.virtualScrollItemSize()}px`, ...(ngDevMode ? [{ debugName: "virtualViewportHeight" }] : /* istanbul ignore next */ []));
|
|
163
138
|
trackByOption = (index, option) => option.value ?? option.label ?? index;
|
|
164
139
|
_optionId(i) {
|
|
165
140
|
return `${this._listId}-opt-${i}`;
|
|
@@ -334,8 +309,8 @@ class NeuAutocompleteComponent {
|
|
|
334
309
|
setDisabledState(d) {
|
|
335
310
|
this._cvaDisabled.set(d);
|
|
336
311
|
}
|
|
337
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
338
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
312
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuAutocompleteComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
313
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: NeuAutocompleteComponent, isStandalone: true, selector: "neu-autocomplete", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, emptyLabel: { classPropertyName: "emptyLabel", publicName: "emptyLabel", isSignal: true, isRequired: false, transformFunction: null }, minLength: { classPropertyName: "minLength", publicName: "minLength", isSignal: true, isRequired: false, transformFunction: null }, floatingLabel: { classPropertyName: "floatingLabel", publicName: "floatingLabel", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, virtualScroll: { classPropertyName: "virtualScroll", publicName: "virtualScroll", isSignal: true, isRequired: false, transformFunction: null }, virtualScrollVisibleItems: { classPropertyName: "virtualScrollVisibleItems", publicName: "virtualScrollVisibleItems", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { optionSelected: "optionSelected", queryChange: "queryChange" }, host: { listeners: { "document:mousedown": "onDocClick($event)", "window:resize": "onWindowResize()" }, properties: { "class.neu-autocomplete--open": "_isOpen()", "class.neu-autocomplete--disabled": "_cvaDisabled()", "class.neu-autocomplete--floating": "floatingLabel()", "class.neu-autocomplete--focused": "_focused()", "class.neu-autocomplete--has-value": "!!_query()", "class.neu-autocomplete--sm": "size() === \"sm\"", "class.neu-autocomplete--lg": "size() === \"lg\"", "style.--neu-autocomplete-option-height": "virtualScrollItemSize() + \"px\"" }, classAttribute: "neu-autocomplete" }, providers: [
|
|
339
314
|
{
|
|
340
315
|
provide: NG_VALUE_ACCESSOR,
|
|
341
316
|
useExisting: forwardRef(() => NeuAutocompleteComponent),
|
|
@@ -467,7 +442,7 @@ class NeuAutocompleteComponent {
|
|
|
467
442
|
}
|
|
468
443
|
`, isInline: true, styles: ["@charset \"UTF-8\";.neu-autocomplete{position:relative;display:block}.neu-autocomplete--disabled{opacity:.55;pointer-events:none}.neu-autocomplete--sm .neu-autocomplete__input{height:36px;font-size:var(--neu-text-sm, .875rem)}.neu-autocomplete--lg .neu-autocomplete__input{height:56px}.neu-autocomplete--floating.neu-autocomplete--focused .neu-autocomplete__input::placeholder{color:var(--neu-text-disabled, #9ca3af)}.neu-autocomplete--floating.neu-autocomplete--focused .neu-autocomplete__input{border-color:var(--neu-primary, #0ea5e9);box-shadow:var(--neu-focus-ring, 0 0 0 3px rgba(14, 165, 233, .2))}.neu-autocomplete__label{display:block;margin-bottom:6px;font-size:var(--neu-text-sm, .875rem);font-weight:500;color:var(--neu-text, #0f172a);line-height:1.4}.neu-autocomplete__input-wrap{position:relative;display:flex;align-items:center}.neu-autocomplete__input{width:100%;height:48px;padding:0 36px 0 12px;border:1.5px solid var(--neu-border, #d1d5db);border-radius:var(--neu-radius, 8px);background:var(--neu-surface, #ffffff);color:var(--neu-text, #111);font-size:.875rem;line-height:1.4;outline:none;transition:border-color var(--neu-transition, .12s),box-shadow var(--neu-transition, .12s),background-color var(--neu-transition, .12s)}.neu-autocomplete__input:hover{border-color:var(--neu-border-hover, var(--neu-border, #d1d5db))}.neu-autocomplete__input:focus,.neu-autocomplete__input:focus-visible{border-color:var(--neu-primary, #0ea5e9);box-shadow:var(--neu-focus-ring, 0 0 0 3px rgba(14, 165, 233, .2))}.neu-autocomplete__input[disabled]{background:var(--neu-surface-2, #f3f4f6);color:var(--neu-text-disabled, #9ca3af)}.neu-autocomplete--floating .neu-autocomplete__input::placeholder{color:transparent;transition:color var(--neu-transition)}.neu-autocomplete__floating-label{position:absolute;left:var(--neu-space-3, 12px);top:50%;transform:translateY(-50%);font-size:var(--neu-text-base, .875rem);color:var(--neu-text-muted, #6b7280);pointer-events:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:calc(100% - var(--neu-space-6, 24px));transition:top var(--neu-transition, .12s),font-size var(--neu-transition, .12s),color var(--neu-transition, .12s),transform var(--neu-transition, .12s),padding var(--neu-transition, .12s),background var(--neu-transition, .12s)}.neu-autocomplete--focused .neu-autocomplete__floating-label,.neu-autocomplete--has-value .neu-autocomplete__floating-label{top:0;transform:translateY(-50%);font-size:12px;font-weight:600;letter-spacing:.01em;background:var(--neu-surface, #fff);padding:0 4px;left:calc(var(--neu-space-3, 12px) - 4px)}.neu-autocomplete--focused .neu-autocomplete__floating-label{color:var(--neu-primary, #0ea5e9)}.neu-autocomplete__clear{all:unset;position:absolute;right:10px;display:flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:50%;font-size:.875rem;color:var(--neu-text-muted, #6b7280);cursor:pointer}.neu-autocomplete__clear:hover{color:var(--neu-text, #111);background:var(--neu-surface-3, #e5e7eb)}.neu-autocomplete__clear:focus-visible{outline:2px solid var(--neu-primary, #0ea5e9);outline-offset:2px}.neu-autocomplete__list{all:unset;display:block;position:relative;background:var(--neu-surface, #ffffff);border:1.5px solid var(--neu-border, #e5e7eb);border-radius:var(--neu-radius-lg, 12px);box-shadow:var(--neu-shadow-lg, 0 8px 20px -4px rgba(0, 0, 0, .1));max-height:240px;overflow-y:auto;padding:6px;z-index:1000;animation:neu-ac-in 80ms ease}.neu-autocomplete__list--virtual{padding:0;overflow:hidden}@keyframes neu-ac-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.neu-autocomplete__option{display:flex;align-items:center;padding:7px 10px;min-height:var(--neu-autocomplete-option-height, 40px);box-sizing:border-box;border-radius:var(--neu-radius-md, 8px);font-size:.875rem;color:var(--neu-text, #111);cursor:pointer}.neu-autocomplete__option:hover:not(.neu-autocomplete__option--disabled){background:var(--neu-surface-2, #f3f4f6)}.neu-autocomplete__option--active{background:var(--neu-primary-50, rgba(14, 165, 233, .12));color:var(--neu-primary, #0ea5e9);font-weight:500}.neu-autocomplete__option--disabled{opacity:.4;cursor:not-allowed}.neu-autocomplete__empty{position:relative;background:var(--neu-surface, #ffffff);border:1.5px solid var(--neu-border, #e5e7eb);border-radius:var(--neu-radius-lg, 12px);padding:12px 16px;font-size:.875rem;color:var(--neu-text-muted, #6b7280);text-align:center}.neu-autocomplete__hint,.neu-autocomplete__error{margin:6px 0 0;font-size:var(--neu-text-sm, .875rem);line-height:1.4}.neu-autocomplete__hint{color:var(--neu-text-muted, #6b7280)}.neu-autocomplete__error{color:var(--neu-danger, #dc2626)}.neu-autocomplete__sr-status{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"], dependencies: [{ kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1.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", "cdkConnectedOverlayUsePopover", "cdkConnectedOverlayMatchWidth", "cdkConnectedOverlay"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i1.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "directive", type: i1.ɵɵCdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i1.ɵɵCdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i1.ɵɵCdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }, { kind: "ngmodule", type: ScrollingModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
469
444
|
}
|
|
470
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
445
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuAutocompleteComponent, decorators: [{
|
|
471
446
|
type: Component,
|
|
472
447
|
args: [{ selector: 'neu-autocomplete', imports: [OverlayModule, ScrollingModule], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
473
448
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neural-ui-core-autocomplete.mjs","sources":["../../../../projects/ui-core/autocomplete/neu-autocomplete.component.ts","../../../../projects/ui-core/autocomplete/neural-ui-core-autocomplete.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n HostListener,\n ViewEncapsulation,\n computed,\n forwardRef,\n inject,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { DOCUMENT } from '@angular/common';\nimport { ConnectedPosition, Overlay, OverlayModule } from '@angular/cdk/overlay';\nimport { CdkVirtualScrollViewport, ScrollingModule } from '@angular/cdk/scrolling';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\nexport interface NeuAutocompleteOption {\n /** Valor / Value */\n value: unknown;\n /** Texto visible / Display text */\n label: string;\n /** Desactiva la opción / Disables the option */\n disabled?: boolean;\n}\n\nlet _seq = 0;\n\n/**\n * NeuralUI Autocomplete\n *\n * Input con lista de sugerencias filtradas y navegación por teclado.\n * Implementa CVA para uso en formularios reactivos.\n *\n * Uso:\n * <neu-autocomplete\n * [options]=\"opts\"\n * placeholder=\"Buscar…\"\n * [formControl]=\"selectedCtrl\"\n * (optionSelected)=\"onSelect($event)\"\n * />\n */\n@Component({\n selector: 'neu-autocomplete',\n imports: [OverlayModule, ScrollingModule],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => NeuAutocompleteComponent),\n multi: true,\n },\n ],\n host: {\n class: 'neu-autocomplete',\n '[class.neu-autocomplete--open]': '_isOpen()',\n '[class.neu-autocomplete--disabled]': '_cvaDisabled()',\n '[class.neu-autocomplete--floating]': 'floatingLabel()',\n '[class.neu-autocomplete--focused]': '_focused()',\n '[class.neu-autocomplete--has-value]': '!!_query()',\n '[class.neu-autocomplete--sm]': 'size() === \"sm\"',\n '[class.neu-autocomplete--lg]': 'size() === \"lg\"',\n '[style.--neu-autocomplete-option-height]': 'virtualScrollItemSize() + \"px\"',\n },\n template: `\n @if (!floatingLabel() && label()) {\n <label class=\"neu-autocomplete__label\" [for]=\"_id\">{{ label() }}</label>\n }\n <div\n cdkOverlayOrigin\n #autocompleteOrigin=\"cdkOverlayOrigin\"\n class=\"neu-autocomplete__input-wrap\"\n [class.neu-autocomplete__input-wrap--focused]=\"_focused()\"\n [class.neu-autocomplete__input-wrap--has-value]=\"!!_query()\"\n >\n <input\n #inputEl\n class=\"neu-autocomplete__input\"\n type=\"text\"\n autocomplete=\"off\"\n role=\"combobox\"\n [id]=\"_id\"\n [attr.placeholder]=\"floatingLabel() ? ' ' : placeholder() || null\"\n [attr.aria-label]=\"label() || placeholder()\"\n [attr.aria-autocomplete]=\"'list'\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"_isOpen() ? 'true' : 'false'\"\n [attr.aria-controls]=\"_listId\"\n [attr.aria-activedescendant]=\"_activeId()\"\n [attr.aria-invalid]=\"hasError() ? 'true' : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [disabled]=\"_cvaDisabled()\"\n [value]=\"_query()\"\n (input)=\"onQueryChange($any($event.target).value)\"\n (focus)=\"_onFocus()\"\n (blur)=\"_onBlur()\"\n (keydown)=\"onKeyDown($event)\"\n />\n @if (floatingLabel() && label()) {\n <label class=\"neu-autocomplete__floating-label\" [for]=\"_id\">{{ label() }}</label>\n }\n @if (_query() && !_cvaDisabled()) {\n <button\n type=\"button\"\n class=\"neu-autocomplete__clear\"\n aria-label=\"Limpiar\"\n tabindex=\"-1\"\n (click)=\"clear()\"\n >\n ×\n </button>\n }\n </div>\n <div class=\"neu-autocomplete__sr-status\" aria-live=\"polite\" aria-atomic=\"true\">\n {{ resultsAnnouncement() }}\n </div>\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"autocompleteOrigin\"\n [cdkConnectedOverlayOpen]=\"_isOpen()\"\n [cdkConnectedOverlayPositions]=\"overlayPositions\"\n [cdkConnectedOverlayScrollStrategy]=\"overlayScrollStrategy\"\n [cdkConnectedOverlayPush]=\"true\"\n [cdkConnectedOverlayViewportMargin]=\"_viewportMargin\"\n (detach)=\"_closePanel()\"\n >\n @if (_filtered().length) {\n @if (virtualScroll()) {\n <cdk-virtual-scroll-viewport\n class=\"neu-autocomplete__list neu-autocomplete__list--virtual\"\n role=\"listbox\"\n [id]=\"_listId\"\n [attr.aria-label]=\"label() || placeholder()\"\n [itemSize]=\"virtualScrollItemSize()\"\n [style.height]=\"virtualViewportHeight()\"\n [style.width.px]=\"overlayWidth()\"\n >\n <div\n *cdkVirtualFor=\"let opt of _filtered(); trackBy: trackByOption; let i = index\"\n class=\"neu-autocomplete__option\"\n role=\"option\"\n [id]=\"_optionId(i)\"\n [class.neu-autocomplete__option--active]=\"_activeIndex() === i\"\n [class.neu-autocomplete__option--disabled]=\"opt.disabled\"\n [attr.aria-selected]=\"_activeIndex() === i\"\n [attr.aria-disabled]=\"opt.disabled ?? false\"\n (mousedown)=\"selectOption(opt)\"\n >\n {{ opt.label }}\n </div>\n </cdk-virtual-scroll-viewport>\n } @else {\n <ul\n class=\"neu-autocomplete__list\"\n role=\"listbox\"\n [id]=\"_listId\"\n [attr.aria-label]=\"label() || placeholder()\"\n [style.width.px]=\"overlayWidth()\"\n >\n @for (opt of _filtered(); track opt.label; let i = $index) {\n <li\n class=\"neu-autocomplete__option\"\n role=\"option\"\n [id]=\"_optionId(i)\"\n [class.neu-autocomplete__option--active]=\"_activeIndex() === i\"\n [class.neu-autocomplete__option--disabled]=\"opt.disabled\"\n [attr.aria-selected]=\"_activeIndex() === i\"\n [attr.aria-disabled]=\"opt.disabled ?? false\"\n (mousedown)=\"selectOption(opt)\"\n >\n {{ opt.label }}\n </li>\n }\n </ul>\n }\n } @else {\n <div class=\"neu-autocomplete__empty\" role=\"status\" [style.width.px]=\"overlayWidth()\">\n {{ emptyLabel() }}\n </div>\n }\n </ng-template>\n @if (hasError()) {\n <p class=\"neu-autocomplete__error\" [id]=\"_id + '-error'\" role=\"alert\">\n {{ errorMessage() }}\n </p>\n } @else if (hint()) {\n <p class=\"neu-autocomplete__hint\" [id]=\"_id + '-hint'\">{{ hint() }}</p>\n }\n `,\n styleUrl: './neu-autocomplete.component.scss',\n})\nexport class NeuAutocompleteComponent implements ControlValueAccessor {\n // ── Inputs / Outputs ────────────────────────────────────────────\n readonly options = input<NeuAutocompleteOption[]>([]);\n readonly placeholder = input<string>('');\n readonly label = input<string>('');\n readonly hint = input<string>('');\n readonly errorMessage = input<string>('');\n readonly emptyLabel = input<string>('Sin resultados');\n readonly minLength = input<number>(0);\n /** Muestra el label como flotante (true) o estático encima del campo (false) / Shows the label as floating (true) or static above the field (false) */\n readonly floatingLabel = input<boolean>(false);\n /** Tamaño del campo: 'sm' = 36px | 'md' = 48px | 'lg' = 56px / Field size */\n readonly size = input<'sm' | 'md' | 'lg'>('md');\n\n /** Habilita scroll virtual para listas largas / Enables virtual scrolling for large result lists */\n readonly virtualScroll = input<boolean>(false);\n\n /** Número de resultados visibles en el viewport virtual / Number of visible results in the virtual viewport */\n readonly virtualScrollVisibleItems = input<number>(8);\n\n /** Emitido al seleccionar una opción / Emitted when an option is selected */\n readonly optionSelected = output<NeuAutocompleteOption>();\n\n /** Emitido al cambiar el texto del input / Emitted on query change */\n readonly queryChange = output<string>();\n\n // ── Internal state ───────────────────────────────────────────────\n readonly _id = `neu-autocomplete-${++_seq}`;\n readonly _listId = `${this._id}-list`;\n\n readonly _query = signal('');\n readonly _isOpen = signal(false);\n readonly _activeIndex = signal(-1);\n readonly _cvaDisabled = signal(false);\n readonly _focused = signal(false);\n private readonly _viewport = viewChild(CdkVirtualScrollViewport);\n readonly overlayWidth = signal<number | null>(null);\n readonly _viewportMargin = 16;\n readonly overlayPositions: ConnectedPosition[] = [\n {\n originX: 'start',\n originY: 'bottom',\n overlayX: 'start',\n overlayY: 'top',\n offsetY: 4,\n },\n {\n originX: 'start',\n originY: 'top',\n overlayX: 'start',\n overlayY: 'bottom',\n offsetY: -4,\n },\n {\n originX: 'end',\n originY: 'bottom',\n overlayX: 'end',\n overlayY: 'top',\n offsetY: 4,\n },\n {\n originX: 'end',\n originY: 'top',\n overlayX: 'end',\n overlayY: 'bottom',\n offsetY: -4,\n },\n ];\n private readonly _document = inject(DOCUMENT);\n private readonly _overlay = inject(Overlay);\n readonly overlayScrollStrategy = this._overlay.scrollStrategies.reposition();\n\n private _onChange: (v: unknown) => void = () => {};\n private _onTouched: () => void = () => {};\n\n // ── Computed ─────────────────────────────────────────────────────\n readonly _filtered = computed(() => {\n const q = this._query().toLowerCase().trim();\n // Con query vacía nunca mostramos opciones (no queremos comportarnos como un select).\n // Empty query → never show options (autocomplete ≠ select).\n if (!q) return [];\n if (q.length < this.minLength()) return [];\n return this.options().filter((o) => o.label.toLowerCase().includes(q));\n });\n\n readonly _activeId = computed(() => {\n const i = this._activeIndex();\n return i >= 0 ? this._optionId(i) : null;\n });\n\n readonly hasError = computed(() => !!this.errorMessage());\n\n readonly describedBy = computed(() => {\n if (this.hasError()) {\n return `${this._id}-error`;\n }\n if (this.hint()) {\n return `${this._id}-hint`;\n }\n return null;\n });\n\n readonly resultsAnnouncement = computed(() => {\n const query = this._query().trim();\n if (!query || !this._isOpen()) {\n return '';\n }\n\n const total = this._filtered().length;\n if (!total) {\n return this.emptyLabel();\n }\n\n return total === 1 ? '1 resultado disponible' : `${total} resultados disponibles`;\n });\n\n readonly virtualScrollItemSize = computed(() => {\n switch (this.size()) {\n case 'sm':\n return 36;\n case 'lg':\n return 52;\n default:\n return 40;\n }\n });\n\n readonly virtualViewportHeight = computed(\n () => `${this.virtualScrollVisibleItems() * this.virtualScrollItemSize()}px`,\n );\n\n readonly trackByOption = (index: number, option: NeuAutocompleteOption) =>\n option.value ?? option.label ?? index;\n\n _optionId(i: number): string {\n return `${this._listId}-opt-${i}`;\n }\n\n // ── HostListener close on outside click ─────────────────────────\n private readonly _el = inject(ElementRef<HTMLElement>);\n\n @HostListener('document:mousedown', ['$event'])\n onDocClick(e: MouseEvent): void {\n const target = e.target as Element | null;\n const isInsideOverlay = !!target?.closest('.neu-autocomplete__list, .neu-autocomplete__empty');\n if (!this._el.nativeElement.contains(e.target as Node) && !isInsideOverlay) {\n this._closePanel();\n }\n }\n\n @HostListener('window:resize')\n onWindowResize(): void {\n if (this._isOpen()) {\n this._syncOverlayWidth();\n }\n }\n\n // ── Event handlers ───────────────────────────────────────────────\n onQueryChange(q: string): void {\n this._query.set(q);\n this._activeIndex.set(-1);\n // Sólo abrimos si hay texto suficiente; si no, cerramos.\n // Only open when there is enough text; otherwise close.\n const minLen = Math.max(1, this.minLength());\n const shouldOpen = q.trim().length >= minLen;\n if (shouldOpen) {\n this._syncOverlayWidth();\n }\n this._isOpen.set(shouldOpen);\n this.queryChange.emit(q);\n // CVA — emit null when query is cleared\n if (!q) {\n this._onChange(null);\n }\n }\n\n _onFocus(): void {\n this._focused.set(true);\n // Abre el dropdown solo si ya hay texto escrito / Only open when there is already a query.\n if (this._query().trim().length >= Math.max(1, this.minLength())) {\n this._syncOverlayWidth();\n this._isOpen.set(true);\n }\n }\n\n _onBlur(): void {\n this._focused.set(false);\n this._onTouched();\n // Small delay to allow mousedown on option to fire first\n setTimeout(() => this._closePanel(), 150);\n }\n\n onKeyDown(e: KeyboardEvent): void {\n const total = this._filtered().length;\n if (!total && e.key !== 'Escape') return;\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n this._syncOverlayWidth();\n this._moveActiveIndex(1);\n this._isOpen.set(true);\n this._scrollActiveOptionIntoView();\n break;\n case 'ArrowUp':\n e.preventDefault();\n this._moveActiveIndex(-1);\n this._scrollActiveOptionIntoView();\n break;\n case 'Enter': {\n const idx = this._activeIndex();\n const opt = this._filtered()[idx];\n if (opt && !opt.disabled) this.selectOption(opt);\n break;\n }\n case 'Escape':\n this._isOpen.set(false);\n this._activeIndex.set(-1);\n break;\n }\n }\n\n private _moveActiveIndex(step: 1 | -1): void {\n const filtered = this._filtered();\n if (!filtered.length) {\n this._activeIndex.set(-1);\n return;\n }\n\n const currentIndex = this._activeIndex();\n let nextIndex = currentIndex;\n\n for (let count = 0; count < filtered.length; count += 1) {\n nextIndex =\n step === 1 ? Math.min(nextIndex + 1, filtered.length - 1) : Math.max(nextIndex - 1, 0);\n\n if (!filtered[nextIndex]?.disabled) {\n this._activeIndex.set(nextIndex);\n return;\n }\n\n if ((step === 1 && nextIndex === filtered.length - 1) || (step === -1 && nextIndex === 0)) {\n break;\n }\n }\n\n if (currentIndex === -1) {\n this._activeIndex.set(filtered.findIndex((option) => !option.disabled));\n }\n }\n\n selectOption(opt: NeuAutocompleteOption): void {\n if (opt.disabled) return;\n this._query.set(opt.label);\n this._isOpen.set(false);\n this._activeIndex.set(-1);\n this._onChange(opt.value);\n this.optionSelected.emit(opt);\n }\n\n clear(): void {\n this._query.set('');\n this._onChange(null);\n this._isOpen.set(false);\n this._activeIndex.set(-1);\n this.queryChange.emit('');\n }\n\n _closePanel(): void {\n this._isOpen.set(false);\n this._activeIndex.set(-1);\n }\n\n private _scrollActiveOptionIntoView(): void {\n const activeIndex = this._activeIndex();\n if (activeIndex < 0) {\n return;\n }\n\n if (this.virtualScroll()) {\n requestAnimationFrame(() => {\n this._viewport()?.scrollToIndex(activeIndex, 'auto');\n this._viewport()?.checkViewportSize();\n });\n return;\n }\n\n requestAnimationFrame(() => {\n const activeOption = this._el.nativeElement.querySelector(\n `#${this._optionId(activeIndex)}`,\n ) as HTMLElement | null;\n const overlayOption =\n activeOption ?? this._document.getElementById(this._optionId(activeIndex));\n if (typeof overlayOption?.scrollIntoView === 'function') {\n overlayOption.scrollIntoView({ block: 'nearest' });\n }\n });\n }\n\n private _syncOverlayWidth(): void {\n const trigger = this._el.nativeElement.querySelector(\n '.neu-autocomplete__input-wrap',\n ) as HTMLElement | null;\n if (!trigger) {\n return;\n }\n const width =\n typeof trigger.getBoundingClientRect === 'function'\n ? trigger.getBoundingClientRect().width\n : 0;\n this.overlayWidth.set(Math.min(width, window.innerWidth - 32));\n if (this.virtualScroll()) {\n requestAnimationFrame(() => this._viewport()?.checkViewportSize());\n }\n }\n\n // ── CVA ──────────────────────────────────────────────────────────\n writeValue(val: unknown): void {\n if (val === null || val === undefined) {\n this._query.set('');\n return;\n }\n const match = this.options().find((o) => o.value === val);\n this._query.set(match ? match.label : String(val));\n }\n\n registerOnChange(fn: (v: unknown) => void): void {\n this._onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this._onTouched = fn;\n }\n\n setDisabledState(d: boolean): void {\n this._cvaDisabled.set(d);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"neural-ui-core-autocomplete.mjs","sources":["../../../../projects/ui-core/autocomplete/neu-autocomplete.component.ts","../../../../projects/ui-core/autocomplete/neural-ui-core-autocomplete.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n HostListener,\n ViewEncapsulation,\n computed,\n forwardRef,\n inject,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { DOCUMENT } from '@angular/common';\nimport { ConnectedPosition, Overlay, OverlayModule } from '@angular/cdk/overlay';\nimport { CdkVirtualScrollViewport, ScrollingModule } from '@angular/cdk/scrolling';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\nexport interface NeuAutocompleteOption {\n /** Valor / Value */\n value: unknown;\n /** Texto visible / Display text */\n label: string;\n /** Desactiva la opción / Disables the option */\n disabled?: boolean;\n}\n\nlet _seq = 0;\n\n/**\n * NeuralUI Autocomplete\n *\n * Input con lista de sugerencias filtradas y navegación por teclado.\n * Implementa CVA para uso en formularios reactivos.\n *\n * Uso:\n * <neu-autocomplete\n * [options]=\"opts\"\n * placeholder=\"Buscar…\"\n * [formControl]=\"selectedCtrl\"\n * (optionSelected)=\"onSelect($event)\"\n * />\n */\n@Component({\n selector: 'neu-autocomplete',\n imports: [OverlayModule, ScrollingModule],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => NeuAutocompleteComponent),\n multi: true,\n },\n ],\n host: {\n class: 'neu-autocomplete',\n '[class.neu-autocomplete--open]': '_isOpen()',\n '[class.neu-autocomplete--disabled]': '_cvaDisabled()',\n '[class.neu-autocomplete--floating]': 'floatingLabel()',\n '[class.neu-autocomplete--focused]': '_focused()',\n '[class.neu-autocomplete--has-value]': '!!_query()',\n '[class.neu-autocomplete--sm]': 'size() === \"sm\"',\n '[class.neu-autocomplete--lg]': 'size() === \"lg\"',\n '[style.--neu-autocomplete-option-height]': 'virtualScrollItemSize() + \"px\"',\n },\n template: `\n @if (!floatingLabel() && label()) {\n <label class=\"neu-autocomplete__label\" [for]=\"_id\">{{ label() }}</label>\n }\n <div\n cdkOverlayOrigin\n #autocompleteOrigin=\"cdkOverlayOrigin\"\n class=\"neu-autocomplete__input-wrap\"\n [class.neu-autocomplete__input-wrap--focused]=\"_focused()\"\n [class.neu-autocomplete__input-wrap--has-value]=\"!!_query()\"\n >\n <input\n #inputEl\n class=\"neu-autocomplete__input\"\n type=\"text\"\n autocomplete=\"off\"\n role=\"combobox\"\n [id]=\"_id\"\n [attr.placeholder]=\"floatingLabel() ? ' ' : placeholder() || null\"\n [attr.aria-label]=\"label() || placeholder()\"\n [attr.aria-autocomplete]=\"'list'\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-expanded]=\"_isOpen() ? 'true' : 'false'\"\n [attr.aria-controls]=\"_listId\"\n [attr.aria-activedescendant]=\"_activeId()\"\n [attr.aria-invalid]=\"hasError() ? 'true' : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [disabled]=\"_cvaDisabled()\"\n [value]=\"_query()\"\n (input)=\"onQueryChange($any($event.target).value)\"\n (focus)=\"_onFocus()\"\n (blur)=\"_onBlur()\"\n (keydown)=\"onKeyDown($event)\"\n />\n @if (floatingLabel() && label()) {\n <label class=\"neu-autocomplete__floating-label\" [for]=\"_id\">{{ label() }}</label>\n }\n @if (_query() && !_cvaDisabled()) {\n <button\n type=\"button\"\n class=\"neu-autocomplete__clear\"\n aria-label=\"Limpiar\"\n tabindex=\"-1\"\n (click)=\"clear()\"\n >\n ×\n </button>\n }\n </div>\n <div class=\"neu-autocomplete__sr-status\" aria-live=\"polite\" aria-atomic=\"true\">\n {{ resultsAnnouncement() }}\n </div>\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"autocompleteOrigin\"\n [cdkConnectedOverlayOpen]=\"_isOpen()\"\n [cdkConnectedOverlayPositions]=\"overlayPositions\"\n [cdkConnectedOverlayScrollStrategy]=\"overlayScrollStrategy\"\n [cdkConnectedOverlayPush]=\"true\"\n [cdkConnectedOverlayViewportMargin]=\"_viewportMargin\"\n (detach)=\"_closePanel()\"\n >\n @if (_filtered().length) {\n @if (virtualScroll()) {\n <cdk-virtual-scroll-viewport\n class=\"neu-autocomplete__list neu-autocomplete__list--virtual\"\n role=\"listbox\"\n [id]=\"_listId\"\n [attr.aria-label]=\"label() || placeholder()\"\n [itemSize]=\"virtualScrollItemSize()\"\n [style.height]=\"virtualViewportHeight()\"\n [style.width.px]=\"overlayWidth()\"\n >\n <div\n *cdkVirtualFor=\"let opt of _filtered(); trackBy: trackByOption; let i = index\"\n class=\"neu-autocomplete__option\"\n role=\"option\"\n [id]=\"_optionId(i)\"\n [class.neu-autocomplete__option--active]=\"_activeIndex() === i\"\n [class.neu-autocomplete__option--disabled]=\"opt.disabled\"\n [attr.aria-selected]=\"_activeIndex() === i\"\n [attr.aria-disabled]=\"opt.disabled ?? false\"\n (mousedown)=\"selectOption(opt)\"\n >\n {{ opt.label }}\n </div>\n </cdk-virtual-scroll-viewport>\n } @else {\n <ul\n class=\"neu-autocomplete__list\"\n role=\"listbox\"\n [id]=\"_listId\"\n [attr.aria-label]=\"label() || placeholder()\"\n [style.width.px]=\"overlayWidth()\"\n >\n @for (opt of _filtered(); track opt.label; let i = $index) {\n <li\n class=\"neu-autocomplete__option\"\n role=\"option\"\n [id]=\"_optionId(i)\"\n [class.neu-autocomplete__option--active]=\"_activeIndex() === i\"\n [class.neu-autocomplete__option--disabled]=\"opt.disabled\"\n [attr.aria-selected]=\"_activeIndex() === i\"\n [attr.aria-disabled]=\"opt.disabled ?? false\"\n (mousedown)=\"selectOption(opt)\"\n >\n {{ opt.label }}\n </li>\n }\n </ul>\n }\n } @else {\n <div class=\"neu-autocomplete__empty\" role=\"status\" [style.width.px]=\"overlayWidth()\">\n {{ emptyLabel() }}\n </div>\n }\n </ng-template>\n @if (hasError()) {\n <p class=\"neu-autocomplete__error\" [id]=\"_id + '-error'\" role=\"alert\">\n {{ errorMessage() }}\n </p>\n } @else if (hint()) {\n <p class=\"neu-autocomplete__hint\" [id]=\"_id + '-hint'\">{{ hint() }}</p>\n }\n `,\n styleUrl: './neu-autocomplete.component.scss',\n})\nexport class NeuAutocompleteComponent implements ControlValueAccessor {\n // ── Inputs / Outputs ────────────────────────────────────────────\n readonly options = input<NeuAutocompleteOption[]>([]);\n readonly placeholder = input<string>('');\n readonly label = input<string>('');\n readonly hint = input<string>('');\n readonly errorMessage = input<string>('');\n readonly emptyLabel = input<string>('Sin resultados');\n readonly minLength = input<number>(0);\n /** Muestra el label como flotante (true) o estático encima del campo (false) / Shows the label as floating (true) or static above the field (false) */\n readonly floatingLabel = input<boolean>(false);\n /** Tamaño del campo: 'sm' = 36px | 'md' = 48px | 'lg' = 56px / Field size */\n readonly size = input<'sm' | 'md' | 'lg'>('md');\n\n /** Habilita scroll virtual para listas largas / Enables virtual scrolling for large result lists */\n readonly virtualScroll = input<boolean>(false);\n\n /** Número de resultados visibles en el viewport virtual / Number of visible results in the virtual viewport */\n readonly virtualScrollVisibleItems = input<number>(8);\n\n /** Emitido al seleccionar una opción / Emitted when an option is selected */\n readonly optionSelected = output<NeuAutocompleteOption>();\n\n /** Emitido al cambiar el texto del input / Emitted on query change */\n readonly queryChange = output<string>();\n\n // ── Internal state ───────────────────────────────────────────────\n readonly _id = `neu-autocomplete-${++_seq}`;\n readonly _listId = `${this._id}-list`;\n\n readonly _query = signal('');\n readonly _isOpen = signal(false);\n readonly _activeIndex = signal(-1);\n readonly _cvaDisabled = signal(false);\n readonly _focused = signal(false);\n private readonly _viewport = viewChild(CdkVirtualScrollViewport);\n readonly overlayWidth = signal<number | null>(null);\n readonly _viewportMargin = 16;\n readonly overlayPositions: ConnectedPosition[] = [\n {\n originX: 'start',\n originY: 'bottom',\n overlayX: 'start',\n overlayY: 'top',\n offsetY: 4,\n },\n {\n originX: 'start',\n originY: 'top',\n overlayX: 'start',\n overlayY: 'bottom',\n offsetY: -4,\n },\n {\n originX: 'end',\n originY: 'bottom',\n overlayX: 'end',\n overlayY: 'top',\n offsetY: 4,\n },\n {\n originX: 'end',\n originY: 'top',\n overlayX: 'end',\n overlayY: 'bottom',\n offsetY: -4,\n },\n ];\n private readonly _document = inject(DOCUMENT);\n private readonly _overlay = inject(Overlay);\n readonly overlayScrollStrategy = this._overlay.scrollStrategies.reposition();\n\n private _onChange: (v: unknown) => void = () => {};\n private _onTouched: () => void = () => {};\n\n // ── Computed ─────────────────────────────────────────────────────\n readonly _filtered = computed(() => {\n const q = this._query().toLowerCase().trim();\n // Con query vacía nunca mostramos opciones (no queremos comportarnos como un select).\n // Empty query → never show options (autocomplete ≠ select).\n if (!q) return [];\n if (q.length < this.minLength()) return [];\n return this.options().filter((o) => o.label.toLowerCase().includes(q));\n });\n\n readonly _activeId = computed(() => {\n const i = this._activeIndex();\n return i >= 0 ? this._optionId(i) : null;\n });\n\n readonly hasError = computed(() => !!this.errorMessage());\n\n readonly describedBy = computed(() => {\n if (this.hasError()) {\n return `${this._id}-error`;\n }\n if (this.hint()) {\n return `${this._id}-hint`;\n }\n return null;\n });\n\n readonly resultsAnnouncement = computed(() => {\n const query = this._query().trim();\n if (!query || !this._isOpen()) {\n return '';\n }\n\n const total = this._filtered().length;\n if (!total) {\n return this.emptyLabel();\n }\n\n return total === 1 ? '1 resultado disponible' : `${total} resultados disponibles`;\n });\n\n readonly virtualScrollItemSize = computed(() => {\n switch (this.size()) {\n case 'sm':\n return 36;\n case 'lg':\n return 52;\n default:\n return 40;\n }\n });\n\n readonly virtualViewportHeight = computed(\n () => `${this.virtualScrollVisibleItems() * this.virtualScrollItemSize()}px`,\n );\n\n readonly trackByOption = (index: number, option: NeuAutocompleteOption) =>\n option.value ?? option.label ?? index;\n\n _optionId(i: number): string {\n return `${this._listId}-opt-${i}`;\n }\n\n // ── HostListener close on outside click ─────────────────────────\n private readonly _el = inject(ElementRef<HTMLElement>);\n\n @HostListener('document:mousedown', ['$event'])\n onDocClick(e: MouseEvent): void {\n const target = e.target as Element | null;\n const isInsideOverlay = !!target?.closest('.neu-autocomplete__list, .neu-autocomplete__empty');\n if (!this._el.nativeElement.contains(e.target as Node) && !isInsideOverlay) {\n this._closePanel();\n }\n }\n\n @HostListener('window:resize')\n onWindowResize(): void {\n if (this._isOpen()) {\n this._syncOverlayWidth();\n }\n }\n\n // ── Event handlers ───────────────────────────────────────────────\n onQueryChange(q: string): void {\n this._query.set(q);\n this._activeIndex.set(-1);\n // Sólo abrimos si hay texto suficiente; si no, cerramos.\n // Only open when there is enough text; otherwise close.\n const minLen = Math.max(1, this.minLength());\n const shouldOpen = q.trim().length >= minLen;\n if (shouldOpen) {\n this._syncOverlayWidth();\n }\n this._isOpen.set(shouldOpen);\n this.queryChange.emit(q);\n // CVA — emit null when query is cleared\n if (!q) {\n this._onChange(null);\n }\n }\n\n _onFocus(): void {\n this._focused.set(true);\n // Abre el dropdown solo si ya hay texto escrito / Only open when there is already a query.\n if (this._query().trim().length >= Math.max(1, this.minLength())) {\n this._syncOverlayWidth();\n this._isOpen.set(true);\n }\n }\n\n _onBlur(): void {\n this._focused.set(false);\n this._onTouched();\n // Small delay to allow mousedown on option to fire first\n setTimeout(() => this._closePanel(), 150);\n }\n\n onKeyDown(e: KeyboardEvent): void {\n const total = this._filtered().length;\n if (!total && e.key !== 'Escape') return;\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n this._syncOverlayWidth();\n this._moveActiveIndex(1);\n this._isOpen.set(true);\n this._scrollActiveOptionIntoView();\n break;\n case 'ArrowUp':\n e.preventDefault();\n this._moveActiveIndex(-1);\n this._scrollActiveOptionIntoView();\n break;\n case 'Enter': {\n const idx = this._activeIndex();\n const opt = this._filtered()[idx];\n if (opt && !opt.disabled) this.selectOption(opt);\n break;\n }\n case 'Escape':\n this._isOpen.set(false);\n this._activeIndex.set(-1);\n break;\n }\n }\n\n private _moveActiveIndex(step: 1 | -1): void {\n const filtered = this._filtered();\n if (!filtered.length) {\n this._activeIndex.set(-1);\n return;\n }\n\n const currentIndex = this._activeIndex();\n let nextIndex = currentIndex;\n\n for (let count = 0; count < filtered.length; count += 1) {\n nextIndex =\n step === 1 ? Math.min(nextIndex + 1, filtered.length - 1) : Math.max(nextIndex - 1, 0);\n\n if (!filtered[nextIndex]?.disabled) {\n this._activeIndex.set(nextIndex);\n return;\n }\n\n if ((step === 1 && nextIndex === filtered.length - 1) || (step === -1 && nextIndex === 0)) {\n break;\n }\n }\n\n if (currentIndex === -1) {\n this._activeIndex.set(filtered.findIndex((option) => !option.disabled));\n }\n }\n\n selectOption(opt: NeuAutocompleteOption): void {\n if (opt.disabled) return;\n this._query.set(opt.label);\n this._isOpen.set(false);\n this._activeIndex.set(-1);\n this._onChange(opt.value);\n this.optionSelected.emit(opt);\n }\n\n clear(): void {\n this._query.set('');\n this._onChange(null);\n this._isOpen.set(false);\n this._activeIndex.set(-1);\n this.queryChange.emit('');\n }\n\n _closePanel(): void {\n this._isOpen.set(false);\n this._activeIndex.set(-1);\n }\n\n private _scrollActiveOptionIntoView(): void {\n const activeIndex = this._activeIndex();\n if (activeIndex < 0) {\n return;\n }\n\n if (this.virtualScroll()) {\n requestAnimationFrame(() => {\n this._viewport()?.scrollToIndex(activeIndex, 'auto');\n this._viewport()?.checkViewportSize();\n });\n return;\n }\n\n requestAnimationFrame(() => {\n const activeOption = this._el.nativeElement.querySelector(\n `#${this._optionId(activeIndex)}`,\n ) as HTMLElement | null;\n const overlayOption =\n activeOption ?? this._document.getElementById(this._optionId(activeIndex));\n if (typeof overlayOption?.scrollIntoView === 'function') {\n overlayOption.scrollIntoView({ block: 'nearest' });\n }\n });\n }\n\n private _syncOverlayWidth(): void {\n const trigger = this._el.nativeElement.querySelector(\n '.neu-autocomplete__input-wrap',\n ) as HTMLElement | null;\n if (!trigger) {\n return;\n }\n const width =\n typeof trigger.getBoundingClientRect === 'function'\n ? trigger.getBoundingClientRect().width\n : 0;\n this.overlayWidth.set(Math.min(width, window.innerWidth - 32));\n if (this.virtualScroll()) {\n requestAnimationFrame(() => this._viewport()?.checkViewportSize());\n }\n }\n\n // ── CVA ──────────────────────────────────────────────────────────\n writeValue(val: unknown): void {\n if (val === null || val === undefined) {\n this._query.set('');\n return;\n }\n const match = this.options().find((o) => o.value === val);\n this._query.set(match ? match.label : String(val));\n }\n\n registerOnChange(fn: (v: unknown) => void): void {\n this._onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this._onTouched = fn;\n }\n\n setDisabledState(d: boolean): void {\n this._cvaDisabled.set(d);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
|