@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
|
@@ -28,10 +28,8 @@ class NeuTabsComponent {
|
|
|
28
28
|
_dragStartX = 0;
|
|
29
29
|
_dragStartScrollLeft = 0;
|
|
30
30
|
_suppressNextClick = false;
|
|
31
|
-
_optimisticActiveTabId = signal(null, /*
|
|
32
|
-
...(ngDevMode ? [{ debugName: "
|
|
33
|
-
isDraggingNav = signal(false, /* @ts-ignore */
|
|
34
|
-
...(ngDevMode ? [{ debugName: "isDraggingNav" }] : /* istanbul ignore next */ []));
|
|
31
|
+
_optimisticActiveTabId = signal(null, ...(ngDevMode ? [{ debugName: "_optimisticActiveTabId" }] : /* istanbul ignore next */ []));
|
|
32
|
+
isDraggingNav = signal(false, ...(ngDevMode ? [{ debugName: "isDraggingNav" }] : /* istanbul ignore next */ []));
|
|
35
33
|
_getUrlParamSignal(key) {
|
|
36
34
|
let paramSignal = this._urlParamSignals.get(key);
|
|
37
35
|
if (!paramSignal) {
|
|
@@ -51,17 +49,13 @@ class NeuTabsComponent {
|
|
|
51
49
|
});
|
|
52
50
|
}
|
|
53
51
|
/** Definición de pestañas / Tab definitions */
|
|
54
|
-
tabs = input([], /*
|
|
55
|
-
...(ngDevMode ? [{ debugName: "tabs" }] : /* istanbul ignore next */ []));
|
|
52
|
+
tabs = input([], ...(ngDevMode ? [{ debugName: "tabs" }] : /* istanbul ignore next */ []));
|
|
56
53
|
/** QueryParam que almacena la pestaña activa / QueryParam that stores the active tab */
|
|
57
|
-
tabParam = input('tab', /*
|
|
58
|
-
...(ngDevMode ? [{ debugName: "tabParam" }] : /* istanbul ignore next */ []));
|
|
54
|
+
tabParam = input('tab', ...(ngDevMode ? [{ debugName: "tabParam" }] : /* istanbul ignore next */ []));
|
|
59
55
|
/** Si true, elimina el padding interno de los paneles / If true, removes the internal padding from panels */
|
|
60
|
-
flush = input(false, /*
|
|
61
|
-
...(ngDevMode ? [{ debugName: "flush" }] : /* istanbul ignore next */ []));
|
|
56
|
+
flush = input(false, ...(ngDevMode ? [{ debugName: "flush" }] : /* istanbul ignore next */ []));
|
|
62
57
|
/** Etiqueta accesible del rol tablist / Accessible label for the tablist role */
|
|
63
|
-
ariaLabel = input('Pestañas de contenido', /*
|
|
64
|
-
...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
58
|
+
ariaLabel = input('Pestañas de contenido', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
65
59
|
/** Emite al cambiar de pestaña / Emits when the tab changes */
|
|
66
60
|
tabChange = output();
|
|
67
61
|
/** ID de la pestaña activa (de la URL o la primera disponible) / Active tab ID (from the URL or the first available) */
|
|
@@ -77,15 +71,11 @@ class NeuTabsComponent {
|
|
|
77
71
|
return optimisticAvailable.id;
|
|
78
72
|
// Fallback: primera pestaña no deshabilitada
|
|
79
73
|
return tabList.find((t) => !t.disabled)?.id ?? '';
|
|
80
|
-
}, /*
|
|
81
|
-
...(ngDevMode ? [{ debugName: "activeTabId" }] : /* istanbul ignore next */ []));
|
|
74
|
+
}, ...(ngDevMode ? [{ debugName: "activeTabId" }] : /* istanbul ignore next */ []));
|
|
82
75
|
/** Posición del indicador calculada mediante medición DOM / Indicator position calculated via DOM measurement */
|
|
83
|
-
_indicatorLeft = signal('0px', /*
|
|
84
|
-
...(ngDevMode ? [{ debugName: "
|
|
85
|
-
|
|
86
|
-
...(ngDevMode ? [{ debugName: "_indicatorWidth" }] : /* istanbul ignore next */ []));
|
|
87
|
-
indicatorStyle = computed(() => `left: ${this._indicatorLeft()}; width: ${this._indicatorWidth()}`, /* @ts-ignore */
|
|
88
|
-
...(ngDevMode ? [{ debugName: "indicatorStyle" }] : /* istanbul ignore next */ []));
|
|
76
|
+
_indicatorLeft = signal('0px', ...(ngDevMode ? [{ debugName: "_indicatorLeft" }] : /* istanbul ignore next */ []));
|
|
77
|
+
_indicatorWidth = signal('0px', ...(ngDevMode ? [{ debugName: "_indicatorWidth" }] : /* istanbul ignore next */ []));
|
|
78
|
+
indicatorStyle = computed(() => `left: ${this._indicatorLeft()}; width: ${this._indicatorWidth()}`, ...(ngDevMode ? [{ debugName: "indicatorStyle" }] : /* istanbul ignore next */ []));
|
|
89
79
|
ngAfterViewInit() {
|
|
90
80
|
this._updateIndicator();
|
|
91
81
|
// Actualizar cuando cambie el tamaño del nav (p.ej. resize de ventana)
|
|
@@ -195,8 +185,8 @@ class NeuTabsComponent {
|
|
|
195
185
|
const btn = this.elRef.nativeElement.querySelector(`#neu-tab-${next.id}`);
|
|
196
186
|
btn?.focus();
|
|
197
187
|
}
|
|
198
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
199
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
188
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuTabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
189
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: NeuTabsComponent, isStandalone: true, selector: "neu-tabs", inputs: { tabs: { classPropertyName: "tabs", publicName: "tabs", isSignal: true, isRequired: false, transformFunction: null }, tabParam: { classPropertyName: "tabParam", publicName: "tabParam", isSignal: true, isRequired: false, transformFunction: null }, flush: { classPropertyName: "flush", publicName: "flush", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { tabChange: "tabChange" }, providers: [{ provide: NEU_TABS_CONTEXT, useExisting: NeuTabsComponent }], ngImport: i0, template: `
|
|
200
190
|
<!-- Barra de pestañas -->
|
|
201
191
|
<div class="neu-tabs" [class.neu-tabs--flush]="flush()">
|
|
202
192
|
<div
|
|
@@ -245,7 +235,7 @@ class NeuTabsComponent {
|
|
|
245
235
|
</div>
|
|
246
236
|
`, isInline: true, styles: [".neu-tabs{display:flex;flex-direction:column}.neu-tabs__nav{position:relative;display:flex;border-bottom:1.5px solid var(--neu-border);overflow-x:auto;cursor:grab;touch-action:pan-x;scrollbar-width:none}.neu-tabs__nav::-webkit-scrollbar{display:none}.neu-tabs__nav--dragging{cursor:grabbing;-webkit-user-select:none;user-select:none}.neu-tabs__tab{position:relative;display:inline-flex;align-items:center;gap:var(--neu-space-2);padding:var(--neu-space-3) var(--neu-space-5);background:transparent;border:none;font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);font-weight:500;color:color-mix(in srgb,var(--neu-text) 72%,var(--neu-surface) 28%);cursor:pointer;white-space:nowrap;flex-shrink:0;transition:color var(--neu-transition),background-color var(--neu-transition);outline:none}.neu-tabs__tab:hover:not(:disabled){color:var(--neu-text);background:var(--neu-surface-2)}.neu-tabs__tab:focus-visible{outline:2px solid var(--neu-primary);outline-offset:-2px;border-radius:var(--neu-radius-sm) var(--neu-radius-sm) 0 0}.neu-tabs__tab--active{color:var(--neu-primary-dark, var(--neu-primary));font-weight:600}.neu-tabs__tab--disabled{opacity:.4;cursor:not-allowed}.neu-tabs__tab-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;border-radius:var(--neu-radius-full);background:var(--neu-primary-100);color:var(--neu-primary-dark, var(--neu-primary));font-size:10px;font-weight:700;line-height:1}.neu-tabs__indicator{position:absolute;bottom:-1.5px;height:2.5px;background:var(--neu-primary);border-radius:var(--neu-radius-full) var(--neu-radius-full) 0 0;transition:left var(--neu-transition-slow),width var(--neu-transition-slow);pointer-events:none}.neu-tabs__panels{flex:1}.neu-tab-panel{padding-top:1.5rem;animation:neu-tab-fade .18s ease}@keyframes neu-tab-fade{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
247
237
|
}
|
|
248
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
238
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuTabsComponent, decorators: [{
|
|
249
239
|
type: Component,
|
|
250
240
|
args: [{ selector: 'neu-tabs', imports: [], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [{ provide: NEU_TABS_CONTEXT, useExisting: NeuTabsComponent }], template: `
|
|
251
241
|
<!-- Barra de pestañas -->
|
|
@@ -311,12 +301,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
311
301
|
class NeuTabPanelComponent {
|
|
312
302
|
tabs = inject(NEU_TABS_CONTEXT, { optional: true });
|
|
313
303
|
/** ID que debe coincidir con NeuTab.id del padre / ID that must match the parent NeuTab.id */
|
|
314
|
-
tabId = input.required(/*
|
|
315
|
-
...(ngDevMode ? [{ debugName: "
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NeuTabPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
319
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: NeuTabPanelComponent, isStandalone: true, selector: "neu-tab-panel", inputs: { tabId: { classPropertyName: "tabId", publicName: "tabId", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
|
|
304
|
+
tabId = input.required(...(ngDevMode ? [{ debugName: "tabId" }] : /* istanbul ignore next */ []));
|
|
305
|
+
isActive = computed(() => this.tabs?.activeTabId() === this.tabId(), ...(ngDevMode ? [{ debugName: "isActive" }] : /* istanbul ignore next */ []));
|
|
306
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuTabPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
307
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: NeuTabPanelComponent, isStandalone: true, selector: "neu-tab-panel", inputs: { tabId: { classPropertyName: "tabId", publicName: "tabId", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
|
|
320
308
|
@if (isActive()) {
|
|
321
309
|
<div
|
|
322
310
|
class="neu-tab-panel"
|
|
@@ -329,7 +317,7 @@ class NeuTabPanelComponent {
|
|
|
329
317
|
}
|
|
330
318
|
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
331
319
|
}
|
|
332
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
320
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuTabPanelComponent, decorators: [{
|
|
333
321
|
type: Component,
|
|
334
322
|
args: [{
|
|
335
323
|
selector: 'neu-tab-panel',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neural-ui-core-tabs.mjs","sources":["../../../../projects/ui-core/tabs/neu-tabs.component.ts","../../../../projects/ui-core/tabs/neural-ui-core-tabs.ts"],"sourcesContent":["import {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n InjectionToken,\n OnDestroy,\n Signal,\n ViewEncapsulation,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { NeuUrlStateService } from '@neural-ui/core/url-state';\n\n// ----------------------------------------------------------------\n// Token de contexto — permite a NeuTabPanelComponent inyectar\n// la instancia padre sin pasar signals manualmente.\n// ----------------------------------------------------------------\nexport const NEU_TABS_CONTEXT = new InjectionToken<NeuTabsComponent>('NeuTabsContext');\n\nexport interface NeuTab {\n /** ID único de la pestaña — se usa como valor en la URL / Unique tab ID — used as the URL value */\n id: string;\n /** Etiqueta visible / Visible label */\n label: string;\n /** Badge opcional junto al label / Optional badge next to the label */\n badge?: string;\n /** Deshabilita la pestaña sin ocultarla / Disables the tab without hiding it */\n disabled?: boolean;\n}\n\n/**\n * NeuralUI Tabs Component\n *\n * Sistema de pestañas con estado sincronizado a la URL via NeuUrlStateService. / Tab system with state synchronized to the URL via NeuUrlStateService.\n * El panel activo se determina por ?{tabParam}={tabId}. / The active panel is determined by ?{tabParam}={tabId}.\n *\n * Uso:\n * <neu-tabs [tabs]=\"tabs\" tabParam=\"tab\">\n * <neu-tab-panel tabId=\"preview\">...</neu-tab-panel>\n * <neu-tab-panel tabId=\"api\">...</neu-tab-panel>\n * </neu-tabs>\n */\n@Component({\n selector: 'neu-tabs',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [{ provide: NEU_TABS_CONTEXT, useExisting: NeuTabsComponent }],\n template: `\n <!-- Barra de pestañas -->\n <div class=\"neu-tabs\" [class.neu-tabs--flush]=\"flush()\">\n <div\n class=\"neu-tabs__nav\"\n role=\"tablist\"\n [attr.aria-label]=\"ariaLabel()\"\n [class.neu-tabs__nav--dragging]=\"isDraggingNav()\"\n #navRef\n (pointerdown)=\"startNavDrag($event)\"\n (pointermove)=\"moveNavDrag($event)\"\n (pointerup)=\"endNavDrag($event)\"\n (pointercancel)=\"endNavDrag($event)\"\n >\n @for (tab of tabs(); track tab.id) {\n <button\n class=\"neu-tabs__tab\"\n [class.neu-tabs__tab--active]=\"activeTabId() === tab.id\"\n [class.neu-tabs__tab--disabled]=\"tab.disabled\"\n role=\"tab\"\n [id]=\"'neu-tab-' + tab.id\"\n [attr.aria-selected]=\"activeTabId() === tab.id\"\n [attr.aria-controls]=\"'neu-tabpanel-' + tab.id\"\n [attr.tabindex]=\"activeTabId() === tab.id ? '0' : '-1'\"\n [disabled]=\"tab.disabled\"\n type=\"button\"\n (click)=\"handleTabClick($event, tab)\"\n (keydown.arrowRight)=\"focusTab($any($event), 1)\"\n (keydown.arrowLeft)=\"focusTab($any($event), -1)\"\n (keydown.home)=\"focusTab($any($event), 'first')\"\n (keydown.end)=\"focusTab($any($event), 'last')\"\n >\n {{ tab.label }}\n @if (tab.badge) {\n <span class=\"neu-tabs__tab-badge\">{{ tab.badge }}</span>\n }\n </button>\n }\n <!-- Indicador deslizante -->\n <span class=\"neu-tabs__indicator\" [style]=\"indicatorStyle()\"></span>\n </div>\n\n <!-- Paneles (proyectados desde NeuTabPanelComponent) -->\n <div class=\"neu-tabs__panels\">\n <ng-content />\n </div>\n </div>\n `,\n styleUrl: './neu-tabs.component.scss',\n})\nexport class NeuTabsComponent implements AfterViewInit, OnDestroy {\n private readonly urlState = inject(NeuUrlStateService);\n private readonly elRef = inject(ElementRef);\n private resizeObserver?: ResizeObserver;\n private readonly _urlParamSignals = new Map<string, Signal<string | null>>();\n private _dragPointerId: number | null = null;\n private _dragStartX = 0;\n private _dragStartScrollLeft = 0;\n private _suppressNextClick = false;\n private readonly _optimisticActiveTabId = signal<string | null>(null);\n readonly isDraggingNav = signal(false);\n\n private _getUrlParamSignal(key: string): Signal<string | null> {\n let paramSignal = this._urlParamSignals.get(key);\n if (!paramSignal) {\n paramSignal = this.urlState.getParam(key);\n this._urlParamSignals.set(key, paramSignal);\n }\n return paramSignal;\n }\n\n private _readUrlParam(key: string): string | null {\n return this._getUrlParamSignal(key)();\n }\n\n constructor() {\n // Actualizar indicador cuando activeTabId cambie — debe estar en el constructor (injection context)\n effect(() => {\n this.activeTabId(); // dependencia reactiva\n requestAnimationFrame(() => this._updateIndicator());\n });\n }\n\n /** Definición de pestañas / Tab definitions */\n tabs = input<NeuTab[]>([]);\n\n /** QueryParam que almacena la pestaña activa / QueryParam that stores the active tab */\n tabParam = input<string>('tab');\n\n /** Si true, elimina el padding interno de los paneles / If true, removes the internal padding from panels */\n flush = input<boolean>(false);\n\n /** Etiqueta accesible del rol tablist / Accessible label for the tablist role */\n ariaLabel = input<string>('Pestañas de contenido');\n\n /** Emite al cambiar de pestaña / Emits when the tab changes */\n tabChange = output<string>();\n\n /** ID de la pestaña activa (de la URL o la primera disponible) / Active tab ID (from the URL or the first available) */\n readonly activeTabId = computed(() => {\n const tabList = this.tabs();\n const fromUrl = this._readUrlParam(this.tabParam());\n const available = tabList.find((t) => t.id === fromUrl && !t.disabled);\n if (available) return available.id;\n\n const optimistic = this._optimisticActiveTabId();\n const optimisticAvailable = tabList.find((t) => t.id === optimistic && !t.disabled);\n if (optimisticAvailable) return optimisticAvailable.id;\n\n // Fallback: primera pestaña no deshabilitada\n return tabList.find((t) => !t.disabled)?.id ?? '';\n });\n\n /** Posición del indicador calculada mediante medición DOM / Indicator position calculated via DOM measurement */\n private readonly _indicatorLeft = signal('0px');\n private readonly _indicatorWidth = signal('0px');\n\n readonly indicatorStyle = computed(\n () => `left: ${this._indicatorLeft()}; width: ${this._indicatorWidth()}`,\n );\n\n ngAfterViewInit(): void {\n this._updateIndicator();\n // Actualizar cuando cambie el tamaño del nav (p.ej. resize de ventana)\n const nav = this.elRef.nativeElement.querySelector('.neu-tabs__nav');\n if (nav && typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver(() => this._updateIndicator());\n this.resizeObserver.observe(nav);\n }\n }\n\n ngOnDestroy(): void {\n this.resizeObserver?.disconnect();\n }\n\n private _updateIndicator(): void {\n const nav: HTMLElement | null = this.elRef.nativeElement.querySelector('.neu-tabs__nav');\n if (!nav) return;\n const tabEls = nav.querySelectorAll<HTMLElement>('.neu-tabs__tab');\n const idx = this.tabs().findIndex((t) => t.id === this.activeTabId());\n const tabEl = tabEls[idx];\n if (tabEl) {\n this._indicatorLeft.set(tabEl.offsetLeft + 'px');\n this._indicatorWidth.set(tabEl.offsetWidth + 'px');\n if (typeof tabEl.scrollIntoView === 'function') {\n tabEl.scrollIntoView({\n behavior: 'smooth',\n block: 'nearest',\n inline: 'nearest',\n });\n }\n }\n }\n\n handleTabClick(event: Event, tab: NeuTab): void {\n if (this._suppressNextClick) {\n event.preventDefault();\n event.stopPropagation();\n this._suppressNextClick = false;\n return;\n }\n this.selectTab(tab);\n }\n\n selectTab(tab: NeuTab): void {\n if (tab.disabled) return;\n this._optimisticActiveTabId.set(tab.id);\n this.urlState.setParam(this.tabParam(), tab.id);\n this.tabChange.emit(tab.id);\n requestAnimationFrame(() => this._updateIndicator());\n }\n\n startNavDrag(event: PointerEvent): void {\n if (event.pointerType === 'mouse' && event.button !== 0) return;\n const target = event.target as HTMLElement | null;\n if (!target?.closest('.neu-tabs__nav')) return;\n if (target.closest('.neu-tabs__tab')) return;\n\n const nav = event.currentTarget as HTMLElement;\n this._dragPointerId = event.pointerId;\n this._dragStartX = event.clientX;\n this._dragStartScrollLeft = nav.scrollLeft;\n this.isDraggingNav.set(false);\n nav.setPointerCapture(event.pointerId);\n }\n\n moveNavDrag(event: PointerEvent): void {\n if (this._dragPointerId !== event.pointerId) return;\n\n const nav = event.currentTarget as HTMLElement;\n const deltaX = event.clientX - this._dragStartX;\n if (!this.isDraggingNav() && Math.abs(deltaX) > 6) {\n this.isDraggingNav.set(true);\n this._suppressNextClick = true;\n }\n if (!this.isDraggingNav()) return;\n\n nav.scrollLeft = this._dragStartScrollLeft - deltaX;\n event.preventDefault();\n }\n\n endNavDrag(event: PointerEvent): void {\n if (this._dragPointerId !== event.pointerId) return;\n\n const nav = event.currentTarget as HTMLElement;\n if (nav.hasPointerCapture(event.pointerId)) {\n nav.releasePointerCapture(event.pointerId);\n }\n this._dragPointerId = null;\n if (this.isDraggingNav()) {\n requestAnimationFrame(() => this.isDraggingNav.set(false));\n }\n }\n\n /** Mueve el foco entre tabs con flechas (roving tabindex — WAI-ARIA Tabs Pattern) / Moves focus between tabs with arrows (roving tabindex — WAI-ARIA Tabs Pattern) */\n focusTab(event: Event, dir: 1 | -1 | 'first' | 'last'): void {\n event.preventDefault();\n const enabledTabs = this.tabs().filter((t) => !t.disabled);\n const currentIdx = enabledTabs.findIndex((t) => t.id === this.activeTabId());\n let nextIdx: number;\n if (dir === 'first') {\n nextIdx = 0;\n } else if (dir === 'last') {\n nextIdx = enabledTabs.length - 1;\n } else {\n nextIdx = (currentIdx + dir + enabledTabs.length) % enabledTabs.length;\n }\n const next = enabledTabs[nextIdx];\n this.selectTab(next);\n const btn = (this.elRef.nativeElement as HTMLElement).querySelector(\n `#neu-tab-${next.id}`,\n ) as HTMLElement | null;\n btn?.focus();\n }\n}\n\n// ----------------------------------------------------------------\n// NeuTabPanelComponent — panel individual (usa DI para el contexto)\n// ----------------------------------------------------------------\n\n/**\n * NeuralUI Tab Panel\n *\n * Panel de contenido asociado a una pestaña de NeuTabsComponent. / Content panel associated with a NeuTabsComponent tab.\n * Solo se renderiza (no oculta con CSS) cuando la pestaña está activa. / Only rendered (not hidden with CSS) when the tab is active.\n *\n * Uso: hijo directo de <neu-tabs>\n * <neu-tab-panel tabId=\"api\">...</neu-tab-panel>\n */\n@Component({\n selector: 'neu-tab-panel',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (isActive()) {\n <div\n class=\"neu-tab-panel\"\n role=\"tabpanel\"\n [id]=\"'neu-tabpanel-' + tabId()\"\n [attr.aria-labelledby]=\"'neu-tab-' + tabId()\"\n >\n <ng-content />\n </div>\n }\n `,\n})\nexport class NeuTabPanelComponent {\n private readonly tabs = inject(NEU_TABS_CONTEXT, { optional: true });\n\n /** ID que debe coincidir con NeuTab.id del padre / ID that must match the parent NeuTab.id */\n tabId = input.required<string>();\n\n readonly isActive = computed(() => this.tabs?.activeTabId() === this.tabId());\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-tabs.mjs","sources":["../../../../projects/ui-core/tabs/neu-tabs.component.ts","../../../../projects/ui-core/tabs/neural-ui-core-tabs.ts"],"sourcesContent":["import {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n InjectionToken,\n OnDestroy,\n Signal,\n ViewEncapsulation,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { NeuUrlStateService } from '@neural-ui/core/url-state';\n\n// ----------------------------------------------------------------\n// Token de contexto — permite a NeuTabPanelComponent inyectar\n// la instancia padre sin pasar signals manualmente.\n// ----------------------------------------------------------------\nexport const NEU_TABS_CONTEXT = new InjectionToken<NeuTabsComponent>('NeuTabsContext');\n\nexport interface NeuTab {\n /** ID único de la pestaña — se usa como valor en la URL / Unique tab ID — used as the URL value */\n id: string;\n /** Etiqueta visible / Visible label */\n label: string;\n /** Badge opcional junto al label / Optional badge next to the label */\n badge?: string;\n /** Deshabilita la pestaña sin ocultarla / Disables the tab without hiding it */\n disabled?: boolean;\n}\n\n/**\n * NeuralUI Tabs Component\n *\n * Sistema de pestañas con estado sincronizado a la URL via NeuUrlStateService. / Tab system with state synchronized to the URL via NeuUrlStateService.\n * El panel activo se determina por ?{tabParam}={tabId}. / The active panel is determined by ?{tabParam}={tabId}.\n *\n * Uso:\n * <neu-tabs [tabs]=\"tabs\" tabParam=\"tab\">\n * <neu-tab-panel tabId=\"preview\">...</neu-tab-panel>\n * <neu-tab-panel tabId=\"api\">...</neu-tab-panel>\n * </neu-tabs>\n */\n@Component({\n selector: 'neu-tabs',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n providers: [{ provide: NEU_TABS_CONTEXT, useExisting: NeuTabsComponent }],\n template: `\n <!-- Barra de pestañas -->\n <div class=\"neu-tabs\" [class.neu-tabs--flush]=\"flush()\">\n <div\n class=\"neu-tabs__nav\"\n role=\"tablist\"\n [attr.aria-label]=\"ariaLabel()\"\n [class.neu-tabs__nav--dragging]=\"isDraggingNav()\"\n #navRef\n (pointerdown)=\"startNavDrag($event)\"\n (pointermove)=\"moveNavDrag($event)\"\n (pointerup)=\"endNavDrag($event)\"\n (pointercancel)=\"endNavDrag($event)\"\n >\n @for (tab of tabs(); track tab.id) {\n <button\n class=\"neu-tabs__tab\"\n [class.neu-tabs__tab--active]=\"activeTabId() === tab.id\"\n [class.neu-tabs__tab--disabled]=\"tab.disabled\"\n role=\"tab\"\n [id]=\"'neu-tab-' + tab.id\"\n [attr.aria-selected]=\"activeTabId() === tab.id\"\n [attr.aria-controls]=\"'neu-tabpanel-' + tab.id\"\n [attr.tabindex]=\"activeTabId() === tab.id ? '0' : '-1'\"\n [disabled]=\"tab.disabled\"\n type=\"button\"\n (click)=\"handleTabClick($event, tab)\"\n (keydown.arrowRight)=\"focusTab($any($event), 1)\"\n (keydown.arrowLeft)=\"focusTab($any($event), -1)\"\n (keydown.home)=\"focusTab($any($event), 'first')\"\n (keydown.end)=\"focusTab($any($event), 'last')\"\n >\n {{ tab.label }}\n @if (tab.badge) {\n <span class=\"neu-tabs__tab-badge\">{{ tab.badge }}</span>\n }\n </button>\n }\n <!-- Indicador deslizante -->\n <span class=\"neu-tabs__indicator\" [style]=\"indicatorStyle()\"></span>\n </div>\n\n <!-- Paneles (proyectados desde NeuTabPanelComponent) -->\n <div class=\"neu-tabs__panels\">\n <ng-content />\n </div>\n </div>\n `,\n styleUrl: './neu-tabs.component.scss',\n})\nexport class NeuTabsComponent implements AfterViewInit, OnDestroy {\n private readonly urlState = inject(NeuUrlStateService);\n private readonly elRef = inject(ElementRef);\n private resizeObserver?: ResizeObserver;\n private readonly _urlParamSignals = new Map<string, Signal<string | null>>();\n private _dragPointerId: number | null = null;\n private _dragStartX = 0;\n private _dragStartScrollLeft = 0;\n private _suppressNextClick = false;\n private readonly _optimisticActiveTabId = signal<string | null>(null);\n readonly isDraggingNav = signal(false);\n\n private _getUrlParamSignal(key: string): Signal<string | null> {\n let paramSignal = this._urlParamSignals.get(key);\n if (!paramSignal) {\n paramSignal = this.urlState.getParam(key);\n this._urlParamSignals.set(key, paramSignal);\n }\n return paramSignal;\n }\n\n private _readUrlParam(key: string): string | null {\n return this._getUrlParamSignal(key)();\n }\n\n constructor() {\n // Actualizar indicador cuando activeTabId cambie — debe estar en el constructor (injection context)\n effect(() => {\n this.activeTabId(); // dependencia reactiva\n requestAnimationFrame(() => this._updateIndicator());\n });\n }\n\n /** Definición de pestañas / Tab definitions */\n tabs = input<NeuTab[]>([]);\n\n /** QueryParam que almacena la pestaña activa / QueryParam that stores the active tab */\n tabParam = input<string>('tab');\n\n /** Si true, elimina el padding interno de los paneles / If true, removes the internal padding from panels */\n flush = input<boolean>(false);\n\n /** Etiqueta accesible del rol tablist / Accessible label for the tablist role */\n ariaLabel = input<string>('Pestañas de contenido');\n\n /** Emite al cambiar de pestaña / Emits when the tab changes */\n tabChange = output<string>();\n\n /** ID de la pestaña activa (de la URL o la primera disponible) / Active tab ID (from the URL or the first available) */\n readonly activeTabId = computed(() => {\n const tabList = this.tabs();\n const fromUrl = this._readUrlParam(this.tabParam());\n const available = tabList.find((t) => t.id === fromUrl && !t.disabled);\n if (available) return available.id;\n\n const optimistic = this._optimisticActiveTabId();\n const optimisticAvailable = tabList.find((t) => t.id === optimistic && !t.disabled);\n if (optimisticAvailable) return optimisticAvailable.id;\n\n // Fallback: primera pestaña no deshabilitada\n return tabList.find((t) => !t.disabled)?.id ?? '';\n });\n\n /** Posición del indicador calculada mediante medición DOM / Indicator position calculated via DOM measurement */\n private readonly _indicatorLeft = signal('0px');\n private readonly _indicatorWidth = signal('0px');\n\n readonly indicatorStyle = computed(\n () => `left: ${this._indicatorLeft()}; width: ${this._indicatorWidth()}`,\n );\n\n ngAfterViewInit(): void {\n this._updateIndicator();\n // Actualizar cuando cambie el tamaño del nav (p.ej. resize de ventana)\n const nav = this.elRef.nativeElement.querySelector('.neu-tabs__nav');\n if (nav && typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver(() => this._updateIndicator());\n this.resizeObserver.observe(nav);\n }\n }\n\n ngOnDestroy(): void {\n this.resizeObserver?.disconnect();\n }\n\n private _updateIndicator(): void {\n const nav: HTMLElement | null = this.elRef.nativeElement.querySelector('.neu-tabs__nav');\n if (!nav) return;\n const tabEls = nav.querySelectorAll<HTMLElement>('.neu-tabs__tab');\n const idx = this.tabs().findIndex((t) => t.id === this.activeTabId());\n const tabEl = tabEls[idx];\n if (tabEl) {\n this._indicatorLeft.set(tabEl.offsetLeft + 'px');\n this._indicatorWidth.set(tabEl.offsetWidth + 'px');\n if (typeof tabEl.scrollIntoView === 'function') {\n tabEl.scrollIntoView({\n behavior: 'smooth',\n block: 'nearest',\n inline: 'nearest',\n });\n }\n }\n }\n\n handleTabClick(event: Event, tab: NeuTab): void {\n if (this._suppressNextClick) {\n event.preventDefault();\n event.stopPropagation();\n this._suppressNextClick = false;\n return;\n }\n this.selectTab(tab);\n }\n\n selectTab(tab: NeuTab): void {\n if (tab.disabled) return;\n this._optimisticActiveTabId.set(tab.id);\n this.urlState.setParam(this.tabParam(), tab.id);\n this.tabChange.emit(tab.id);\n requestAnimationFrame(() => this._updateIndicator());\n }\n\n startNavDrag(event: PointerEvent): void {\n if (event.pointerType === 'mouse' && event.button !== 0) return;\n const target = event.target as HTMLElement | null;\n if (!target?.closest('.neu-tabs__nav')) return;\n if (target.closest('.neu-tabs__tab')) return;\n\n const nav = event.currentTarget as HTMLElement;\n this._dragPointerId = event.pointerId;\n this._dragStartX = event.clientX;\n this._dragStartScrollLeft = nav.scrollLeft;\n this.isDraggingNav.set(false);\n nav.setPointerCapture(event.pointerId);\n }\n\n moveNavDrag(event: PointerEvent): void {\n if (this._dragPointerId !== event.pointerId) return;\n\n const nav = event.currentTarget as HTMLElement;\n const deltaX = event.clientX - this._dragStartX;\n if (!this.isDraggingNav() && Math.abs(deltaX) > 6) {\n this.isDraggingNav.set(true);\n this._suppressNextClick = true;\n }\n if (!this.isDraggingNav()) return;\n\n nav.scrollLeft = this._dragStartScrollLeft - deltaX;\n event.preventDefault();\n }\n\n endNavDrag(event: PointerEvent): void {\n if (this._dragPointerId !== event.pointerId) return;\n\n const nav = event.currentTarget as HTMLElement;\n if (nav.hasPointerCapture(event.pointerId)) {\n nav.releasePointerCapture(event.pointerId);\n }\n this._dragPointerId = null;\n if (this.isDraggingNav()) {\n requestAnimationFrame(() => this.isDraggingNav.set(false));\n }\n }\n\n /** Mueve el foco entre tabs con flechas (roving tabindex — WAI-ARIA Tabs Pattern) / Moves focus between tabs with arrows (roving tabindex — WAI-ARIA Tabs Pattern) */\n focusTab(event: Event, dir: 1 | -1 | 'first' | 'last'): void {\n event.preventDefault();\n const enabledTabs = this.tabs().filter((t) => !t.disabled);\n const currentIdx = enabledTabs.findIndex((t) => t.id === this.activeTabId());\n let nextIdx: number;\n if (dir === 'first') {\n nextIdx = 0;\n } else if (dir === 'last') {\n nextIdx = enabledTabs.length - 1;\n } else {\n nextIdx = (currentIdx + dir + enabledTabs.length) % enabledTabs.length;\n }\n const next = enabledTabs[nextIdx];\n this.selectTab(next);\n const btn = (this.elRef.nativeElement as HTMLElement).querySelector(\n `#neu-tab-${next.id}`,\n ) as HTMLElement | null;\n btn?.focus();\n }\n}\n\n// ----------------------------------------------------------------\n// NeuTabPanelComponent — panel individual (usa DI para el contexto)\n// ----------------------------------------------------------------\n\n/**\n * NeuralUI Tab Panel\n *\n * Panel de contenido asociado a una pestaña de NeuTabsComponent. / Content panel associated with a NeuTabsComponent tab.\n * Solo se renderiza (no oculta con CSS) cuando la pestaña está activa. / Only rendered (not hidden with CSS) when the tab is active.\n *\n * Uso: hijo directo de <neu-tabs>\n * <neu-tab-panel tabId=\"api\">...</neu-tab-panel>\n */\n@Component({\n selector: 'neu-tab-panel',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (isActive()) {\n <div\n class=\"neu-tab-panel\"\n role=\"tabpanel\"\n [id]=\"'neu-tabpanel-' + tabId()\"\n [attr.aria-labelledby]=\"'neu-tab-' + tabId()\"\n >\n <ng-content />\n </div>\n }\n `,\n})\nexport class NeuTabPanelComponent {\n private readonly tabs = inject(NEU_TABS_CONTEXT, { optional: true });\n\n /** ID que debe coincidir con NeuTab.id del padre / ID that must match the parent NeuTab.id */\n tabId = input.required<string>();\n\n readonly isActive = computed(() => this.tabs?.activeTabId() === this.tabId());\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
|
|
@@ -14,53 +14,33 @@ let _neuTextareaIdSeq = 0;
|
|
|
14
14
|
* <neu-textarea label="Bio" [rows]="5" [autoResize]="true" />
|
|
15
15
|
*/
|
|
16
16
|
class NeuTextareaComponent {
|
|
17
|
-
label = input('', /*
|
|
18
|
-
...(ngDevMode ? [{ debugName: "
|
|
19
|
-
rows = input(3, /* @ts-ignore */
|
|
20
|
-
...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
|
|
17
|
+
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
18
|
+
rows = input(3, ...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
|
|
21
19
|
/** Tamaño del campo: 'sm' = compacto | 'md' = estándar | 'lg' = grande / Field size */
|
|
22
|
-
size = input('md', /*
|
|
23
|
-
...(ngDevMode ? [{ debugName: "
|
|
24
|
-
autoResize = input(false, /* @ts-ignore */
|
|
25
|
-
...(ngDevMode ? [{ debugName: "autoResize" }] : /* istanbul ignore next */ []));
|
|
20
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
21
|
+
autoResize = input(false, ...(ngDevMode ? [{ debugName: "autoResize" }] : /* istanbul ignore next */ []));
|
|
26
22
|
/** Permite al usuario redimensionar el campo manualmente (por defecto: true) / Allows the user to manually resize the field (default: true) */
|
|
27
|
-
resizable = input(true, /*
|
|
28
|
-
...(ngDevMode ? [{ debugName: "
|
|
29
|
-
|
|
30
|
-
...(ngDevMode ? [{ debugName: "
|
|
31
|
-
|
|
32
|
-
...(ngDevMode ? [{ debugName: "
|
|
33
|
-
|
|
34
|
-
...(ngDevMode ? [{ debugName: "
|
|
35
|
-
readonly = input(false, /* @ts-ignore */
|
|
36
|
-
...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
|
|
37
|
-
required = input(false, /* @ts-ignore */
|
|
38
|
-
...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
|
|
39
|
-
name = input('', /* @ts-ignore */
|
|
40
|
-
...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
|
|
41
|
-
maxlength = input(null, /* @ts-ignore */
|
|
42
|
-
...(ngDevMode ? [{ debugName: "maxlength" }] : /* istanbul ignore next */ []));
|
|
23
|
+
resizable = input(true, ...(ngDevMode ? [{ debugName: "resizable" }] : /* istanbul ignore next */ []));
|
|
24
|
+
errorMessage = input('', ...(ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []));
|
|
25
|
+
hint = input('', ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
|
|
26
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
27
|
+
readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
|
|
28
|
+
required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
|
|
29
|
+
name = input('', ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
|
|
30
|
+
maxlength = input(null, ...(ngDevMode ? [{ debugName: "maxlength" }] : /* istanbul ignore next */ []));
|
|
43
31
|
_id = `neu-textarea-${_neuTextareaIdSeq++}`;
|
|
44
|
-
_value = signal('', /*
|
|
45
|
-
...(ngDevMode ? [{ debugName: "
|
|
46
|
-
|
|
47
|
-
...(ngDevMode ? [{ debugName: "
|
|
48
|
-
|
|
49
|
-
...(ngDevMode ? [{ debugName: "
|
|
50
|
-
_isDisabledState = computed(() => this.disabled() || this._isDisabled(), /* @ts-ignore */
|
|
51
|
-
...(ngDevMode ? [{ debugName: "_isDisabledState" }] : /* istanbul ignore next */ []));
|
|
52
|
-
hasValue = computed(() => this._value().length > 0, /* @ts-ignore */
|
|
53
|
-
...(ngDevMode ? [{ debugName: "hasValue" }] : /* istanbul ignore next */ []));
|
|
54
|
-
hasError = computed(() => !!this.errorMessage(), /* @ts-ignore */
|
|
55
|
-
...(ngDevMode ? [{ debugName: "hasError" }] : /* istanbul ignore next */ []));
|
|
32
|
+
_value = signal('', ...(ngDevMode ? [{ debugName: "_value" }] : /* istanbul ignore next */ []));
|
|
33
|
+
_focused = signal(false, ...(ngDevMode ? [{ debugName: "_focused" }] : /* istanbul ignore next */ []));
|
|
34
|
+
_isDisabled = signal(false, ...(ngDevMode ? [{ debugName: "_isDisabled" }] : /* istanbul ignore next */ []));
|
|
35
|
+
_isDisabledState = computed(() => this.disabled() || this._isDisabled(), ...(ngDevMode ? [{ debugName: "_isDisabledState" }] : /* istanbul ignore next */ []));
|
|
36
|
+
hasValue = computed(() => this._value().length > 0, ...(ngDevMode ? [{ debugName: "hasValue" }] : /* istanbul ignore next */ []));
|
|
37
|
+
hasError = computed(() => !!this.errorMessage(), ...(ngDevMode ? [{ debugName: "hasError" }] : /* istanbul ignore next */ []));
|
|
56
38
|
_resizeStyle = computed(() => {
|
|
57
39
|
if (this.autoResize())
|
|
58
40
|
return 'none';
|
|
59
41
|
return this.resizable() ? 'vertical' : 'none';
|
|
60
|
-
}, /*
|
|
61
|
-
...(ngDevMode ? [{ debugName: "
|
|
62
|
-
_textareaRef = viewChild('textareaRef', /* @ts-ignore */
|
|
63
|
-
...(ngDevMode ? [{ debugName: "_textareaRef" }] : /* istanbul ignore next */ []));
|
|
42
|
+
}, ...(ngDevMode ? [{ debugName: "_resizeStyle" }] : /* istanbul ignore next */ []));
|
|
43
|
+
_textareaRef = viewChild('textareaRef', ...(ngDevMode ? [{ debugName: "_textareaRef" }] : /* istanbul ignore next */ []));
|
|
64
44
|
_onChange = () => { };
|
|
65
45
|
_onTouched = () => { };
|
|
66
46
|
constructor() {
|
|
@@ -102,8 +82,8 @@ class NeuTextareaComponent {
|
|
|
102
82
|
setDisabledState(isDisabled) {
|
|
103
83
|
this._isDisabled.set(isDisabled);
|
|
104
84
|
}
|
|
105
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
106
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
85
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuTextareaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
86
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: NeuTextareaComponent, isStandalone: true, selector: "neu-textarea", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, autoResize: { classPropertyName: "autoResize", publicName: "autoResize", isSignal: true, isRequired: false, transformFunction: null }, resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, maxlength: { classPropertyName: "maxlength", publicName: "maxlength", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.neu-textarea-host--sm": "size() === \"sm\"", "class.neu-textarea-host--lg": "size() === \"lg\"" }, classAttribute: "neu-textarea-host" }, providers: [
|
|
107
87
|
{
|
|
108
88
|
provide: NG_VALUE_ACCESSOR,
|
|
109
89
|
useExisting: forwardRef(() => NeuTextareaComponent),
|
|
@@ -148,7 +128,7 @@ class NeuTextareaComponent {
|
|
|
148
128
|
</div>
|
|
149
129
|
`, isInline: true, styles: [".neu-textarea-host{display:block;width:100%}.neu-textarea-host--sm .neu-textarea__field{min-height:60px;padding:.7rem var(--neu-space-3) var(--neu-space-2)}.neu-textarea-host--sm .neu-textarea__label{top:.6rem}.neu-textarea-host--lg .neu-textarea__field{min-height:100px;font-size:var(--neu-text-base);padding:1.5rem var(--neu-space-5) var(--neu-space-4)}.neu-textarea-host--lg .neu-textarea__label{top:1.2rem}.neu-textarea__wrapper{position:relative;width:100%}.neu-textarea__wrapper--disabled{opacity:.5;pointer-events:none}.neu-textarea__field{width:100%;min-height:80px;padding:1.25rem var(--neu-space-4) var(--neu-space-3);font-family:var(--neu-font-sans);font-size:var(--neu-text-sm);color:var(--neu-text);background:var(--neu-surface);border:1.5px solid var(--neu-border);border-radius:var(--neu-radius);outline:none;resize:var(--_neu-textarea-resize, vertical);transition:border-color var(--neu-transition),box-shadow var(--neu-transition);line-height:1.5;box-sizing:border-box}.neu-textarea__field::placeholder{color:transparent}.neu-textarea__wrapper--error .neu-textarea__field{border-color:var(--neu-error)}.neu-textarea__wrapper--focused .neu-textarea__field{border-color:var(--neu-border-focus);box-shadow:var(--neu-focus-ring)}.neu-textarea__wrapper--disabled .neu-textarea__field{background:var(--neu-surface-2);cursor:not-allowed}.neu-textarea__field[style*=height]{resize:none;overflow:hidden}.neu-textarea__label{position:absolute;top:.9rem;left:var(--neu-space-4);font-size:var(--neu-text-base);color:var(--neu-text-muted);pointer-events:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:calc(100% - var(--neu-space-8));transition:top var(--neu-transition),transform var(--neu-transition),color var(--neu-transition),font-size var(--neu-transition),padding var(--neu-transition),background var(--neu-transition)}.neu-textarea__wrapper--focused .neu-textarea__label,.neu-textarea__wrapper--has-value .neu-textarea__label{top:0;transform:translateY(-50%);font-size:12px;font-weight:600;letter-spacing:.01em;background:var(--neu-surface);padding:0 4px;left:calc(var(--neu-space-4) - 4px);color:var(--neu-primary)}.neu-textarea__wrapper--focused.neu-textarea__wrapper--error .neu-textarea__label,.neu-textarea__wrapper--error .neu-textarea__label{color:var(--neu-error)}.neu-textarea__wrapper--disabled .neu-textarea__label{background:var(--neu-surface-2)}.neu-textarea__hint{display:block;margin-top:var(--neu-space-1);font-size:var(--neu-text-xs);color:var(--neu-text-muted)}.neu-textarea__error{display:block;margin-top:var(--neu-space-1);font-size:var(--neu-text-xs);color:var(--neu-error-text)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
150
130
|
}
|
|
151
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
131
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuTextareaComponent, decorators: [{
|
|
152
132
|
type: Component,
|
|
153
133
|
args: [{ selector: 'neu-textarea', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
154
134
|
class: 'neu-textarea-host',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neural-ui-core-textarea.mjs","sources":["../../../../projects/ui-core/textarea/neu-textarea.component.ts","../../../../projects/ui-core/textarea/neural-ui-core-textarea.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n computed,\n effect,\n forwardRef,\n inject,\n input,\n signal,\n viewChild,\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\nlet _neuTextareaIdSeq = 0;\n\n/**\n * NeuralUI Textarea Component\n *\n * Textarea con floating label y soporte completo para Angular Forms.\n * Soporta auto-resize opcional.\n *\n * Uso:\n * <neu-textarea label=\"Descripción\" [formControl]=\"ctrl\" />\n * <neu-textarea label=\"Bio\" [rows]=\"5\" [autoResize]=\"true\" />\n */\n@Component({\n selector: 'neu-textarea',\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'neu-textarea-host',\n '[class.neu-textarea-host--sm]': 'size() === \"sm\"',\n '[class.neu-textarea-host--lg]': 'size() === \"lg\"',\n },\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => NeuTextareaComponent),\n multi: true,\n },\n ],\n template: `\n <div\n class=\"neu-textarea__wrapper\"\n [class.neu-textarea__wrapper--focused]=\"_focused()\"\n [class.neu-textarea__wrapper--has-value]=\"hasValue()\"\n [class.neu-textarea__wrapper--error]=\"hasError()\"\n [class.neu-textarea__wrapper--disabled]=\"_isDisabledState()\"\n >\n <textarea\n #textareaRef\n class=\"neu-textarea__field\"\n [id]=\"_id\"\n [rows]=\"rows()\"\n [placeholder]=\"' '\"\n [attr.disabled]=\"_isDisabledState() ? true : null\"\n [attr.readonly]=\"readonly() ? true : null\"\n [attr.required]=\"required() ? true : null\"\n [attr.maxlength]=\"maxlength() ?? null\"\n [attr.name]=\"name() || null\"\n [attr.aria-describedby]=\"hasError() ? _id + '-error' : hint() ? _id + '-hint' : null\"\n [attr.aria-invalid]=\"hasError() ? 'true' : null\"\n [style.resize]=\"_resizeStyle()\"\n [value]=\"_value()\"\n (input)=\"onInput($event)\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n ></textarea>\n <label class=\"neu-textarea__label\" [for]=\"_id\">{{ label() }}</label>\n @if (hint() && !hasError()) {\n <span class=\"neu-textarea__hint\" [id]=\"_id + '-hint'\">{{ hint() }}</span>\n }\n @if (hasError()) {\n <span class=\"neu-textarea__error\" role=\"alert\" [id]=\"_id + '-error'\">{{\n errorMessage()\n }}</span>\n }\n </div>\n `,\n styleUrl: './neu-textarea.component.scss',\n})\nexport class NeuTextareaComponent implements ControlValueAccessor {\n readonly label = input('');\n readonly rows = input<number>(3);\n /** Tamaño del campo: 'sm' = compacto | 'md' = estándar | 'lg' = grande / Field size */\n readonly size = input<'sm' | 'md' | 'lg'>('md');\n readonly autoResize = input<boolean>(false);\n /** Permite al usuario redimensionar el campo manualmente (por defecto: true) / Allows the user to manually resize the field (default: true) */\n readonly resizable = input<boolean>(true);\n readonly errorMessage = input<string>('');\n readonly hint = input<string>('');\n readonly disabled = input<boolean>(false);\n readonly readonly = input<boolean>(false);\n readonly required = input<boolean>(false);\n readonly name = input<string>('');\n readonly maxlength = input<number | null>(null);\n\n readonly _id = `neu-textarea-${_neuTextareaIdSeq++}`;\n\n protected readonly _value = signal('');\n protected readonly _focused = signal(false);\n protected readonly _isDisabled = signal(false);\n\n readonly _isDisabledState = computed(() => this.disabled() || this._isDisabled());\n readonly hasValue = computed(() => this._value().length > 0);\n readonly hasError = computed(() => !!this.errorMessage());\n readonly _resizeStyle = computed(() => {\n if (this.autoResize()) return 'none';\n return this.resizable() ? 'vertical' : 'none';\n });\n\n private readonly _textareaRef = viewChild<ElementRef<HTMLTextAreaElement>>('textareaRef');\n\n private _onChange: (v: string) => void = () => {};\n private _onTouched: () => void = () => {};\n\n constructor() {\n effect(() => {\n if (this.autoResize()) {\n const el = this._textareaRef()?.nativeElement;\n if (el) {\n el.style.height = 'auto';\n el.style.height = `${el.scrollHeight}px`;\n }\n }\n });\n }\n\n onInput(event: Event): void {\n const el = event.target as HTMLTextAreaElement;\n this._value.set(el.value);\n this._onChange(el.value);\n\n if (this.autoResize()) {\n el.style.height = 'auto';\n el.style.height = `${el.scrollHeight}px`;\n }\n }\n\n onFocus(): void {\n this._focused.set(true);\n }\n\n onBlur(): void {\n this._focused.set(false);\n this._onTouched();\n }\n\n writeValue(val: unknown): void {\n this._value.set(val == null ? '' : String(val));\n }\n\n registerOnChange(fn: (v: string) => void): void {\n this._onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this._onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this._isDisabled.set(isDisabled);\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-textarea.mjs","sources":["../../../../projects/ui-core/textarea/neu-textarea.component.ts","../../../../projects/ui-core/textarea/neural-ui-core-textarea.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n ViewEncapsulation,\n computed,\n effect,\n forwardRef,\n inject,\n input,\n signal,\n viewChild,\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\nlet _neuTextareaIdSeq = 0;\n\n/**\n * NeuralUI Textarea Component\n *\n * Textarea con floating label y soporte completo para Angular Forms.\n * Soporta auto-resize opcional.\n *\n * Uso:\n * <neu-textarea label=\"Descripción\" [formControl]=\"ctrl\" />\n * <neu-textarea label=\"Bio\" [rows]=\"5\" [autoResize]=\"true\" />\n */\n@Component({\n selector: 'neu-textarea',\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n class: 'neu-textarea-host',\n '[class.neu-textarea-host--sm]': 'size() === \"sm\"',\n '[class.neu-textarea-host--lg]': 'size() === \"lg\"',\n },\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => NeuTextareaComponent),\n multi: true,\n },\n ],\n template: `\n <div\n class=\"neu-textarea__wrapper\"\n [class.neu-textarea__wrapper--focused]=\"_focused()\"\n [class.neu-textarea__wrapper--has-value]=\"hasValue()\"\n [class.neu-textarea__wrapper--error]=\"hasError()\"\n [class.neu-textarea__wrapper--disabled]=\"_isDisabledState()\"\n >\n <textarea\n #textareaRef\n class=\"neu-textarea__field\"\n [id]=\"_id\"\n [rows]=\"rows()\"\n [placeholder]=\"' '\"\n [attr.disabled]=\"_isDisabledState() ? true : null\"\n [attr.readonly]=\"readonly() ? true : null\"\n [attr.required]=\"required() ? true : null\"\n [attr.maxlength]=\"maxlength() ?? null\"\n [attr.name]=\"name() || null\"\n [attr.aria-describedby]=\"hasError() ? _id + '-error' : hint() ? _id + '-hint' : null\"\n [attr.aria-invalid]=\"hasError() ? 'true' : null\"\n [style.resize]=\"_resizeStyle()\"\n [value]=\"_value()\"\n (input)=\"onInput($event)\"\n (focus)=\"onFocus()\"\n (blur)=\"onBlur()\"\n ></textarea>\n <label class=\"neu-textarea__label\" [for]=\"_id\">{{ label() }}</label>\n @if (hint() && !hasError()) {\n <span class=\"neu-textarea__hint\" [id]=\"_id + '-hint'\">{{ hint() }}</span>\n }\n @if (hasError()) {\n <span class=\"neu-textarea__error\" role=\"alert\" [id]=\"_id + '-error'\">{{\n errorMessage()\n }}</span>\n }\n </div>\n `,\n styleUrl: './neu-textarea.component.scss',\n})\nexport class NeuTextareaComponent implements ControlValueAccessor {\n readonly label = input('');\n readonly rows = input<number>(3);\n /** Tamaño del campo: 'sm' = compacto | 'md' = estándar | 'lg' = grande / Field size */\n readonly size = input<'sm' | 'md' | 'lg'>('md');\n readonly autoResize = input<boolean>(false);\n /** Permite al usuario redimensionar el campo manualmente (por defecto: true) / Allows the user to manually resize the field (default: true) */\n readonly resizable = input<boolean>(true);\n readonly errorMessage = input<string>('');\n readonly hint = input<string>('');\n readonly disabled = input<boolean>(false);\n readonly readonly = input<boolean>(false);\n readonly required = input<boolean>(false);\n readonly name = input<string>('');\n readonly maxlength = input<number | null>(null);\n\n readonly _id = `neu-textarea-${_neuTextareaIdSeq++}`;\n\n protected readonly _value = signal('');\n protected readonly _focused = signal(false);\n protected readonly _isDisabled = signal(false);\n\n readonly _isDisabledState = computed(() => this.disabled() || this._isDisabled());\n readonly hasValue = computed(() => this._value().length > 0);\n readonly hasError = computed(() => !!this.errorMessage());\n readonly _resizeStyle = computed(() => {\n if (this.autoResize()) return 'none';\n return this.resizable() ? 'vertical' : 'none';\n });\n\n private readonly _textareaRef = viewChild<ElementRef<HTMLTextAreaElement>>('textareaRef');\n\n private _onChange: (v: string) => void = () => {};\n private _onTouched: () => void = () => {};\n\n constructor() {\n effect(() => {\n if (this.autoResize()) {\n const el = this._textareaRef()?.nativeElement;\n if (el) {\n el.style.height = 'auto';\n el.style.height = `${el.scrollHeight}px`;\n }\n }\n });\n }\n\n onInput(event: Event): void {\n const el = event.target as HTMLTextAreaElement;\n this._value.set(el.value);\n this._onChange(el.value);\n\n if (this.autoResize()) {\n el.style.height = 'auto';\n el.style.height = `${el.scrollHeight}px`;\n }\n }\n\n onFocus(): void {\n this._focused.set(true);\n }\n\n onBlur(): void {\n this._focused.set(false);\n this._onTouched();\n }\n\n writeValue(val: unknown): void {\n this._value.set(val == null ? '' : String(val));\n }\n\n registerOnChange(fn: (v: string) => void): void {\n this._onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this._onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this._isDisabled.set(isDisabled);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
|
|
@@ -2,30 +2,21 @@ import * as i0 from '@angular/core';
|
|
|
2
2
|
import { input, output, computed, ChangeDetectionStrategy, ViewEncapsulation, Component } from '@angular/core';
|
|
3
3
|
|
|
4
4
|
class NeuTimelineGridComponent {
|
|
5
|
-
columns = input([], /*
|
|
6
|
-
...(ngDevMode ? [{ debugName: "
|
|
7
|
-
|
|
8
|
-
...(ngDevMode ? [{ debugName: "
|
|
9
|
-
|
|
10
|
-
...(ngDevMode ? [{ debugName: "
|
|
11
|
-
|
|
12
|
-
...(ngDevMode ? [{ debugName: "stickyLabels" }] : /* istanbul ignore next */ []));
|
|
13
|
-
minColumnWidth = input('112px', /* @ts-ignore */
|
|
14
|
-
...(ngDevMode ? [{ debugName: "minColumnWidth" }] : /* istanbul ignore next */ []));
|
|
15
|
-
selectedItemId = input(null, /* @ts-ignore */
|
|
16
|
-
...(ngDevMode ? [{ debugName: "selectedItemId" }] : /* istanbul ignore next */ []));
|
|
17
|
-
selectedSlot = input(null, /* @ts-ignore */
|
|
18
|
-
...(ngDevMode ? [{ debugName: "selectedSlot" }] : /* istanbul ignore next */ []));
|
|
5
|
+
columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
|
|
6
|
+
rows = input([], ...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
|
|
7
|
+
compact = input(false, ...(ngDevMode ? [{ debugName: "compact" }] : /* istanbul ignore next */ []));
|
|
8
|
+
stickyLabels = input(true, ...(ngDevMode ? [{ debugName: "stickyLabels" }] : /* istanbul ignore next */ []));
|
|
9
|
+
minColumnWidth = input('112px', ...(ngDevMode ? [{ debugName: "minColumnWidth" }] : /* istanbul ignore next */ []));
|
|
10
|
+
selectedItemId = input(null, ...(ngDevMode ? [{ debugName: "selectedItemId" }] : /* istanbul ignore next */ []));
|
|
11
|
+
selectedSlot = input(null, ...(ngDevMode ? [{ debugName: "selectedSlot" }] : /* istanbul ignore next */ []));
|
|
19
12
|
itemClick = output();
|
|
20
13
|
slotClick = output();
|
|
21
14
|
_columnIndexMap = computed(() => {
|
|
22
15
|
const indexMap = new Map();
|
|
23
16
|
this.columns().forEach((column, index) => indexMap.set(column.id, index + 1));
|
|
24
17
|
return indexMap;
|
|
25
|
-
}, /*
|
|
26
|
-
...(ngDevMode ? [{ debugName: "
|
|
27
|
-
gridTemplateColumns = computed(() => `repeat(${Math.max(this.columns().length, 1)}, minmax(var(--neu-timeline-grid-min-column-width), 1fr))`, /* @ts-ignore */
|
|
28
|
-
...(ngDevMode ? [{ debugName: "gridTemplateColumns" }] : /* istanbul ignore next */ []));
|
|
18
|
+
}, ...(ngDevMode ? [{ debugName: "_columnIndexMap" }] : /* istanbul ignore next */ []));
|
|
19
|
+
gridTemplateColumns = computed(() => `repeat(${Math.max(this.columns().length, 1)}, minmax(var(--neu-timeline-grid-min-column-width), 1fr))`, ...(ngDevMode ? [{ debugName: "gridTemplateColumns" }] : /* istanbul ignore next */ []));
|
|
29
20
|
validItems(row) {
|
|
30
21
|
const indexMap = this._columnIndexMap();
|
|
31
22
|
return row.items.filter((item) => indexMap.has(item.start));
|
|
@@ -62,8 +53,8 @@ class NeuTimelineGridComponent {
|
|
|
62
53
|
onSlotClick(rowId, columnId) {
|
|
63
54
|
this.slotClick.emit({ rowId, columnId });
|
|
64
55
|
}
|
|
65
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
66
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
56
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuTimelineGridComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
57
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: NeuTimelineGridComponent, isStandalone: true, selector: "neu-timeline-grid", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, stickyLabels: { classPropertyName: "stickyLabels", publicName: "stickyLabels", isSignal: true, isRequired: false, transformFunction: null }, minColumnWidth: { classPropertyName: "minColumnWidth", publicName: "minColumnWidth", isSignal: true, isRequired: false, transformFunction: null }, selectedItemId: { classPropertyName: "selectedItemId", publicName: "selectedItemId", isSignal: true, isRequired: false, transformFunction: null }, selectedSlot: { classPropertyName: "selectedSlot", publicName: "selectedSlot", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { itemClick: "itemClick", slotClick: "slotClick" }, host: { properties: { "class.neu-timeline-grid--compact": "compact()", "class.neu-timeline-grid--sticky-labels": "stickyLabels()", "style.--neu-timeline-grid-min-column-width": "minColumnWidth()" } }, ngImport: i0, template: `
|
|
67
58
|
<div class="neu-timeline-grid">
|
|
68
59
|
<div class="neu-timeline-grid__header">
|
|
69
60
|
<div class="neu-timeline-grid__corner" aria-hidden="true"></div>
|
|
@@ -136,7 +127,7 @@ class NeuTimelineGridComponent {
|
|
|
136
127
|
</div>
|
|
137
128
|
`, isInline: true, styles: ["neu-timeline-grid{min-width:0}.neu-timeline-grid{display:grid;gap:var(--neu-space-4);width:100%;overflow-x:auto;color:var(--neu-text)}.neu-timeline-grid--compact .neu-timeline-grid__track,.neu-timeline-grid--compact .neu-timeline-grid__slot{min-height:60px}.neu-timeline-grid--compact .neu-timeline-grid__item{margin:8px 0;padding:8px 10px}.neu-timeline-grid--sticky-labels .neu-timeline-grid__row-label,.neu-timeline-grid--sticky-labels .neu-timeline-grid__corner{position:sticky;left:0;z-index:2;background:var(--neu-surface)}.neu-timeline-grid__header,.neu-timeline-grid__row{display:grid;grid-template-columns:minmax(180px,220px) minmax(0,1fr);gap:var(--neu-space-4);min-width:max-content}.neu-timeline-grid__corner,.neu-timeline-grid__row-label{padding:var(--neu-space-3) 0}.neu-timeline-grid__header-track,.neu-timeline-grid__track{display:grid;position:relative;gap:var(--neu-space-3)}.neu-timeline-grid__column{display:flex;flex-direction:column;gap:2px;min-width:0;padding:0 var(--neu-space-2)}.neu-timeline-grid__column-label{font-size:var(--neu-text-sm);font-weight:700}.neu-timeline-grid__column-desc,.neu-timeline-grid__row-label span,.neu-timeline-grid__item-subtitle,.neu-timeline-grid__item-meta{font-size:var(--neu-text-xs);color:var(--neu-text-muted)}.neu-timeline-grid__body{display:grid;gap:var(--neu-space-3)}.neu-timeline-grid__row-label{display:flex;flex-direction:column;gap:4px}.neu-timeline-grid__row-label strong{font-size:var(--neu-text-sm)}.neu-timeline-grid__track{align-items:stretch;min-height:76px}.neu-timeline-grid__slot,.neu-timeline-grid__item{grid-row:1}.neu-timeline-grid__slot{min-height:76px;border-radius:0;border:0;background:linear-gradient(180deg,color-mix(in srgb,var(--neu-surface-2) 18%,transparent),color-mix(in srgb,var(--neu-surface) 96%,transparent));box-shadow:inset 1px 0 color-mix(in srgb,var(--neu-border) 16%,transparent),inset 0 1px #ffffff04}.neu-timeline-grid__slot-button{appearance:none;display:block;width:100%;min-width:100%;justify-self:stretch;align-self:stretch;box-sizing:border-box;padding:0;cursor:pointer}.neu-timeline-grid__slot-button:hover{background:linear-gradient(180deg,color-mix(in srgb,var(--neu-primary) 7%,var(--neu-surface-2)),color-mix(in srgb,var(--neu-primary) 4%,var(--neu-surface)));box-shadow:inset 1px 0 color-mix(in srgb,var(--neu-primary) 22%,transparent),inset 0 1px #ffffff08}.neu-timeline-grid__slot--selected{border-radius:var(--neu-radius-md);background:color-mix(in srgb,var(--neu-primary) 10%,var(--neu-surface-2));box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--neu-primary) 42%,var(--neu-border)),inset 0 1px #ffffff08}.neu-timeline-grid__item{display:flex;flex-direction:column;align-items:flex-start;justify-content:center;gap:4px;min-width:0;margin:10px 0;padding:10px 12px;border:1px solid transparent;border-radius:var(--neu-radius-lg);text-align:left;background:var(--neu-surface);box-shadow:var(--neu-shadow-sm);color:var(--neu-text)}.neu-timeline-grid__item-title{font-size:var(--neu-text-sm);font-weight:700}.neu-timeline-grid__item--selected{outline:2px solid color-mix(in srgb,var(--neu-primary) 48%,transparent);outline-offset:1px}.neu-timeline-grid__item--default{border-color:var(--neu-border)}.neu-timeline-grid__item--info{border-color:color-mix(in srgb,var(--neu-primary) 36%,var(--neu-border));background:color-mix(in srgb,var(--neu-primary) 8%,var(--neu-surface))}.neu-timeline-grid__item--success{border-color:color-mix(in srgb,var(--neu-success) 36%,var(--neu-border));background:color-mix(in srgb,var(--neu-success) 9%,var(--neu-surface))}.neu-timeline-grid__item--warning{border-color:color-mix(in srgb,var(--neu-warning) 40%,var(--neu-border));background:color-mix(in srgb,var(--neu-warning) 11%,var(--neu-surface))}.neu-timeline-grid__item--danger{border-color:color-mix(in srgb,var(--neu-error) 38%,var(--neu-border));background:color-mix(in srgb,var(--neu-error) 10%,var(--neu-surface))}@media(max-width:720px){.neu-timeline-grid__header,.neu-timeline-grid__row{grid-template-columns:minmax(140px,180px) minmax(0,1fr);gap:var(--neu-space-3)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
138
129
|
}
|
|
139
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
130
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuTimelineGridComponent, decorators: [{
|
|
140
131
|
type: Component,
|
|
141
132
|
args: [{ selector: 'neu-timeline-grid', imports: [], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
142
133
|
'[class.neu-timeline-grid--compact]': 'compact()',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neural-ui-core-timeline-grid.mjs","sources":["../../../../projects/ui-core/timeline-grid/neu-timeline-grid.component.ts","../../../../projects/ui-core/timeline-grid/neural-ui-core-timeline-grid.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n input,\n output,\n ViewEncapsulation,\n} from '@angular/core';\n\nexport type NeuTimelineGridItemVariant = 'default' | 'success' | 'warning' | 'danger' | 'info';\n\nexport interface NeuTimelineGridColumn {\n id: string;\n label: string;\n description?: string;\n}\n\nexport interface NeuTimelineGridItem {\n id: string;\n title: string;\n start: string;\n span?: number;\n subtitle?: string;\n meta?: string;\n variant?: NeuTimelineGridItemVariant;\n}\n\nexport interface NeuTimelineGridRow {\n id: string;\n label: string;\n description?: string;\n items: NeuTimelineGridItem[];\n}\n\nexport interface NeuTimelineGridSlotSelection {\n rowId: string;\n columnId: string;\n}\n\n@Component({\n selector: 'neu-timeline-grid',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class.neu-timeline-grid--compact]': 'compact()',\n '[class.neu-timeline-grid--sticky-labels]': 'stickyLabels()',\n '[style.--neu-timeline-grid-min-column-width]': 'minColumnWidth()',\n },\n template: `\n <div class=\"neu-timeline-grid\">\n <div class=\"neu-timeline-grid__header\">\n <div class=\"neu-timeline-grid__corner\" aria-hidden=\"true\"></div>\n <div\n class=\"neu-timeline-grid__header-track\"\n [style.gridTemplateColumns]=\"gridTemplateColumns()\"\n >\n @for (column of columns(); track column.id) {\n <div class=\"neu-timeline-grid__column\">\n <span class=\"neu-timeline-grid__column-label\">{{ column.label }}</span>\n @if (column.description) {\n <span class=\"neu-timeline-grid__column-desc\">{{ column.description }}</span>\n }\n </div>\n }\n </div>\n </div>\n\n <div class=\"neu-timeline-grid__body\">\n @for (row of rows(); track row.id) {\n <section class=\"neu-timeline-grid__row\" [attr.aria-label]=\"row.label\">\n <div class=\"neu-timeline-grid__row-label\">\n <strong>{{ row.label }}</strong>\n @if (row.description) {\n <span>{{ row.description }}</span>\n }\n </div>\n\n <div\n class=\"neu-timeline-grid__track\"\n [style.gridTemplateColumns]=\"gridTemplateColumns()\"\n >\n @for (column of columns(); track column.id) {\n <button\n type=\"button\"\n class=\"neu-timeline-grid__slot neu-timeline-grid__slot-button\"\n [class.neu-timeline-grid__slot--selected]=\"isSlotSelected(row.id, column.id)\"\n [style.gridColumn]=\"slotGridColumn(column.id)\"\n [attr.aria-label]=\"slotAriaLabel(row, column)\"\n [attr.aria-pressed]=\"isSlotSelected(row.id, column.id)\"\n [attr.data-slot-key]=\"slotKey(row.id, column.id)\"\n (click)=\"onSlotClick(row.id, column.id)\"\n ></button>\n }\n\n @for (item of validItems(row); track item.id) {\n <button\n type=\"button\"\n class=\"neu-timeline-grid__item\"\n [class]=\"itemClass(item)\"\n [style.gridColumn]=\"itemGridColumn(item)\"\n [attr.aria-label]=\"itemAriaLabel(row, item)\"\n [attr.aria-pressed]=\"isItemSelected(item.id)\"\n [attr.data-item-id]=\"item.id\"\n (click)=\"itemClick.emit(item)\"\n >\n <span class=\"neu-timeline-grid__item-title\">{{ item.title }}</span>\n @if (item.subtitle) {\n <span class=\"neu-timeline-grid__item-subtitle\">{{ item.subtitle }}</span>\n }\n @if (item.meta) {\n <span class=\"neu-timeline-grid__item-meta\">{{ item.meta }}</span>\n }\n </button>\n }\n </div>\n </section>\n }\n </div>\n </div>\n `,\n styleUrl: './neu-timeline-grid.component.scss',\n})\nexport class NeuTimelineGridComponent {\n readonly columns = input<NeuTimelineGridColumn[]>([]);\n readonly rows = input<NeuTimelineGridRow[]>([]);\n readonly compact = input<boolean>(false);\n readonly stickyLabels = input<boolean>(true);\n readonly minColumnWidth = input<string>('112px');\n readonly selectedItemId = input<string | null>(null);\n readonly selectedSlot = input<NeuTimelineGridSlotSelection | null>(null);\n\n readonly itemClick = output<NeuTimelineGridItem>();\n readonly slotClick = output<NeuTimelineGridSlotSelection>();\n\n readonly _columnIndexMap = computed(() => {\n const indexMap = new Map<string, number>();\n this.columns().forEach((column, index) => indexMap.set(column.id, index + 1));\n return indexMap;\n });\n\n readonly gridTemplateColumns = computed(\n () =>\n `repeat(${Math.max(this.columns().length, 1)}, minmax(var(--neu-timeline-grid-min-column-width), 1fr))`,\n );\n\n validItems(row: NeuTimelineGridRow): NeuTimelineGridItem[] {\n const indexMap = this._columnIndexMap();\n return row.items.filter((item) => indexMap.has(item.start));\n }\n\n itemGridColumn(item: NeuTimelineGridItem): string {\n const start = this._columnIndexMap().get(item.start) ?? 1;\n const span = Math.max(1, item.span ?? 1);\n return `${start} / span ${span}`;\n }\n\n slotGridColumn(columnId: string): string {\n const start = this._columnIndexMap().get(columnId) ?? 1;\n return `${start} / span 1`;\n }\n\n itemClass(item: NeuTimelineGridItem): string {\n const selectedClass = this.isItemSelected(item.id) ? ' neu-timeline-grid__item--selected' : '';\n return `neu-timeline-grid__item neu-timeline-grid__item--${item.variant ?? 'default'}${selectedClass}`;\n }\n\n itemAriaLabel(row: NeuTimelineGridRow, item: NeuTimelineGridItem): string {\n return `${row.label}: ${item.title}`;\n }\n\n slotAriaLabel(row: NeuTimelineGridRow, column: NeuTimelineGridColumn): string {\n return `${row.label}: ${column.label}`;\n }\n\n slotKey(rowId: string, columnId: string): string {\n return `${rowId}:${columnId}`;\n }\n\n isItemSelected(itemId: string): boolean {\n return this.selectedItemId() === itemId;\n }\n\n isSlotSelected(rowId: string, columnId: string): boolean {\n const selectedSlot = this.selectedSlot();\n return selectedSlot?.rowId === rowId && selectedSlot?.columnId === columnId;\n }\n\n onSlotClick(rowId: string, columnId: string): void {\n this.slotClick.emit({ rowId, columnId });\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-timeline-grid.mjs","sources":["../../../../projects/ui-core/timeline-grid/neu-timeline-grid.component.ts","../../../../projects/ui-core/timeline-grid/neural-ui-core-timeline-grid.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n computed,\n input,\n output,\n ViewEncapsulation,\n} from '@angular/core';\n\nexport type NeuTimelineGridItemVariant = 'default' | 'success' | 'warning' | 'danger' | 'info';\n\nexport interface NeuTimelineGridColumn {\n id: string;\n label: string;\n description?: string;\n}\n\nexport interface NeuTimelineGridItem {\n id: string;\n title: string;\n start: string;\n span?: number;\n subtitle?: string;\n meta?: string;\n variant?: NeuTimelineGridItemVariant;\n}\n\nexport interface NeuTimelineGridRow {\n id: string;\n label: string;\n description?: string;\n items: NeuTimelineGridItem[];\n}\n\nexport interface NeuTimelineGridSlotSelection {\n rowId: string;\n columnId: string;\n}\n\n@Component({\n selector: 'neu-timeline-grid',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class.neu-timeline-grid--compact]': 'compact()',\n '[class.neu-timeline-grid--sticky-labels]': 'stickyLabels()',\n '[style.--neu-timeline-grid-min-column-width]': 'minColumnWidth()',\n },\n template: `\n <div class=\"neu-timeline-grid\">\n <div class=\"neu-timeline-grid__header\">\n <div class=\"neu-timeline-grid__corner\" aria-hidden=\"true\"></div>\n <div\n class=\"neu-timeline-grid__header-track\"\n [style.gridTemplateColumns]=\"gridTemplateColumns()\"\n >\n @for (column of columns(); track column.id) {\n <div class=\"neu-timeline-grid__column\">\n <span class=\"neu-timeline-grid__column-label\">{{ column.label }}</span>\n @if (column.description) {\n <span class=\"neu-timeline-grid__column-desc\">{{ column.description }}</span>\n }\n </div>\n }\n </div>\n </div>\n\n <div class=\"neu-timeline-grid__body\">\n @for (row of rows(); track row.id) {\n <section class=\"neu-timeline-grid__row\" [attr.aria-label]=\"row.label\">\n <div class=\"neu-timeline-grid__row-label\">\n <strong>{{ row.label }}</strong>\n @if (row.description) {\n <span>{{ row.description }}</span>\n }\n </div>\n\n <div\n class=\"neu-timeline-grid__track\"\n [style.gridTemplateColumns]=\"gridTemplateColumns()\"\n >\n @for (column of columns(); track column.id) {\n <button\n type=\"button\"\n class=\"neu-timeline-grid__slot neu-timeline-grid__slot-button\"\n [class.neu-timeline-grid__slot--selected]=\"isSlotSelected(row.id, column.id)\"\n [style.gridColumn]=\"slotGridColumn(column.id)\"\n [attr.aria-label]=\"slotAriaLabel(row, column)\"\n [attr.aria-pressed]=\"isSlotSelected(row.id, column.id)\"\n [attr.data-slot-key]=\"slotKey(row.id, column.id)\"\n (click)=\"onSlotClick(row.id, column.id)\"\n ></button>\n }\n\n @for (item of validItems(row); track item.id) {\n <button\n type=\"button\"\n class=\"neu-timeline-grid__item\"\n [class]=\"itemClass(item)\"\n [style.gridColumn]=\"itemGridColumn(item)\"\n [attr.aria-label]=\"itemAriaLabel(row, item)\"\n [attr.aria-pressed]=\"isItemSelected(item.id)\"\n [attr.data-item-id]=\"item.id\"\n (click)=\"itemClick.emit(item)\"\n >\n <span class=\"neu-timeline-grid__item-title\">{{ item.title }}</span>\n @if (item.subtitle) {\n <span class=\"neu-timeline-grid__item-subtitle\">{{ item.subtitle }}</span>\n }\n @if (item.meta) {\n <span class=\"neu-timeline-grid__item-meta\">{{ item.meta }}</span>\n }\n </button>\n }\n </div>\n </section>\n }\n </div>\n </div>\n `,\n styleUrl: './neu-timeline-grid.component.scss',\n})\nexport class NeuTimelineGridComponent {\n readonly columns = input<NeuTimelineGridColumn[]>([]);\n readonly rows = input<NeuTimelineGridRow[]>([]);\n readonly compact = input<boolean>(false);\n readonly stickyLabels = input<boolean>(true);\n readonly minColumnWidth = input<string>('112px');\n readonly selectedItemId = input<string | null>(null);\n readonly selectedSlot = input<NeuTimelineGridSlotSelection | null>(null);\n\n readonly itemClick = output<NeuTimelineGridItem>();\n readonly slotClick = output<NeuTimelineGridSlotSelection>();\n\n readonly _columnIndexMap = computed(() => {\n const indexMap = new Map<string, number>();\n this.columns().forEach((column, index) => indexMap.set(column.id, index + 1));\n return indexMap;\n });\n\n readonly gridTemplateColumns = computed(\n () =>\n `repeat(${Math.max(this.columns().length, 1)}, minmax(var(--neu-timeline-grid-min-column-width), 1fr))`,\n );\n\n validItems(row: NeuTimelineGridRow): NeuTimelineGridItem[] {\n const indexMap = this._columnIndexMap();\n return row.items.filter((item) => indexMap.has(item.start));\n }\n\n itemGridColumn(item: NeuTimelineGridItem): string {\n const start = this._columnIndexMap().get(item.start) ?? 1;\n const span = Math.max(1, item.span ?? 1);\n return `${start} / span ${span}`;\n }\n\n slotGridColumn(columnId: string): string {\n const start = this._columnIndexMap().get(columnId) ?? 1;\n return `${start} / span 1`;\n }\n\n itemClass(item: NeuTimelineGridItem): string {\n const selectedClass = this.isItemSelected(item.id) ? ' neu-timeline-grid__item--selected' : '';\n return `neu-timeline-grid__item neu-timeline-grid__item--${item.variant ?? 'default'}${selectedClass}`;\n }\n\n itemAriaLabel(row: NeuTimelineGridRow, item: NeuTimelineGridItem): string {\n return `${row.label}: ${item.title}`;\n }\n\n slotAriaLabel(row: NeuTimelineGridRow, column: NeuTimelineGridColumn): string {\n return `${row.label}: ${column.label}`;\n }\n\n slotKey(rowId: string, columnId: string): string {\n return `${rowId}:${columnId}`;\n }\n\n isItemSelected(itemId: string): boolean {\n return this.selectedItemId() === itemId;\n }\n\n isSlotSelected(rowId: string, columnId: string): boolean {\n const selectedSlot = this.selectedSlot();\n return selectedSlot?.rowId === rowId && selectedSlot?.columnId === columnId;\n }\n\n onSlotClick(rowId: string, columnId: string): void {\n this.slotClick.emit({ rowId, columnId });\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
|
|
@@ -12,10 +12,9 @@ import { input, ChangeDetectionStrategy, ViewEncapsulation, Component } from '@a
|
|
|
12
12
|
*/
|
|
13
13
|
class NeuTimelineComponent {
|
|
14
14
|
/** Eventos a mostrar / Events to display */
|
|
15
|
-
items = input([], /*
|
|
16
|
-
|
|
17
|
-
static
|
|
18
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: NeuTimelineComponent, isStandalone: true, selector: "neu-timeline", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
15
|
+
items = input([], ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
16
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuTimelineComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
17
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: NeuTimelineComponent, isStandalone: true, selector: "neu-timeline", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
19
18
|
<ol class="neu-timeline">
|
|
20
19
|
@for (item of items(); track item.title; let last = $last) {
|
|
21
20
|
<li class="neu-timeline__item" [class.neu-timeline__item--last]="last">
|
|
@@ -61,7 +60,7 @@ class NeuTimelineComponent {
|
|
|
61
60
|
</ol>
|
|
62
61
|
`, isInline: true, styles: [".neu-timeline{list-style:none;margin:0;padding:0;font-family:var(--neu-font-sans)}.neu-timeline__item{display:flex;gap:var(--neu-space-4);min-height:56px}.neu-timeline__axis{display:flex;flex-direction:column;align-items:center;flex-shrink:0;width:24px}.neu-timeline__dot{width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;border:2.5px solid;background:var(--neu-surface)}.neu-timeline__dot--default{border-color:var(--neu-border);color:var(--neu-text-disabled);background:var(--neu-surface-2)}.neu-timeline__dot--success{border-color:var(--neu-success);color:var(--neu-success)}.neu-timeline__dot--warning{border-color:var(--neu-warning);color:var(--neu-warning)}.neu-timeline__dot--danger{border-color:var(--neu-error);color:var(--neu-error)}.neu-timeline__dot--info{border-color:var(--neu-primary);color:var(--neu-primary)}.neu-timeline__dot-icon{width:12px;height:12px}.neu-timeline__line{width:2px;flex:1;background:var(--neu-border);margin:4px 0;min-height:16px}.neu-timeline__content{flex:1;padding-bottom:var(--neu-space-5);padding-top:2px}.neu-timeline__header{display:flex;align-items:baseline;justify-content:space-between;gap:var(--neu-space-3);margin-bottom:4px}.neu-timeline__title{font-size:var(--neu-text-sm);font-weight:600;color:var(--neu-text)}.neu-timeline__time{font-size:var(--neu-text-xs);color:var(--neu-text-disabled);white-space:nowrap;flex-shrink:0}.neu-timeline__desc{font-size:var(--neu-text-sm);color:var(--neu-text-muted);line-height:1.6;margin:0}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
63
62
|
}
|
|
64
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
63
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: NeuTimelineComponent, decorators: [{
|
|
65
64
|
type: Component,
|
|
66
65
|
args: [{ selector: 'neu-timeline', imports: [], encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
67
66
|
<ol class="neu-timeline">
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neural-ui-core-timeline.mjs","sources":["../../../../projects/ui-core/timeline/neu-timeline.component.ts","../../../../projects/ui-core/timeline/neural-ui-core-timeline.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, ViewEncapsulation, input } from '@angular/core';\n\nexport type NeuTimelineItemVariant = 'default' | 'success' | 'warning' | 'danger' | 'info';\n\nexport interface NeuTimelineItem {\n /** Etiqueta de tiempo (ej. \"Hace 2h\", \"12 Mar\") / Time label (e.g. \"2h ago\", \"Mar 12\") */\n time?: string;\n /** Título del evento / Event title */\n title: string;\n /** Descripción opcional / Optional description */\n description?: string;\n /** Variante de color del punto / Dot color variant */\n variant?: NeuTimelineItemVariant;\n /** Icono SVG path opcional / Optional SVG path icon */\n icon?: string;\n}\n\n/**\n * NeuralUI Timeline Component\n *\n * Lista vertical de eventos cronológicos con línea conectora. / Vertical list of chronological events with a connector line.\n *\n * Uso:\n * <neu-timeline [items]=\"events\" />\n * <neu-timeline [items]=\"events\" align=\"right\" />\n */\n@Component({\n selector: 'neu-timeline',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <ol class=\"neu-timeline\">\n @for (item of items(); track item.title; let last = $last) {\n <li class=\"neu-timeline__item\" [class.neu-timeline__item--last]=\"last\">\n <!-- Eje izquierdo (punto + línea) -->\n <div class=\"neu-timeline__axis\">\n <div\n class=\"neu-timeline__dot\"\n [class]=\"'neu-timeline__dot--' + (item.variant ?? 'default')\"\n >\n @if (item.icon) {\n <svg\n class=\"neu-timeline__dot-icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n aria-hidden=\"true\"\n >\n <path [attr.d]=\"item.icon\" />\n </svg>\n }\n </div>\n @if (!last) {\n <div class=\"neu-timeline__line\"></div>\n }\n </div>\n\n <!-- Contenido -->\n <div class=\"neu-timeline__content\">\n <div class=\"neu-timeline__header\">\n <span class=\"neu-timeline__title\">{{ item.title }}</span>\n @if (item.time) {\n <span class=\"neu-timeline__time\">{{ item.time }}</span>\n }\n </div>\n @if (item.description) {\n <p class=\"neu-timeline__desc\">{{ item.description }}</p>\n }\n </div>\n </li>\n }\n </ol>\n `,\n styleUrl: './neu-timeline.component.scss',\n})\nexport class NeuTimelineComponent {\n /** Eventos a mostrar / Events to display */\n items = input<NeuTimelineItem[]>([]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":";;;AAiBA;;;;;;;;AAQG;MAqDU,oBAAoB,CAAA;;
|
|
1
|
+
{"version":3,"file":"neural-ui-core-timeline.mjs","sources":["../../../../projects/ui-core/timeline/neu-timeline.component.ts","../../../../projects/ui-core/timeline/neural-ui-core-timeline.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, ViewEncapsulation, input } from '@angular/core';\n\nexport type NeuTimelineItemVariant = 'default' | 'success' | 'warning' | 'danger' | 'info';\n\nexport interface NeuTimelineItem {\n /** Etiqueta de tiempo (ej. \"Hace 2h\", \"12 Mar\") / Time label (e.g. \"2h ago\", \"Mar 12\") */\n time?: string;\n /** Título del evento / Event title */\n title: string;\n /** Descripción opcional / Optional description */\n description?: string;\n /** Variante de color del punto / Dot color variant */\n variant?: NeuTimelineItemVariant;\n /** Icono SVG path opcional / Optional SVG path icon */\n icon?: string;\n}\n\n/**\n * NeuralUI Timeline Component\n *\n * Lista vertical de eventos cronológicos con línea conectora. / Vertical list of chronological events with a connector line.\n *\n * Uso:\n * <neu-timeline [items]=\"events\" />\n * <neu-timeline [items]=\"events\" align=\"right\" />\n */\n@Component({\n selector: 'neu-timeline',\n imports: [],\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <ol class=\"neu-timeline\">\n @for (item of items(); track item.title; let last = $last) {\n <li class=\"neu-timeline__item\" [class.neu-timeline__item--last]=\"last\">\n <!-- Eje izquierdo (punto + línea) -->\n <div class=\"neu-timeline__axis\">\n <div\n class=\"neu-timeline__dot\"\n [class]=\"'neu-timeline__dot--' + (item.variant ?? 'default')\"\n >\n @if (item.icon) {\n <svg\n class=\"neu-timeline__dot-icon\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n aria-hidden=\"true\"\n >\n <path [attr.d]=\"item.icon\" />\n </svg>\n }\n </div>\n @if (!last) {\n <div class=\"neu-timeline__line\"></div>\n }\n </div>\n\n <!-- Contenido -->\n <div class=\"neu-timeline__content\">\n <div class=\"neu-timeline__header\">\n <span class=\"neu-timeline__title\">{{ item.title }}</span>\n @if (item.time) {\n <span class=\"neu-timeline__time\">{{ item.time }}</span>\n }\n </div>\n @if (item.description) {\n <p class=\"neu-timeline__desc\">{{ item.description }}</p>\n }\n </div>\n </li>\n }\n </ol>\n `,\n styleUrl: './neu-timeline.component.scss',\n})\nexport class NeuTimelineComponent {\n /** Eventos a mostrar / Events to display */\n items = input<NeuTimelineItem[]>([]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":";;;AAiBA;;;;;;;;AAQG;MAqDU,oBAAoB,CAAA;;AAE/B,IAAA,KAAK,GAAG,KAAK,CAAoB,EAAE,4EAAC;wGAFzB,oBAAoB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAApB,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,oBAAoB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,cAAA,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,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA/CrB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,qgDAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;4FAGU,oBAAoB,EAAA,UAAA,EAAA,CAAA;kBApDhC,SAAS;+BACE,cAAc,EAAA,OAAA,EACf,EAAE,EAAA,aAAA,EACI,iBAAiB,CAAC,IAAI,EAAA,eAAA,EACpB,uBAAuB,CAAC,MAAM,EAAA,QAAA,EACrC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,qgDAAA,CAAA,EAAA;;;AC3EH;;AAEG;;;;"}
|