@neural-ui/core 1.6.1 → 1.6.3
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/accordion/package.json +4 -0
- package/alert/package.json +4 -0
- package/autocomplete/package.json +4 -0
- package/avatar/package.json +4 -0
- package/badge/package.json +4 -0
- package/block-ui/package.json +4 -0
- package/breadcrumb/package.json +4 -0
- package/button/package.json +4 -0
- package/calendar/package.json +4 -0
- package/card/package.json +4 -0
- package/chart/package.json +4 -0
- package/checkbox/package.json +4 -0
- package/chip/package.json +4 -0
- package/code-block/package.json +4 -0
- package/color-picker/package.json +4 -0
- package/command-palette/package.json +4 -0
- package/confirm-dialog/package.json +4 -0
- package/context-menu/package.json +4 -0
- package/dashboard-grid/package.json +4 -0
- package/date-input/package.json +4 -0
- package/divider/package.json +4 -0
- package/empty-state/package.json +4 -0
- 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/filter-bar/package.json +4 -0
- package/icon/package.json +4 -0
- package/image-gallery/package.json +4 -0
- package/image-viewer/package.json +4 -0
- package/input/package.json +4 -0
- package/input-otp/package.json +4 -0
- package/kanban/package.json +4 -0
- package/knob/package.json +4 -0
- package/meter-group/package.json +4 -0
- package/modal/package.json +4 -0
- package/multiselect/package.json +4 -0
- package/nav/package.json +4 -0
- package/notification-center/package.json +4 -0
- package/number-input/package.json +4 -0
- package/package.json +6 -6
- package/pagination/package.json +4 -0
- package/popover/package.json +4 -0
- package/progress-bar/package.json +4 -0
- package/radio/package.json +4 -0
- package/rating/package.json +4 -0
- package/rich-text-editor/package.json +4 -0
- package/scheduler-gantt/package.json +4 -0
- package/select/package.json +4 -0
- package/sidebar/package.json +4 -0
- package/skeleton/package.json +4 -0
- package/slider/package.json +4 -0
- package/spinner/package.json +4 -0
- package/split-button/package.json +4 -0
- package/splitter/package.json +4 -0
- package/stats-card/package.json +4 -0
- package/stepper/package.json +4 -0
- package/switch/package.json +4 -0
- package/table/package.json +4 -0
- package/tabs/package.json +4 -0
- package/textarea/package.json +4 -0
- package/timeline/package.json +4 -0
- package/timeline-grid/package.json +4 -0
- package/toast/package.json +4 -0
- package/toggle-button-group/package.json +4 -0
- package/toolbar/package.json +4 -0
- package/tooltip/package.json +4 -0
- package/tree/package.json +4 -0
- package/tree-table/package.json +4 -0
- package/uploader/package.json +4 -0
- package/url-state/package.json +4 -0
- package/virtual-list/package.json +4 -0
|
@@ -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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"}
|
|
@@ -12,29 +12,21 @@ import { NgClass } from '@angular/common';
|
|
|
12
12
|
*/
|
|
13
13
|
class NeuAvatarComponent {
|
|
14
14
|
/** URL de la imagen. Si falla la carga, muestra las iniciales. / Image URL. If loading fails, shows the initials. */
|
|
15
|
-
src = input('', /*
|
|
16
|
-
...(ngDevMode ? [{ debugName: "src" }] : /* istanbul ignore next */ []));
|
|
15
|
+
src = input('', ...(ngDevMode ? [{ debugName: "src" }] : /* istanbul ignore next */ []));
|
|
17
16
|
/** Texto alternativo de la imagen. / Image alternative text. */
|
|
18
|
-
alt = input('', /*
|
|
19
|
-
...(ngDevMode ? [{ debugName: "alt" }] : /* istanbul ignore next */ []));
|
|
17
|
+
alt = input('', ...(ngDevMode ? [{ debugName: "alt" }] : /* istanbul ignore next */ []));
|
|
20
18
|
/** Nombre completo — se usan las iniciales como fallback. / Full name — initials are used as fallback. */
|
|
21
|
-
name = input('', /*
|
|
22
|
-
...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
|
|
19
|
+
name = input('', ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
|
|
23
20
|
/** Tamaño: xs (24) | sm (32) | md (40) | lg (48) | xl (64). Por defecto 'md'. / Size: xs (24) | sm (32) | md (40) | lg (48) | xl (64). Default 'md'. */
|
|
24
|
-
size = input('md', /*
|
|
25
|
-
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
21
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
26
22
|
/** Forma: 'circle' (default) o 'square'. / Shape: 'circle' (default) or 'square'. */
|
|
27
|
-
shape = input('circle', /*
|
|
28
|
-
...(ngDevMode ? [{ debugName: "shape" }] : /* istanbul ignore next */ []));
|
|
23
|
+
shape = input('circle', ...(ngDevMode ? [{ debugName: "shape" }] : /* istanbul ignore next */ []));
|
|
29
24
|
/** Color de fondo para iniciales. / Background color for initials. */
|
|
30
|
-
color = input('blue', /*
|
|
31
|
-
...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
|
|
25
|
+
color = input('blue', ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
|
|
32
26
|
/** Indicador de presencia. / Presence indicator. */
|
|
33
|
-
status = input('', /*
|
|
34
|
-
...(ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []));
|
|
27
|
+
status = input('', ...(ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []));
|
|
35
28
|
/** @internal Imagen fallida / Failed image */
|
|
36
|
-
imgError = signal(false, /*
|
|
37
|
-
...(ngDevMode ? [{ debugName: "imgError" }] : /* istanbul ignore next */ []));
|
|
29
|
+
imgError = signal(false, ...(ngDevMode ? [{ debugName: "imgError" }] : /* istanbul ignore next */ []));
|
|
38
30
|
initials = computed(() => {
|
|
39
31
|
const n = this.name().trim();
|
|
40
32
|
if (!n)
|
|
@@ -43,16 +35,14 @@ class NeuAvatarComponent {
|
|
|
43
35
|
return parts.length === 1
|
|
44
36
|
? parts[0].slice(0, 2).toUpperCase()
|
|
45
37
|
: (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
|
|
46
|
-
}, /*
|
|
47
|
-
...(ngDevMode ? [{ debugName: "initials" }] : /* istanbul ignore next */ []));
|
|
38
|
+
}, ...(ngDevMode ? [{ debugName: "initials" }] : /* istanbul ignore next */ []));
|
|
48
39
|
hostClasses = computed(() => [
|
|
49
40
|
`neu-avatar--${this.size()}`,
|
|
50
41
|
`neu-avatar--${this.shape()}`,
|
|
51
42
|
...(!this.src() || this.imgError() ? [`neu-avatar--${this.color()}`] : []),
|
|
52
|
-
], /*
|
|
53
|
-
|
|
54
|
-
static
|
|
55
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: NeuAvatarComponent, isStandalone: true, selector: "neu-avatar", inputs: { src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: false, transformFunction: null }, alt: { classPropertyName: "alt", publicName: "alt", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "neu-avatar-host" }, ngImport: i0, template: `
|
|
43
|
+
], ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
|
|
44
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuAvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
45
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: NeuAvatarComponent, isStandalone: true, selector: "neu-avatar", inputs: { src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: false, transformFunction: null }, alt: { classPropertyName: "alt", publicName: "alt", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "neu-avatar-host" }, ngImport: i0, template: `
|
|
56
46
|
<span
|
|
57
47
|
class="neu-avatar"
|
|
58
48
|
[ngClass]="hostClasses()"
|
|
@@ -80,7 +70,7 @@ class NeuAvatarComponent {
|
|
|
80
70
|
}
|
|
81
71
|
`, isInline: true, styles: [".neu-avatar-host{display:inline-block;vertical-align:middle;flex-shrink:0;position:relative}.neu-avatar{position:relative;display:inline-flex;align-items:center;justify-content:center;overflow:hidden;background:var(--neu-surface-2);color:var(--neu-text-muted);font-weight:600;font-family:var(--neu-font-sans);-webkit-user-select:none;user-select:none;flex-shrink:0}.neu-avatar--xs{width:24px;height:24px;font-size:10px}.neu-avatar--sm{width:32px;height:32px;font-size:12px}.neu-avatar--md{width:40px;height:40px;font-size:14px}.neu-avatar--lg{width:48px;height:48px;font-size:16px}.neu-avatar--xl{width:64px;height:64px;font-size:22px}.neu-avatar--circle{border-radius:50%}.neu-avatar--square{border-radius:var(--neu-radius)}.neu-avatar--blue{background:#dbeafe;color:#1d4ed8}.neu-avatar--violet{background:#ede9fe;color:#5b21b6}.neu-avatar--green{background:#dcfce7;color:#15803d}.neu-avatar--amber{background:#fef3c7;color:#b45309}.neu-avatar--red{background:#fee2e2;color:#b91c1c}.neu-avatar--slate{background:#f1f5f9;color:#475569}.neu-avatar__img{width:100%;height:100%;object-fit:cover;display:block}.neu-avatar__initials{line-height:1;letter-spacing:-.01em}.neu-avatar__status{position:absolute;bottom:3%;right:3%;width:25%;height:25%;min-width:8px;min-height:8px;border-radius:50%;border:2px solid var(--neu-surface);box-sizing:border-box;z-index:1}.neu-avatar__status--online{background:var(--neu-success)}.neu-avatar__status--offline{background:var(--neu-text-disabled)}.neu-avatar__status--busy{background:var(--neu-error)}.neu-avatar__status--away{background:var(--neu-warning)}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
82
72
|
}
|
|
83
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
73
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuAvatarComponent, decorators: [{
|
|
84
74
|
type: Component,
|
|
85
75
|
args: [{ selector: 'neu-avatar', imports: [NgClass], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'neu-avatar-host' }, template: `
|
|
86
76
|
<span
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neural-ui-core-avatar.mjs","sources":["../../../../projects/ui-core/avatar/neu-avatar.component.ts","../../../../projects/ui-core/avatar/neural-ui-core-avatar.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n signal,\n} from '@angular/core';\nimport { NgClass } from '@angular/common';\n\nexport type NeuAvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\nexport type NeuAvatarShape = 'circle' | 'square';\nexport type NeuAvatarColor = 'blue' | 'violet' | 'green' | 'amber' | 'red' | 'slate';\nexport type NeuAvatarStatus = 'online' | 'offline' | 'busy' | 'away' | '';\n\n/**\n * NeuAvatar — Avatar circular o cuadrado para foto o iniciales.\n *\n * Uso:\n * <neu-avatar name=\"Pedro Moreno\" />\n * <neu-avatar src=\"/assets/avatar.jpg\" alt=\"Pedro\" size=\"lg\" />\n * <neu-avatar name=\"PM\" size=\"lg\" color=\"blue\" status=\"online\" />\n */\n@Component({\n selector: 'neu-avatar',\n imports: [NgClass],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { class: 'neu-avatar-host' },\n template: `\n <span\n class=\"neu-avatar\"\n [ngClass]=\"hostClasses()\"\n [attr.aria-label]=\"alt() || name() || 'Avatar'\"\n role=\"img\"\n >\n @if (src() && !imgError()) {\n <img\n class=\"neu-avatar__img\"\n [src]=\"src()\"\n [alt]=\"alt() || name()\"\n (error)=\"imgError.set(true)\"\n />\n } @else {\n <span class=\"neu-avatar__initials\" aria-hidden=\"true\">{{ initials() }}</span>\n }\n </span>\n\n @if (status()) {\n <span\n class=\"neu-avatar__status\"\n [ngClass]=\"'neu-avatar__status--' + status()\"\n aria-hidden=\"true\"\n ></span>\n }\n `,\n styleUrl: './neu-avatar.component.scss',\n})\nexport class NeuAvatarComponent {\n /** URL de la imagen. Si falla la carga, muestra las iniciales. / Image URL. If loading fails, shows the initials. */\n src = input<string>('');\n /** Texto alternativo de la imagen. / Image alternative text. */\n alt = input<string>('');\n /** Nombre completo — se usan las iniciales como fallback. / Full name — initials are used as fallback. */\n name = input<string>('');\n /** Tamaño: xs (24) | sm (32) | md (40) | lg (48) | xl (64). Por defecto 'md'. / Size: xs (24) | sm (32) | md (40) | lg (48) | xl (64). Default 'md'. */\n size = input<NeuAvatarSize>('md');\n /** Forma: 'circle' (default) o 'square'. / Shape: 'circle' (default) or 'square'. */\n shape = input<NeuAvatarShape>('circle');\n /** Color de fondo para iniciales. / Background color for initials. */\n color = input<NeuAvatarColor>('blue');\n /** Indicador de presencia. / Presence indicator. */\n status = input<NeuAvatarStatus>('');\n\n /** @internal Imagen fallida / Failed image */\n protected readonly imgError = signal(false);\n\n protected readonly initials = computed(() => {\n const n = this.name().trim();\n if (!n) return '?';\n const parts = n.split(/\\s+/);\n return parts.length === 1\n ? parts[0].slice(0, 2).toUpperCase()\n : (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();\n });\n\n protected readonly hostClasses = computed(() => [\n `neu-avatar--${this.size()}`,\n `neu-avatar--${this.shape()}`,\n ...(!this.src() || this.imgError() ? [`neu-avatar--${this.color()}`] : []),\n ]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":";;;;AAeA;;;;;;;AAOG;MAoCU,kBAAkB,CAAA;;
|
|
1
|
+
{"version":3,"file":"neural-ui-core-avatar.mjs","sources":["../../../../projects/ui-core/avatar/neu-avatar.component.ts","../../../../projects/ui-core/avatar/neural-ui-core-avatar.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n signal,\n} from '@angular/core';\nimport { NgClass } from '@angular/common';\n\nexport type NeuAvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\nexport type NeuAvatarShape = 'circle' | 'square';\nexport type NeuAvatarColor = 'blue' | 'violet' | 'green' | 'amber' | 'red' | 'slate';\nexport type NeuAvatarStatus = 'online' | 'offline' | 'busy' | 'away' | '';\n\n/**\n * NeuAvatar — Avatar circular o cuadrado para foto o iniciales.\n *\n * Uso:\n * <neu-avatar name=\"Pedro Moreno\" />\n * <neu-avatar src=\"/assets/avatar.jpg\" alt=\"Pedro\" size=\"lg\" />\n * <neu-avatar name=\"PM\" size=\"lg\" color=\"blue\" status=\"online\" />\n */\n@Component({\n selector: 'neu-avatar',\n imports: [NgClass],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { class: 'neu-avatar-host' },\n template: `\n <span\n class=\"neu-avatar\"\n [ngClass]=\"hostClasses()\"\n [attr.aria-label]=\"alt() || name() || 'Avatar'\"\n role=\"img\"\n >\n @if (src() && !imgError()) {\n <img\n class=\"neu-avatar__img\"\n [src]=\"src()\"\n [alt]=\"alt() || name()\"\n (error)=\"imgError.set(true)\"\n />\n } @else {\n <span class=\"neu-avatar__initials\" aria-hidden=\"true\">{{ initials() }}</span>\n }\n </span>\n\n @if (status()) {\n <span\n class=\"neu-avatar__status\"\n [ngClass]=\"'neu-avatar__status--' + status()\"\n aria-hidden=\"true\"\n ></span>\n }\n `,\n styleUrl: './neu-avatar.component.scss',\n})\nexport class NeuAvatarComponent {\n /** URL de la imagen. Si falla la carga, muestra las iniciales. / Image URL. If loading fails, shows the initials. */\n src = input<string>('');\n /** Texto alternativo de la imagen. / Image alternative text. */\n alt = input<string>('');\n /** Nombre completo — se usan las iniciales como fallback. / Full name — initials are used as fallback. */\n name = input<string>('');\n /** Tamaño: xs (24) | sm (32) | md (40) | lg (48) | xl (64). Por defecto 'md'. / Size: xs (24) | sm (32) | md (40) | lg (48) | xl (64). Default 'md'. */\n size = input<NeuAvatarSize>('md');\n /** Forma: 'circle' (default) o 'square'. / Shape: 'circle' (default) or 'square'. */\n shape = input<NeuAvatarShape>('circle');\n /** Color de fondo para iniciales. / Background color for initials. */\n color = input<NeuAvatarColor>('blue');\n /** Indicador de presencia. / Presence indicator. */\n status = input<NeuAvatarStatus>('');\n\n /** @internal Imagen fallida / Failed image */\n protected readonly imgError = signal(false);\n\n protected readonly initials = computed(() => {\n const n = this.name().trim();\n if (!n) return '?';\n const parts = n.split(/\\s+/);\n return parts.length === 1\n ? parts[0].slice(0, 2).toUpperCase()\n : (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();\n });\n\n protected readonly hostClasses = computed(() => [\n `neu-avatar--${this.size()}`,\n `neu-avatar--${this.shape()}`,\n ...(!this.src() || this.imgError() ? [`neu-avatar--${this.color()}`] : []),\n ]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
|
|
@@ -11,20 +11,15 @@ import { input, computed, ChangeDetectionStrategy, ViewEncapsulation, Component
|
|
|
11
11
|
*/
|
|
12
12
|
class NeuBadgeComponent {
|
|
13
13
|
/** Variante semántica / Semantic variant */
|
|
14
|
-
variant = input('default', /*
|
|
15
|
-
...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
14
|
+
variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
16
15
|
/** Tamaño / Size */
|
|
17
|
-
size = input('md', /*
|
|
18
|
-
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
16
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
19
17
|
/** Muestra un punto de color a la izquierda / Shows a colored dot on the left */
|
|
20
|
-
dot = input(false, /*
|
|
21
|
-
...(ngDevMode ? [{ debugName: "dot" }] : /* istanbul ignore next */ []));
|
|
18
|
+
dot = input(false, ...(ngDevMode ? [{ debugName: "dot" }] : /* istanbul ignore next */ []));
|
|
22
19
|
/** Estilo con solo borde (outline) sin relleno / Border-only style (outline) without fill */
|
|
23
|
-
outline = input(false, /*
|
|
24
|
-
...(ngDevMode ? [{ debugName: "outline" }] : /* istanbul ignore next */ []));
|
|
20
|
+
outline = input(false, ...(ngDevMode ? [{ debugName: "outline" }] : /* istanbul ignore next */ []));
|
|
25
21
|
/** Estilo completamente redondeado (pill) / Fully rounded style (pill) */
|
|
26
|
-
pill = input(true, /*
|
|
27
|
-
...(ngDevMode ? [{ debugName: "pill" }] : /* istanbul ignore next */ []));
|
|
22
|
+
pill = input(true, ...(ngDevMode ? [{ debugName: "pill" }] : /* istanbul ignore next */ []));
|
|
28
23
|
hostClasses = computed(() => ({
|
|
29
24
|
'neu-badge': true,
|
|
30
25
|
[`neu-badge--${this.variant()}`]: true,
|
|
@@ -32,17 +27,16 @@ class NeuBadgeComponent {
|
|
|
32
27
|
'neu-badge--outline': this.outline(),
|
|
33
28
|
'neu-badge--pill': this.pill(),
|
|
34
29
|
'neu-badge--dot': this.dot(),
|
|
35
|
-
}), /*
|
|
36
|
-
|
|
37
|
-
static
|
|
38
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: NeuBadgeComponent, isStandalone: true, selector: "neu-badge", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, dot: { classPropertyName: "dot", publicName: "dot", isSignal: true, isRequired: false, transformFunction: null }, outline: { classPropertyName: "outline", publicName: "outline", isSignal: true, isRequired: false, transformFunction: null }, pill: { classPropertyName: "pill", publicName: "pill", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, ngImport: i0, template: `
|
|
30
|
+
}), ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
|
|
31
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuBadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
32
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: NeuBadgeComponent, isStandalone: true, selector: "neu-badge", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, dot: { classPropertyName: "dot", publicName: "dot", isSignal: true, isRequired: false, transformFunction: null }, outline: { classPropertyName: "outline", publicName: "outline", isSignal: true, isRequired: false, transformFunction: null }, pill: { classPropertyName: "pill", publicName: "pill", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "hostClasses()" } }, ngImport: i0, template: `
|
|
39
33
|
@if (dot()) {
|
|
40
34
|
<span class="neu-badge__dot" aria-hidden="true"></span>
|
|
41
35
|
}
|
|
42
36
|
<ng-content />
|
|
43
37
|
`, isInline: true, styles: [".neu-badge{display:inline-flex;align-items:center;gap:5px;font-family:var(--neu-font-sans);font-weight:500;line-height:1;white-space:nowrap}.neu-badge--sm{padding:2px 8px;font-size:11px;border-radius:var(--neu-radius-sm)}.neu-badge--md{padding:4px 10px;font-size:var(--neu-text-xs);border-radius:var(--neu-radius)}.neu-badge--pill.neu-badge--sm,.neu-badge--pill.neu-badge--md{border-radius:var(--neu-radius-full)}.neu-badge--default{background:var(--neu-surface-2);color:color-mix(in srgb,var(--neu-text) 72%,var(--neu-surface) 28%);border:1px solid var(--neu-border)}.neu-badge--default .neu-badge__dot{background:var(--neu-text-disabled)}.neu-badge--success{background:var(--neu-success-bg);color:color-mix(in srgb,var(--neu-text) 78%,var(--neu-success) 22%);border:1px solid transparent}.neu-badge--success .neu-badge__dot{background:var(--neu-success)}.neu-badge--info{background:var(--neu-info-bg);color:color-mix(in srgb,var(--neu-text) 76%,var(--neu-info) 24%);border:1px solid transparent}.neu-badge--info .neu-badge__dot{background:var(--neu-info)}.neu-badge--warning{background:var(--neu-warning-bg);color:color-mix(in srgb,var(--neu-text) 78%,var(--neu-warning) 22%);border:1px solid transparent}.neu-badge--warning .neu-badge__dot{background:var(--neu-warning)}.neu-badge--danger{background:var(--neu-error-bg);color:color-mix(in srgb,var(--neu-text) 74%,var(--neu-error) 26%);border:1px solid transparent}.neu-badge--danger .neu-badge__dot{background:var(--neu-error)}.neu-badge--outline{background:transparent}.neu-badge--outline.neu-badge--success{border-color:var(--neu-success);background:transparent}.neu-badge--outline.neu-badge--info{border-color:var(--neu-info);background:transparent}.neu-badge--outline.neu-badge--warning{border-color:var(--neu-warning);background:transparent}.neu-badge--outline.neu-badge--danger{border-color:var(--neu-error);background:transparent}.neu-badge__dot{width:6px;height:6px;border-radius:var(--neu-radius-full);flex-shrink:0}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
44
38
|
}
|
|
45
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
39
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuBadgeComponent, decorators: [{
|
|
46
40
|
type: Component,
|
|
47
41
|
args: [{ selector: 'neu-badge', imports: [], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: { '[class]': 'hostClasses()' }, template: `
|
|
48
42
|
@if (dot()) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neural-ui-core-badge.mjs","sources":["../../../../projects/ui-core/badge/neu-badge.component.ts","../../../../projects/ui-core/badge/neural-ui-core-badge.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n} from '@angular/core';\n\nexport type NeuBadgeVariant = 'default' | 'success' | 'info' | 'warning' | 'danger';\nexport type NeuBadgeSize = 'sm' | 'md';\n\n/**\n * NeuralUI Badge Component\n *\n * Etiqueta de estado compacta y semántica. / Compact and semantic status label.\n *\n * Uso: <neu-badge variant=\"success\">Activo</neu-badge>\n * <neu-badge variant=\"danger\" [dot]=\"true\">Error</neu-badge>\n */\n@Component({\n selector: 'neu-badge',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { '[class]': 'hostClasses()' },\n template: `\n @if (dot()) {\n <span class=\"neu-badge__dot\" aria-hidden=\"true\"></span>\n }\n <ng-content />\n `,\n styleUrl: './neu-badge.component.scss',\n})\nexport class NeuBadgeComponent {\n /** Variante semántica / Semantic variant */\n variant = input<NeuBadgeVariant>('default');\n\n /** Tamaño / Size */\n size = input<NeuBadgeSize>('md');\n\n /** Muestra un punto de color a la izquierda / Shows a colored dot on the left */\n dot = input<boolean>(false);\n\n /** Estilo con solo borde (outline) sin relleno / Border-only style (outline) without fill */\n outline = input<boolean>(false);\n\n /** Estilo completamente redondeado (pill) / Fully rounded style (pill) */\n pill = input<boolean>(true);\n\n readonly hostClasses = computed(() => ({\n 'neu-badge': true,\n [`neu-badge--${this.variant()}`]: true,\n [`neu-badge--${this.size()}`]: true,\n 'neu-badge--outline': this.outline(),\n 'neu-badge--pill': this.pill(),\n 'neu-badge--dot': this.dot(),\n }));\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":";;;AAWA;;;;;;;AAOG;MAeU,iBAAiB,CAAA;;
|
|
1
|
+
{"version":3,"file":"neural-ui-core-badge.mjs","sources":["../../../../projects/ui-core/badge/neu-badge.component.ts","../../../../projects/ui-core/badge/neural-ui-core-badge.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ViewEncapsulation,\n computed,\n input,\n} from '@angular/core';\n\nexport type NeuBadgeVariant = 'default' | 'success' | 'info' | 'warning' | 'danger';\nexport type NeuBadgeSize = 'sm' | 'md';\n\n/**\n * NeuralUI Badge Component\n *\n * Etiqueta de estado compacta y semántica. / Compact and semantic status label.\n *\n * Uso: <neu-badge variant=\"success\">Activo</neu-badge>\n * <neu-badge variant=\"danger\" [dot]=\"true\">Error</neu-badge>\n */\n@Component({\n selector: 'neu-badge',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { '[class]': 'hostClasses()' },\n template: `\n @if (dot()) {\n <span class=\"neu-badge__dot\" aria-hidden=\"true\"></span>\n }\n <ng-content />\n `,\n styleUrl: './neu-badge.component.scss',\n})\nexport class NeuBadgeComponent {\n /** Variante semántica / Semantic variant */\n variant = input<NeuBadgeVariant>('default');\n\n /** Tamaño / Size */\n size = input<NeuBadgeSize>('md');\n\n /** Muestra un punto de color a la izquierda / Shows a colored dot on the left */\n dot = input<boolean>(false);\n\n /** Estilo con solo borde (outline) sin relleno / Border-only style (outline) without fill */\n outline = input<boolean>(false);\n\n /** Estilo completamente redondeado (pill) / Fully rounded style (pill) */\n pill = input<boolean>(true);\n\n readonly hostClasses = computed(() => ({\n 'neu-badge': true,\n [`neu-badge--${this.variant()}`]: true,\n [`neu-badge--${this.size()}`]: true,\n 'neu-badge--outline': this.outline(),\n 'neu-badge--pill': this.pill(),\n 'neu-badge--dot': this.dot(),\n }));\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
|
|
@@ -19,21 +19,17 @@ import { input, computed, ChangeDetectionStrategy, ViewEncapsulation, Component,
|
|
|
19
19
|
*/
|
|
20
20
|
class NeuBlockUIComponent {
|
|
21
21
|
/** Activa la superposición / Activates the overlay */
|
|
22
|
-
blocked = input(false, /*
|
|
23
|
-
...(ngDevMode ? [{ debugName: "blocked" }] : /* istanbul ignore next */ []));
|
|
22
|
+
blocked = input(false, ...(ngDevMode ? [{ debugName: "blocked" }] : /* istanbul ignore next */ []));
|
|
24
23
|
/** Mensaje opcional bajo el spinner / Optional message below the spinner */
|
|
25
|
-
message = input('', /*
|
|
26
|
-
...(ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []));
|
|
24
|
+
message = input('', ...(ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []));
|
|
27
25
|
/** Variante de opacidad del overlay */
|
|
28
|
-
variant = input('default', /*
|
|
29
|
-
...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
26
|
+
variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
30
27
|
hostClasses = computed(() => ({
|
|
31
28
|
'neu-block-ui': true,
|
|
32
29
|
[`neu-block-ui--${this.variant()}`]: true,
|
|
33
|
-
}), /*
|
|
34
|
-
|
|
35
|
-
static
|
|
36
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: NeuBlockUIComponent, isStandalone: true, selector: "neu-block-ui", inputs: { blocked: { classPropertyName: "blocked", publicName: "blocked", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "status" }, properties: { "class": "hostClasses()", "attr.aria-busy": "blocked()", "attr.aria-hidden": "!blocked()" } }, ngImport: i0, template: `
|
|
30
|
+
}), ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
|
|
31
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuBlockUIComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
32
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: NeuBlockUIComponent, isStandalone: true, selector: "neu-block-ui", inputs: { blocked: { classPropertyName: "blocked", publicName: "blocked", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "status" }, properties: { "class": "hostClasses()", "attr.aria-busy": "blocked()", "attr.aria-hidden": "!blocked()" } }, ngImport: i0, template: `
|
|
37
33
|
@if (blocked()) {
|
|
38
34
|
<div class="neu-block-ui__overlay">
|
|
39
35
|
<div class="neu-block-ui__content">
|
|
@@ -46,7 +42,7 @@ class NeuBlockUIComponent {
|
|
|
46
42
|
}
|
|
47
43
|
`, isInline: true, styles: ["@charset \"UTF-8\";.neu-block-ui{position:absolute;inset:0;z-index:100;pointer-events:none;display:contents}.neu-block-ui--dark .neu-block-ui__overlay{background:var(--neu-block-ui-bg, rgba(0, 0, 0, .5))}.neu-block-ui--light .neu-block-ui__overlay{background:var(--neu-block-ui-bg, rgba(255, 255, 255, .9))}.neu-block-ui__overlay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:var(--neu-block-ui-bg, rgba(255, 255, 255, .7));border-radius:var(--neu-block-ui-radius, inherit);pointer-events:all;-webkit-backdrop-filter:blur(1px);backdrop-filter:blur(1px);z-index:100}.neu-block-ui__content{display:flex;flex-direction:column;align-items:center;gap:10px}.neu-block-ui__spinner{display:inline-block;width:32px;height:32px;border:3px solid var(--neu-spinner-track, #e5e7eb);border-top-color:var(--neu-color-primary, #0ea5e9);border-radius:50%;animation:neu-block-ui-spin .75s linear infinite}@keyframes neu-block-ui-spin{to{transform:rotate(360deg)}}.neu-block-ui__message{font-size:.875rem;color:var(--neu-text-secondary, #6b7280);font-weight:500}.neu-block-ui__host{position:relative}.neu-block-ui__host--blocked{overflow:hidden;pointer-events:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
48
44
|
}
|
|
49
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
45
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuBlockUIComponent, decorators: [{
|
|
50
46
|
type: Component,
|
|
51
47
|
args: [{ selector: 'neu-block-ui', imports: [], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
52
48
|
'[class]': 'hostClasses()',
|
|
@@ -72,8 +68,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
72
68
|
* Uso: <div [neuBlockUI]="loading$ | async">...</div>
|
|
73
69
|
*/
|
|
74
70
|
class NeuBlockUIDirective {
|
|
75
|
-
neuBlockUI = input(false, /*
|
|
76
|
-
...(ngDevMode ? [{ debugName: "neuBlockUI" }] : /* istanbul ignore next */ []));
|
|
71
|
+
neuBlockUI = input(false, ...(ngDevMode ? [{ debugName: "neuBlockUI" }] : /* istanbul ignore next */ []));
|
|
77
72
|
_el = inject((ElementRef));
|
|
78
73
|
constructor() {
|
|
79
74
|
effect(() => {
|
|
@@ -81,10 +76,10 @@ class NeuBlockUIDirective {
|
|
|
81
76
|
this._el.nativeElement.classList.toggle('neu-block-ui__host--blocked', blocked);
|
|
82
77
|
});
|
|
83
78
|
}
|
|
84
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
85
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "
|
|
79
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuBlockUIDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
80
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.17", type: NeuBlockUIDirective, isStandalone: true, selector: "[neuBlockUI]", inputs: { neuBlockUI: { classPropertyName: "neuBlockUI", publicName: "neuBlockUI", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.neu-block-ui__host": "true" } }, ngImport: i0 });
|
|
86
81
|
}
|
|
87
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
82
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuBlockUIDirective, decorators: [{
|
|
88
83
|
type: Directive,
|
|
89
84
|
args: [{
|
|
90
85
|
selector: '[neuBlockUI]',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neural-ui-core-block-ui.mjs","sources":["../../../../projects/ui-core/block-ui/neu-block-ui.component.ts","../../../../projects/ui-core/block-ui/neural-ui-core-block-ui.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n Directive,\n ElementRef,\n ViewEncapsulation,\n computed,\n effect,\n inject,\n input,\n} from '@angular/core';\n\n/**\n * NeuralUI BlockUI Component\n *\n * Superposición que bloquea la interacción de un contenedor mientras está activa.\n *\n * Uso (componente):\n * <div style=\"position:relative\">\n * <neu-block-ui [blocked]=\"isLoading\" message=\"Cargando...\" />\n * <form>...</form>\n * </div>\n *\n * Uso (directiva en el contenedor padre):\n * <div [neuBlockUI]=\"isLoading\">\n * <form>...</form>\n * </div>\n */\n@Component({\n selector: 'neu-block-ui',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class]': 'hostClasses()',\n '[attr.aria-busy]': 'blocked()',\n '[attr.aria-hidden]': '!blocked()',\n role: 'status',\n },\n template: `\n @if (blocked()) {\n <div class=\"neu-block-ui__overlay\">\n <div class=\"neu-block-ui__content\">\n <span class=\"neu-block-ui__spinner\" aria-hidden=\"true\"></span>\n @if (message()) {\n <span class=\"neu-block-ui__message\">{{ message() }}</span>\n }\n </div>\n </div>\n }\n `,\n styleUrl: './neu-block-ui.component.scss',\n})\nexport class NeuBlockUIComponent {\n /** Activa la superposición / Activates the overlay */\n readonly blocked = input<boolean>(false);\n\n /** Mensaje opcional bajo el spinner / Optional message below the spinner */\n readonly message = input<string>('');\n\n /** Variante de opacidad del overlay */\n readonly variant = input<'default' | 'light' | 'dark'>('default');\n\n readonly hostClasses = computed(() => ({\n 'neu-block-ui': true,\n [`neu-block-ui--${this.variant()}`]: true,\n }));\n}\n\n/**\n * Directive [neuBlockUI] — Aplica el efecto BlockUI al elemento host.\n *\n * Uso: <div [neuBlockUI]=\"loading$ | async\">...</div>\n */\n@Directive({\n selector: '[neuBlockUI]',\n host: { '[class.neu-block-ui__host]': 'true' },\n})\nexport class NeuBlockUIDirective {\n readonly neuBlockUI = input<boolean>(false);\n\n private readonly _el = inject(ElementRef<HTMLElement>);\n\n constructor() {\n effect(() => {\n const blocked = this.neuBlockUI();\n this._el.nativeElement.classList.toggle('neu-block-ui__host--blocked', blocked);\n });\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":";;;AAYA;;;;;;;;;;;;;;;AAeG;MA0BU,mBAAmB,CAAA;;
|
|
1
|
+
{"version":3,"file":"neural-ui-core-block-ui.mjs","sources":["../../../../projects/ui-core/block-ui/neu-block-ui.component.ts","../../../../projects/ui-core/block-ui/neural-ui-core-block-ui.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n Directive,\n ElementRef,\n ViewEncapsulation,\n computed,\n effect,\n inject,\n input,\n} from '@angular/core';\n\n/**\n * NeuralUI BlockUI Component\n *\n * Superposición que bloquea la interacción de un contenedor mientras está activa.\n *\n * Uso (componente):\n * <div style=\"position:relative\">\n * <neu-block-ui [blocked]=\"isLoading\" message=\"Cargando...\" />\n * <form>...</form>\n * </div>\n *\n * Uso (directiva en el contenedor padre):\n * <div [neuBlockUI]=\"isLoading\">\n * <form>...</form>\n * </div>\n */\n@Component({\n selector: 'neu-block-ui',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class]': 'hostClasses()',\n '[attr.aria-busy]': 'blocked()',\n '[attr.aria-hidden]': '!blocked()',\n role: 'status',\n },\n template: `\n @if (blocked()) {\n <div class=\"neu-block-ui__overlay\">\n <div class=\"neu-block-ui__content\">\n <span class=\"neu-block-ui__spinner\" aria-hidden=\"true\"></span>\n @if (message()) {\n <span class=\"neu-block-ui__message\">{{ message() }}</span>\n }\n </div>\n </div>\n }\n `,\n styleUrl: './neu-block-ui.component.scss',\n})\nexport class NeuBlockUIComponent {\n /** Activa la superposición / Activates the overlay */\n readonly blocked = input<boolean>(false);\n\n /** Mensaje opcional bajo el spinner / Optional message below the spinner */\n readonly message = input<string>('');\n\n /** Variante de opacidad del overlay */\n readonly variant = input<'default' | 'light' | 'dark'>('default');\n\n readonly hostClasses = computed(() => ({\n 'neu-block-ui': true,\n [`neu-block-ui--${this.variant()}`]: true,\n }));\n}\n\n/**\n * Directive [neuBlockUI] — Aplica el efecto BlockUI al elemento host.\n *\n * Uso: <div [neuBlockUI]=\"loading$ | async\">...</div>\n */\n@Directive({\n selector: '[neuBlockUI]',\n host: { '[class.neu-block-ui__host]': 'true' },\n})\nexport class NeuBlockUIDirective {\n readonly neuBlockUI = input<boolean>(false);\n\n private readonly _el = inject(ElementRef<HTMLElement>);\n\n constructor() {\n effect(() => {\n const blocked = this.neuBlockUI();\n this._el.nativeElement.classList.toggle('neu-block-ui__host--blocked', blocked);\n });\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
|
|
@@ -19,13 +19,11 @@ import { RouterLink } from '@angular/router';
|
|
|
19
19
|
*/
|
|
20
20
|
class NeuBreadcrumbComponent {
|
|
21
21
|
/** Lista de ítems de navegación / Navigation item list */
|
|
22
|
-
items = input([], /*
|
|
23
|
-
...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
22
|
+
items = input([], ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
24
23
|
/** Separador personalizable / Customizable separator */
|
|
25
|
-
separator = input('/', /*
|
|
26
|
-
|
|
27
|
-
static
|
|
28
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: NeuBreadcrumbComponent, isStandalone: true, selector: "neu-breadcrumb", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, separator: { classPropertyName: "separator", publicName: "separator", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
24
|
+
separator = input('/', ...(ngDevMode ? [{ debugName: "separator" }] : /* istanbul ignore next */ []));
|
|
25
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuBreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
26
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: NeuBreadcrumbComponent, isStandalone: true, selector: "neu-breadcrumb", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, separator: { classPropertyName: "separator", publicName: "separator", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
29
27
|
<nav class="neu-breadcrumb" aria-label="Breadcrumb">
|
|
30
28
|
<ol class="neu-breadcrumb__list">
|
|
31
29
|
@for (item of items(); track item.label; let last = $last) {
|
|
@@ -48,9 +46,9 @@ class NeuBreadcrumbComponent {
|
|
|
48
46
|
}
|
|
49
47
|
</ol>
|
|
50
48
|
</nav>
|
|
51
|
-
`, isInline: true, styles: [".neu-breadcrumb{display:inline-flex}.neu-breadcrumb__list{display:flex;align-items:center;flex-wrap:wrap;gap:4px;list-style:none;margin:0;padding:0;font-family:var(--neu-font-sans);font-size:var(--neu-text-sm)}.neu-breadcrumb__item{display:inline-flex;align-items:center;gap:4px}.neu-breadcrumb__link{color:var(--neu-text-muted);text-decoration:none;transition:color var(--neu-transition);border-radius:var(--neu-radius-xs);outline:none}.neu-breadcrumb__link:hover{color:var(--neu-text)}.neu-breadcrumb__link:focus-visible{outline:2px solid var(--neu-primary);outline-offset:2px}.neu-breadcrumb__separator{color:var(--neu-text-disabled);font-size:var(--neu-text-xs);-webkit-user-select:none;user-select:none;margin:0 2px}.neu-breadcrumb__current{color:var(--neu-text);font-weight:500}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "
|
|
49
|
+
`, isInline: true, styles: [".neu-breadcrumb{display:inline-flex}.neu-breadcrumb__list{display:flex;align-items:center;flex-wrap:wrap;gap:4px;list-style:none;margin:0;padding:0;font-family:var(--neu-font-sans);font-size:var(--neu-text-sm)}.neu-breadcrumb__item{display:inline-flex;align-items:center;gap:4px}.neu-breadcrumb__link{color:var(--neu-text-muted);text-decoration:none;transition:color var(--neu-transition);border-radius:var(--neu-radius-xs);outline:none}.neu-breadcrumb__link:hover{color:var(--neu-text)}.neu-breadcrumb__link:focus-visible{outline:2px solid var(--neu-primary);outline-offset:2px}.neu-breadcrumb__separator{color:var(--neu-text-disabled);font-size:var(--neu-text-xs);-webkit-user-select:none;user-select:none;margin:0 2px}.neu-breadcrumb__current{color:var(--neu-text);font-weight:500}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
52
50
|
}
|
|
53
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
51
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuBreadcrumbComponent, decorators: [{
|
|
54
52
|
type: Component,
|
|
55
53
|
args: [{ selector: 'neu-breadcrumb', imports: [RouterLink], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
56
54
|
<nav class="neu-breadcrumb" aria-label="Breadcrumb">
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neural-ui-core-breadcrumb.mjs","sources":["../../../../projects/ui-core/breadcrumb/neu-breadcrumb.component.ts","../../../../projects/ui-core/breadcrumb/neural-ui-core-breadcrumb.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, ViewEncapsulation, input } from '@angular/core';\nimport { RouterLink } from '@angular/router';\n\nexport interface NeuBreadcrumbItem {\n /** Etiqueta visible / Visible label */\n label: string;\n /** Ruta interna (RouterLink) / Internal route (RouterLink) */\n route?: string | string[];\n /** URL externa / External URL */\n url?: string;\n /** Icono Lucide opcional / Optional Lucide icon */\n icon?: string;\n}\n\n/**\n * NeuralUI Breadcrumb Component\n *\n * Ruta de navegación jerárquica. El último elemento se muestra\n * como activo (sin enlace).\n *\n * Uso:\n * <neu-breadcrumb [items]=\"breadcrumbs\" />\n *\n * items = [\n * { label: 'Inicio', route: '/' },\n * { label: 'Componentes', route: '/components' },\n * { label: 'Breadcrumb' },\n * ];\n */\n@Component({\n selector: 'neu-breadcrumb',\n imports: [RouterLink],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <nav class=\"neu-breadcrumb\" aria-label=\"Breadcrumb\">\n <ol class=\"neu-breadcrumb__list\">\n @for (item of items(); track item.label; let last = $last) {\n <li class=\"neu-breadcrumb__item\" [class.neu-breadcrumb__item--active]=\"last\">\n @if (!last) {\n @if (item.route) {\n <a class=\"neu-breadcrumb__link\" [routerLink]=\"item.route\">{{ item.label }}</a>\n } @else if (item.url) {\n <a class=\"neu-breadcrumb__link\" [href]=\"item.url\" target=\"_blank\" rel=\"noopener\">{{\n item.label\n }}</a>\n } @else {\n <span class=\"neu-breadcrumb__link\">{{ item.label }}</span>\n }\n <span class=\"neu-breadcrumb__separator\" aria-hidden=\"true\">{{ separator() }}</span>\n } @else {\n <span class=\"neu-breadcrumb__current\" aria-current=\"page\">{{ item.label }}</span>\n }\n </li>\n }\n </ol>\n </nav>\n `,\n styleUrl: './neu-breadcrumb.component.scss',\n})\nexport class NeuBreadcrumbComponent {\n /** Lista de ítems de navegación / Navigation item list */\n items = input<NeuBreadcrumbItem[]>([]);\n\n /** Separador personalizable / Customizable separator */\n separator = input<string>('/');\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":";;;;AAcA;;;;;;;;;;;;;;AAcG;MAgCU,sBAAsB,CAAA;;
|
|
1
|
+
{"version":3,"file":"neural-ui-core-breadcrumb.mjs","sources":["../../../../projects/ui-core/breadcrumb/neu-breadcrumb.component.ts","../../../../projects/ui-core/breadcrumb/neural-ui-core-breadcrumb.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, ViewEncapsulation, input } from '@angular/core';\nimport { RouterLink } from '@angular/router';\n\nexport interface NeuBreadcrumbItem {\n /** Etiqueta visible / Visible label */\n label: string;\n /** Ruta interna (RouterLink) / Internal route (RouterLink) */\n route?: string | string[];\n /** URL externa / External URL */\n url?: string;\n /** Icono Lucide opcional / Optional Lucide icon */\n icon?: string;\n}\n\n/**\n * NeuralUI Breadcrumb Component\n *\n * Ruta de navegación jerárquica. El último elemento se muestra\n * como activo (sin enlace).\n *\n * Uso:\n * <neu-breadcrumb [items]=\"breadcrumbs\" />\n *\n * items = [\n * { label: 'Inicio', route: '/' },\n * { label: 'Componentes', route: '/components' },\n * { label: 'Breadcrumb' },\n * ];\n */\n@Component({\n selector: 'neu-breadcrumb',\n imports: [RouterLink],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <nav class=\"neu-breadcrumb\" aria-label=\"Breadcrumb\">\n <ol class=\"neu-breadcrumb__list\">\n @for (item of items(); track item.label; let last = $last) {\n <li class=\"neu-breadcrumb__item\" [class.neu-breadcrumb__item--active]=\"last\">\n @if (!last) {\n @if (item.route) {\n <a class=\"neu-breadcrumb__link\" [routerLink]=\"item.route\">{{ item.label }}</a>\n } @else if (item.url) {\n <a class=\"neu-breadcrumb__link\" [href]=\"item.url\" target=\"_blank\" rel=\"noopener\">{{\n item.label\n }}</a>\n } @else {\n <span class=\"neu-breadcrumb__link\">{{ item.label }}</span>\n }\n <span class=\"neu-breadcrumb__separator\" aria-hidden=\"true\">{{ separator() }}</span>\n } @else {\n <span class=\"neu-breadcrumb__current\" aria-current=\"page\">{{ item.label }}</span>\n }\n </li>\n }\n </ol>\n </nav>\n `,\n styleUrl: './neu-breadcrumb.component.scss',\n})\nexport class NeuBreadcrumbComponent {\n /** Lista de ítems de navegación / Navigation item list */\n items = input<NeuBreadcrumbItem[]>([]);\n\n /** Separador personalizable / Customizable separator */\n separator = input<string>('/');\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":";;;;AAcA;;;;;;;;;;;;;;AAcG;MAgCU,sBAAsB,CAAA;;AAEjC,IAAA,KAAK,GAAG,KAAK,CAAsB,EAAE,4EAAC;;AAGtC,IAAA,SAAS,GAAG,KAAK,CAAS,GAAG,gFAAC;wGALnB,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAtB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,sBAAsB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,iBAAA,EAAA,WAAA,EAAA,UAAA,EAAA,WAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA1BvB;;;;;;;;;;;;;;;;;;;;;;;AAuBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,oxBAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EA1BS,UAAU,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,aAAA,EAAA,UAAA,EAAA,qBAAA,EAAA,OAAA,EAAA,MAAA,EAAA,YAAA,EAAA,kBAAA,EAAA,oBAAA,EAAA,YAAA,EAAA,YAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;4FA6BT,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBA/BlC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,gBAAgB,EAAA,OAAA,EACjB,CAAC,UAAU,CAAC,EAAA,aAAA,EACN,iBAAiB,CAAC,IAAI,EAAA,eAAA,EACpB,uBAAuB,CAAC,MAAM,EAAA,QAAA,EACrC;;;;;;;;;;;;;;;;;;;;;;;AAuBT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,oxBAAA,CAAA,EAAA;;;ACzDH;;AAEG;;;;"}
|