sapenlinea-components 0.0.9 → 0.0.10

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.
@@ -1,16 +1,439 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Component, EventEmitter, signal, computed, Output, Input, input, output, HostListener } from '@angular/core';
2
+ import { input, output, signal, computed, forwardRef, Component, EventEmitter, Output, Input, HostListener } from '@angular/core';
3
+ import { NG_VALUE_ACCESSOR } from '@angular/forms';
3
4
  import * as i1 from '@angular/common';
4
5
  import { CommonModule } from '@angular/common';
5
6
 
6
- class MyComponent {
7
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: MyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.13", type: MyComponent, isStandalone: true, selector: "lib-my-component", ngImport: i0, template: "<p>my-component works!</p>\r\n", styles: [""] });
7
+ class DateTimeFilter {
8
+ elementRef;
9
+ ngZone;
10
+ mode = input('date', ...(ngDevMode ? [{ debugName: "mode" }] : []));
11
+ placeholder = input('Seleccionar fecha', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
12
+ minDate = input(null, ...(ngDevMode ? [{ debugName: "minDate" }] : []));
13
+ maxDate = input(null, ...(ngDevMode ? [{ debugName: "maxDate" }] : []));
14
+ filter = input.required(...(ngDevMode ? [{ debugName: "filter" }] : []));
15
+ dateSelected = output();
16
+ filters = [
17
+ { label: 'Fecha inicio', value: 'inicio', type: 'date' },
18
+ { label: 'Fecha fin', value: 'fin', type: 'date' },
19
+ { label: 'Fecha Nacimiento', value: 'born', type: 'date' },
20
+ ];
21
+ dateChange = output();
22
+ isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
23
+ selectedDate = signal(null, ...(ngDevMode ? [{ debugName: "selectedDate" }] : []));
24
+ isDisabled = signal(false, ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
25
+ isTouched = signal(false, ...(ngDevMode ? [{ debugName: "isTouched" }] : []));
26
+ // Navegación del calendario
27
+ currentMonth = signal(new Date().getMonth(), ...(ngDevMode ? [{ debugName: "currentMonth" }] : []));
28
+ currentYear = signal(new Date().getFullYear(), ...(ngDevMode ? [{ debugName: "currentYear" }] : []));
29
+ // Hora en formato 24h (para el backend)
30
+ selectedHour = signal(0, ...(ngDevMode ? [{ debugName: "selectedHour" }] : []));
31
+ selectedMinute = signal(0, ...(ngDevMode ? [{ debugName: "selectedMinute" }] : []));
32
+ // Estado AM/PM
33
+ selectedAmPm = signal('AM', ...(ngDevMode ? [{ debugName: "selectedAmPm" }] : []));
34
+ documentClickListener;
35
+ showFilters = false;
36
+ showDatePicker = false;
37
+ activeFilterType = null;
38
+ selectDate(date) {
39
+ this.dateSelected.emit({
40
+ filter: this.filter(),
41
+ value: date
42
+ });
43
+ }
44
+ getDatePickerMode(type) {
45
+ switch (type) {
46
+ case 'date':
47
+ return 'date';
48
+ case 'datetime':
49
+ return 'datetime';
50
+ default:
51
+ return 'date';
52
+ }
53
+ }
54
+ displayValue = computed(() => {
55
+ const date = this.selectedDate();
56
+ if (!date)
57
+ return '';
58
+ const options = {
59
+ day: '2-digit',
60
+ month: '2-digit',
61
+ year: 'numeric',
62
+ };
63
+ if (this.mode() === 'datetime') {
64
+ options.hour = '2-digit';
65
+ options.minute = '2-digit';
66
+ options.hour12 = true; // Cambiado a formato 12 horas
67
+ }
68
+ return date.toLocaleDateString('es-ES', options);
69
+ }, ...(ngDevMode ? [{ debugName: "displayValue" }] : []));
70
+ monthName = computed(() => {
71
+ const months = [
72
+ 'Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio',
73
+ 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'
74
+ ];
75
+ return months[this.currentMonth()];
76
+ }, ...(ngDevMode ? [{ debugName: "monthName" }] : []));
77
+ calendarDays = computed(() => {
78
+ const year = this.currentYear();
79
+ const month = this.currentMonth();
80
+ const firstDay = new Date(year, month, 1);
81
+ const lastDay = new Date(year, month + 1, 0);
82
+ const daysInMonth = lastDay.getDate();
83
+ const startingDayOfWeek = firstDay.getDay();
84
+ const days = [];
85
+ // Días vacíos al inicio
86
+ for (let i = 0; i < startingDayOfWeek; i++) {
87
+ days.push(null);
88
+ }
89
+ // Días del mes
90
+ for (let day = 1; day <= daysInMonth; day++) {
91
+ days.push(day);
92
+ }
93
+ return days;
94
+ }, ...(ngDevMode ? [{ debugName: "calendarDays" }] : []));
95
+ // Horas en formato 12h
96
+ hours12 = computed(() => {
97
+ return Array.from({ length: 12 }, (_, i) => {
98
+ const hour12 = i === 0 ? 12 : i;
99
+ return {
100
+ value: hour12,
101
+ display: hour12.toString().padStart(2, '0')
102
+ };
103
+ });
104
+ }, ...(ngDevMode ? [{ debugName: "hours12" }] : []));
105
+ // Hora seleccionada en formato 12h
106
+ selectedHour12 = computed(() => {
107
+ const hour24 = this.selectedHour();
108
+ if (hour24 === 0)
109
+ return 12;
110
+ if (hour24 > 12)
111
+ return hour24 - 12;
112
+ return hour24;
113
+ }, ...(ngDevMode ? [{ debugName: "selectedHour12" }] : []));
114
+ minutes = computed(() => Array.from({ length: 60 }, (_, i) => i), ...(ngDevMode ? [{ debugName: "minutes" }] : []));
115
+ onChange = () => { };
116
+ onTouched = () => { };
117
+ constructor(elementRef, ngZone) {
118
+ this.elementRef = elementRef;
119
+ this.ngZone = ngZone;
120
+ }
121
+ ngOnDestroy() {
122
+ this.removeDocumentListener();
123
+ }
124
+ writeValue(value) {
125
+ let date = null;
126
+ if (value instanceof Date) {
127
+ date = value;
128
+ }
129
+ else if (typeof value === 'string' && value) {
130
+ // Manejar tanto fechas ISO como otros formatos de string
131
+ const parsedDate = new Date(value);
132
+ if (!isNaN(parsedDate.getTime())) {
133
+ date = parsedDate;
134
+ }
135
+ }
136
+ if (date) {
137
+ this.selectedDate.set(date);
138
+ this.currentMonth.set(date.getMonth());
139
+ this.currentYear.set(date.getFullYear());
140
+ this.selectedHour.set(date.getHours());
141
+ this.selectedMinute.set(date.getMinutes());
142
+ this.selectedAmPm.set(date.getHours() >= 12 ? 'PM' : 'AM');
143
+ }
144
+ else {
145
+ this.selectedDate.set(null);
146
+ // Valores por defecto
147
+ this.selectedHour.set(0);
148
+ this.selectedMinute.set(0);
149
+ this.selectedAmPm.set('AM');
150
+ }
151
+ }
152
+ registerOnChange(fn) {
153
+ this.onChange = fn;
154
+ }
155
+ registerOnTouched(fn) {
156
+ this.onTouched = fn;
157
+ }
158
+ setDisabledState(isDisabled) {
159
+ this.isDisabled.set(isDisabled);
160
+ }
161
+ toggle() {
162
+ if (this.isDisabled())
163
+ return;
164
+ this.markAsTouched();
165
+ if (this.isOpen()) {
166
+ this.close();
167
+ }
168
+ else {
169
+ this.open();
170
+ }
171
+ }
172
+ open() {
173
+ if (this.isDisabled())
174
+ return;
175
+ this.markAsTouched();
176
+ this.isOpen.set(true);
177
+ this.addDocumentListener();
178
+ // Si hay fecha seleccionada, navegar a ese mes/año
179
+ const selected = this.selectedDate();
180
+ if (selected) {
181
+ this.currentMonth.set(selected.getMonth());
182
+ this.currentYear.set(selected.getFullYear());
183
+ }
184
+ }
185
+ close() {
186
+ this.isOpen.set(false);
187
+ this.removeDocumentListener();
188
+ this.markAsTouched();
189
+ }
190
+ selectDay(day) {
191
+ if (!day || this.isDisabled())
192
+ return;
193
+ const newDate = new Date(this.currentYear(), this.currentMonth(), day, this.selectedHour(), this.selectedMinute());
194
+ if (this.isDateDisabled(newDate))
195
+ return;
196
+ this.selectedDate.set(newDate);
197
+ this.onChange(newDate.toISOString());
198
+ this.markAsTouched();
199
+ this.dateChange.emit(newDate);
200
+ // Notificar selección de fecha al padre
201
+ this.dateSelected.emit({
202
+ filter: this.filter(),
203
+ value: newDate,
204
+ });
205
+ // Solo cerrar automáticamente si es modo 'date'
206
+ if (this.mode() === 'date') {
207
+ this.close();
208
+ }
209
+ }
210
+ setHour12(hour12) {
211
+ if (this.isDisabled())
212
+ return;
213
+ // Convertir de 12h a 24h
214
+ let hour24;
215
+ const amPm = this.selectedAmPm();
216
+ if (hour12 === 12) {
217
+ hour24 = amPm === 'AM' ? 0 : 12;
218
+ }
219
+ else {
220
+ hour24 = amPm === 'AM' ? hour12 : hour12 + 12;
221
+ }
222
+ this.selectedHour.set(hour24);
223
+ this.updateDateTime();
224
+ }
225
+ setMinute(minute) {
226
+ if (this.isDisabled())
227
+ return;
228
+ this.selectedMinute.set(minute);
229
+ this.updateDateTime();
230
+ }
231
+ setAmPm(amPm) {
232
+ if (this.isDisabled())
233
+ return;
234
+ const currentHour24 = this.selectedHour();
235
+ const currentHour12 = this.selectedHour12();
236
+ let newHour24;
237
+ if (amPm === 'AM') {
238
+ newHour24 = currentHour12 === 12 ? 0 : currentHour12;
239
+ }
240
+ else {
241
+ newHour24 = currentHour12 === 12 ? 12 : currentHour12 + 12;
242
+ }
243
+ this.selectedAmPm.set(amPm);
244
+ this.selectedHour.set(newHour24);
245
+ this.updateDateTime();
246
+ }
247
+ previousMonth() {
248
+ const currentMonth = this.currentMonth();
249
+ const currentYear = this.currentYear();
250
+ if (currentMonth === 0) {
251
+ this.currentMonth.set(11);
252
+ this.currentYear.set(currentYear - 1);
253
+ }
254
+ else {
255
+ this.currentMonth.set(currentMonth - 1);
256
+ }
257
+ }
258
+ nextMonth() {
259
+ const currentMonth = this.currentMonth();
260
+ const currentYear = this.currentYear();
261
+ if (currentMonth === 11) {
262
+ this.currentMonth.set(0);
263
+ this.currentYear.set(currentYear + 1);
264
+ }
265
+ else {
266
+ this.currentMonth.set(currentMonth + 1);
267
+ }
268
+ }
269
+ previousYear() {
270
+ this.currentYear.set(this.currentYear() - 1);
271
+ }
272
+ nextYear() {
273
+ this.currentYear.set(this.currentYear() + 1);
274
+ }
275
+ today() {
276
+ const today = new Date();
277
+ this.currentMonth.set(today.getMonth());
278
+ this.currentYear.set(today.getFullYear());
279
+ this.selectedDate.set(today);
280
+ this.selectedHour.set(today.getHours());
281
+ this.selectedMinute.set(today.getMinutes());
282
+ this.selectedAmPm.set(today.getHours() >= 12 ? 'PM' : 'AM');
283
+ this.onChange(today.toISOString());
284
+ this.markAsTouched();
285
+ this.dateChange.emit(today);
286
+ // Notificar selección de fecha al padre
287
+ this.dateSelected.emit({
288
+ filter: this.filter(),
289
+ value: today,
290
+ });
291
+ if (this.mode() === 'date') {
292
+ this.close();
293
+ }
294
+ }
295
+ clear() {
296
+ this.selectedDate.set(null);
297
+ this.onChange(null);
298
+ this.markAsTouched();
299
+ this.dateChange.emit(null);
300
+ this.close();
301
+ }
302
+ onKeyDown(event) {
303
+ if (this.isDisabled())
304
+ return;
305
+ if (event.key === 'Escape') {
306
+ this.close();
307
+ }
308
+ else if (event.key === 'Tab') {
309
+ this.markAsTouched();
310
+ this.close();
311
+ }
312
+ }
313
+ isDaySelected(day) {
314
+ if (!day)
315
+ return false;
316
+ const selected = this.selectedDate();
317
+ if (!selected)
318
+ return false;
319
+ return (selected.getDate() === day &&
320
+ selected.getMonth() === this.currentMonth() &&
321
+ selected.getFullYear() === this.currentYear());
322
+ }
323
+ isToday(day) {
324
+ if (!day)
325
+ return false;
326
+ const today = new Date();
327
+ return (today.getDate() === day &&
328
+ today.getMonth() === this.currentMonth() &&
329
+ today.getFullYear() === this.currentYear());
330
+ }
331
+ isDayDisabled(day) {
332
+ if (!day)
333
+ return true;
334
+ const date = new Date(this.currentYear(), this.currentMonth(), day);
335
+ return this.isDateDisabled(date);
336
+ }
337
+ isDateDisabled(date) {
338
+ const minDate = this.minDate();
339
+ const maxDate = this.maxDate();
340
+ if (minDate && date < minDate)
341
+ return true;
342
+ if (maxDate && date > maxDate)
343
+ return true;
344
+ return false;
345
+ }
346
+ updateDateTime() {
347
+ const selected = this.selectedDate();
348
+ if (!selected)
349
+ return;
350
+ const newDate = new Date(selected);
351
+ newDate.setHours(this.selectedHour());
352
+ newDate.setMinutes(this.selectedMinute());
353
+ this.selectedDate.set(newDate);
354
+ this.onChange(newDate.toISOString());
355
+ this.markAsTouched();
356
+ this.dateChange.emit(newDate);
357
+ }
358
+ markAsTouched() {
359
+ if (!this.isTouched()) {
360
+ this.isTouched.set(true);
361
+ this.onTouched();
362
+ }
363
+ }
364
+ addDocumentListener() {
365
+ if (this.documentClickListener) {
366
+ this.removeDocumentListener();
367
+ }
368
+ this.ngZone.runOutsideAngular(() => {
369
+ this.documentClickListener = (event) => {
370
+ const target = event.target;
371
+ if (!this.elementRef.nativeElement.contains(target)) {
372
+ this.ngZone.run(() => {
373
+ if (this.isOpen()) {
374
+ this.markAsTouched();
375
+ this.close();
376
+ }
377
+ });
378
+ }
379
+ };
380
+ setTimeout(() => {
381
+ document.addEventListener('click', this.documentClickListener, true);
382
+ }, 10);
383
+ });
384
+ }
385
+ removeDocumentListener() {
386
+ if (this.documentClickListener) {
387
+ document.removeEventListener('click', this.documentClickListener, true);
388
+ this.documentClickListener = undefined;
389
+ }
390
+ }
391
+ markTouched() {
392
+ this.markAsTouched();
393
+ }
394
+ /**
395
+ * Obtiene la fecha seleccionada en formato ISO string
396
+ * @returns string ISO o null si no hay fecha seleccionada
397
+ */
398
+ getISOString() {
399
+ const date = this.selectedDate();
400
+ return date ? date.toISOString() : null;
401
+ }
402
+ /**
403
+ * Establece la fecha desde un string ISO
404
+ * @param isoString - Fecha en formato ISO
405
+ */
406
+ setFromISOString(isoString) {
407
+ if (isoString) {
408
+ const date = new Date(isoString);
409
+ if (!isNaN(date.getTime())) {
410
+ this.writeValue(date);
411
+ this.onChange(isoString);
412
+ }
413
+ }
414
+ else {
415
+ this.clear();
416
+ }
417
+ }
418
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: DateTimeFilter, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
419
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.13", type: DateTimeFilter, isStandalone: true, selector: "app-date-time-filter", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { dateSelected: "dateSelected", dateChange: "dateChange" }, providers: [
420
+ {
421
+ provide: NG_VALUE_ACCESSOR,
422
+ useExisting: forwardRef(() => DateTimeFilter),
423
+ multi: true,
424
+ },
425
+ ], ngImport: i0, template: "<div class=\"datetime-container\">\r\n \r\n @if (isOpen()) {\r\n <div class=\"dropdown\">\r\n <div class=\"datetime-content\">\r\n <!-- Secci\u00F3n del calendario -->\r\n <div class=\"calendar-section\">\r\n <!-- Navegaci\u00F3n -->\r\n <div class=\"calendar-nav\">\r\n <div class=\"nav-section\">\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"previousYear()\"\r\n title=\"A\u00F1o anterior\"\r\n >\r\n \u2039\u2039\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"previousMonth()\"\r\n title=\"Mes anterior\"\r\n >\r\n \u2039\r\n </button>\r\n </div>\r\n\r\n <div class=\"current-date\">{{ monthName() }} {{ currentYear() }}</div>\r\n\r\n <div class=\"nav-section\">\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"nextMonth()\"\r\n title=\"Siguiente mes\"\r\n >\r\n \u203A\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"nextYear()\"\r\n title=\"Siguiente a\u00F1o\"\r\n >\r\n \u203A\u203A\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- D\u00EDas de la semana -->\r\n <div class=\"weekdays\">\r\n <div class=\"weekday\">Dom</div>\r\n <div class=\"weekday\">Lun</div>\r\n <div class=\"weekday\">Mar</div>\r\n <div class=\"weekday\">Mi\u00E9</div>\r\n <div class=\"weekday\">Jue</div>\r\n <div class=\"weekday\">Vie</div>\r\n <div class=\"weekday\">S\u00E1b</div>\r\n </div>\r\n\r\n <!-- D\u00EDas -->\r\n <div class=\"calendar-grid\">\r\n @for (day of calendarDays(); track $index) {\r\n <div\r\n class=\"calendar-day\"\r\n [class.selected]=\"isDaySelected(day)\"\r\n [class.today]=\"isToday(day)\"\r\n [class.disabled]=\"isDayDisabled(day)\"\r\n [class.empty]=\"!day\"\r\n (click)=\"selectDay(day)\"\r\n >\r\n {{ day || \"\" }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- TIME PICKER -->\r\n @if (mode() === 'datetime') {\r\n <div class=\"time-section\">\r\n <div class=\"time-header\">Horario</div>\r\n\r\n <div class=\"time-selectors\">\r\n <div class=\"time-group\">\r\n <div class=\"time-column\">\r\n <div class=\"time-label\">Hora</div>\r\n <div class=\"time-scroll\">\r\n @for (hour of hours12(); track hour.value) {\r\n <div\r\n class=\"time-option\"\r\n [class.selected]=\"hour.value === selectedHour12()\"\r\n (click)=\"setHour12(hour.value)\"\r\n >\r\n {{ hour.display }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"time-separator-vertical\">:</div>\r\n\r\n <div class=\"time-column\">\r\n <div class=\"time-label\">Min</div>\r\n <div class=\"time-scroll\">\r\n @for (minute of minutes(); track minute) {\r\n <div\r\n class=\"time-option\"\r\n [class.selected]=\"minute === selectedMinute()\"\r\n (click)=\"setMinute(minute)\"\r\n >\r\n {{ minute.toString().padStart(2, \"0\") }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"time-column\">\r\n <div class=\"time-label\">AM/PM</div>\r\n <div class=\"time-scroll ampm\">\r\n <div\r\n class=\"time-option\"\r\n [class.selected]=\"selectedAmPm() === 'AM'\"\r\n (click)=\"setAmPm('AM')\"\r\n >\r\n AM\r\n </div>\r\n <div\r\n class=\"time-option\"\r\n [class.selected]=\"selectedAmPm() === 'PM'\"\r\n (click)=\"setAmPm('PM')\"\r\n >\r\n PM\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- botones -->\r\n <div class=\"action-buttons\">\r\n <button type=\"button\" class=\"action-btn secondary\" (click)=\"today()\">\r\n Hoy\r\n </button>\r\n\r\n @if (mode() === 'datetime') {\r\n <button type=\"button\" class=\"action-btn primary\" (click)=\"close()\">\r\n Aceptar\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n", styles: [".datetime-container{position:relative;width:100%}.datetime-header{width:100%;border:1px solid #787861;border-radius:5px;padding:15px;background-color:transparent;cursor:pointer;display:flex;justify-content:space-between;align-items:center;min-height:auto;transition:border-color .2s}.datetime-header:hover,.datetime-header:focus{outline:none;border-color:#a9a97f}.datetime-header.active{border-color:#a9a97f;outline:none}.datetime-header.disabled{cursor:not-allowed;opacity:.6}.selected-text{color:#454733;font-size:1.3rem;flex:1}.selected-text.placeholder{color:#787861}.header-icons{display:flex;align-items:center;gap:8px}.clear-icon{width:20px;height:20px;display:flex;align-items:center;justify-content:center;color:#787861;font-size:1.5rem;cursor:pointer;border-radius:50%;transition:all .2s}.clear-icon:hover{background-color:#7878611a;color:#454733}.arrow{width:15px;height:15px;background-image:url(\"data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e\");background-repeat:no-repeat;background-size:15px;background-position:center;color:#787861;flex-shrink:0;transition:transform .2s}.arrow.open{transform:rotate(180deg)}.dropdown{position:absolute;top:100%;left:0;right:0;background:#e3e3d1;border:1px solid #787861;border-top:none;border-radius:0 0 5px 5px;z-index:1000;box-shadow:0 4px 12px #00000026;min-width:400px}.datetime-content{display:flex}.calendar-section{flex:1;min-width:280px}.calendar-nav{display:flex;justify-content:space-between;align-items:center;padding:15px;border-bottom:1px solid rgba(120,120,97,.2)}.nav-section{display:flex;gap:5px}.nav-btn{background:none;border:none;color:#787861;cursor:pointer;font-size:1.2rem;padding:5px 10px;border-radius:3px;transition:all .2s}.nav-btn:hover{background-color:#a9a97f1a;color:#454733}.current-date{font-weight:500;color:#454733;font-size:1.1rem}.weekdays{display:grid;grid-template-columns:repeat(7,1fr);background:#7878611a}.weekday{padding:10px 5px;text-align:center;font-size:.9rem;font-weight:500;color:#787861}.calendar-grid{display:grid;grid-template-columns:repeat(7,1fr)}.calendar-day{padding:12px 5px;text-align:center;cursor:pointer;color:#454733;font-size:1rem;border-right:1px solid rgba(120,120,97,.1);border-bottom:1px solid rgba(120,120,97,.1);transition:all .2s}.calendar-day:hover:not(.disabled):not(.empty){background-color:#a9a97f33}.calendar-day.selected{background-color:#a9a97f;color:#e3e3d1;font-weight:500}.calendar-day.today:not(.selected){background-color:#a9a97f4d;font-weight:500}.calendar-day.disabled{color:#78786166;cursor:not-allowed}.calendar-day.empty{cursor:default}.calendar-day:nth-child(7n){border-right:none}.time-section{border-left:1px solid rgba(120,120,97,.2);min-width:140px;display:flex;flex-direction:column;background:#a9a97f0d}.time-header{padding:15px;border-bottom:1px solid rgba(120,120,97,.2);text-align:center;font-weight:500;color:#454733;background:#a9a97f1a}.time-selectors{display:flex;flex-direction:column;padding:15px;gap:20px;flex:1}.time-group{display:flex;align-items:center;gap:10px}.time-column{flex:1;display:flex;flex-direction:column;align-items:center}.time-label{font-size:.9rem;color:#787861;margin-bottom:10px;font-weight:500}.time-scroll{max-height:150px;overflow-y:auto;border:1px solid rgba(120,120,97,.2);border-radius:3px;width:50px;background:#a9a97f}.time-option{padding:8px 12px;text-align:center;cursor:pointer;color:#454733;font-size:1rem;transition:all .2s}.time-option:hover{background-color:#a9a97f1a}.time-option.selected{background-color:#a9a97f;color:#e3e3d1;font-weight:500}.time-separator-vertical{font-size:1.5rem;color:#787861;font-weight:700;align-self:flex-end;margin-bottom:10px}.time-scroll::-webkit-scrollbar{width:4px}.time-scroll::-webkit-scrollbar-track{background:#7878611a}.time-scroll::-webkit-scrollbar-thumb{background:#787861;border-radius:2px}.time-scroll::-webkit-scrollbar-thumb:hover{background:#a9a97f}.action-buttons{display:flex;justify-content:space-between;padding:15px;border-top:1px solid rgba(120,120,97,.2);gap:10px}.action-btn{padding:10px 20px;border:none;border-radius:3px;cursor:pointer;font-size:1rem;transition:all .2s}.action-btn.secondary{background:transparent;color:#787861;border:1px solid #787861}.action-btn.secondary:hover{background:#7878611a;color:#454733}.action-btn.primary{background:#a9a97f;color:#e3e3d1;border:1px solid #a9a97f}.action-btn.primary:hover{background:#969669;border-color:#969669}@media (max-width: 768px){.dropdown{min-width:320px}.datetime-content{flex-direction:column}.time-section{border-left:none;border-top:1px solid rgba(120,120,97,.2)}.time-selectors{flex-direction:row;justify-content:center;padding:15px}.time-group{gap:15px}.datetime-header{padding:12px 15px}.calendar-nav{padding:12px}.calendar-day{padding:10px 3px;font-size:.9rem}.action-buttons{padding:12px}}@media (max-width: 480px){.dropdown{min-width:280px}.time-section{min-width:auto}.time-scroll{width:45px}.time-selectors{padding:10px}}\n"] });
9
426
  }
10
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: MyComponent, decorators: [{
427
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: DateTimeFilter, decorators: [{
11
428
  type: Component,
12
- args: [{ selector: 'lib-my-component', imports: [], template: "<p>my-component works!</p>\r\n" }]
13
- }] });
429
+ args: [{ selector: 'app-date-time-filter', standalone: true, imports: [], providers: [
430
+ {
431
+ provide: NG_VALUE_ACCESSOR,
432
+ useExisting: forwardRef(() => DateTimeFilter),
433
+ multi: true,
434
+ },
435
+ ], template: "<div class=\"datetime-container\">\r\n \r\n @if (isOpen()) {\r\n <div class=\"dropdown\">\r\n <div class=\"datetime-content\">\r\n <!-- Secci\u00F3n del calendario -->\r\n <div class=\"calendar-section\">\r\n <!-- Navegaci\u00F3n -->\r\n <div class=\"calendar-nav\">\r\n <div class=\"nav-section\">\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"previousYear()\"\r\n title=\"A\u00F1o anterior\"\r\n >\r\n \u2039\u2039\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"previousMonth()\"\r\n title=\"Mes anterior\"\r\n >\r\n \u2039\r\n </button>\r\n </div>\r\n\r\n <div class=\"current-date\">{{ monthName() }} {{ currentYear() }}</div>\r\n\r\n <div class=\"nav-section\">\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"nextMonth()\"\r\n title=\"Siguiente mes\"\r\n >\r\n \u203A\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"nextYear()\"\r\n title=\"Siguiente a\u00F1o\"\r\n >\r\n \u203A\u203A\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- D\u00EDas de la semana -->\r\n <div class=\"weekdays\">\r\n <div class=\"weekday\">Dom</div>\r\n <div class=\"weekday\">Lun</div>\r\n <div class=\"weekday\">Mar</div>\r\n <div class=\"weekday\">Mi\u00E9</div>\r\n <div class=\"weekday\">Jue</div>\r\n <div class=\"weekday\">Vie</div>\r\n <div class=\"weekday\">S\u00E1b</div>\r\n </div>\r\n\r\n <!-- D\u00EDas -->\r\n <div class=\"calendar-grid\">\r\n @for (day of calendarDays(); track $index) {\r\n <div\r\n class=\"calendar-day\"\r\n [class.selected]=\"isDaySelected(day)\"\r\n [class.today]=\"isToday(day)\"\r\n [class.disabled]=\"isDayDisabled(day)\"\r\n [class.empty]=\"!day\"\r\n (click)=\"selectDay(day)\"\r\n >\r\n {{ day || \"\" }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- TIME PICKER -->\r\n @if (mode() === 'datetime') {\r\n <div class=\"time-section\">\r\n <div class=\"time-header\">Horario</div>\r\n\r\n <div class=\"time-selectors\">\r\n <div class=\"time-group\">\r\n <div class=\"time-column\">\r\n <div class=\"time-label\">Hora</div>\r\n <div class=\"time-scroll\">\r\n @for (hour of hours12(); track hour.value) {\r\n <div\r\n class=\"time-option\"\r\n [class.selected]=\"hour.value === selectedHour12()\"\r\n (click)=\"setHour12(hour.value)\"\r\n >\r\n {{ hour.display }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"time-separator-vertical\">:</div>\r\n\r\n <div class=\"time-column\">\r\n <div class=\"time-label\">Min</div>\r\n <div class=\"time-scroll\">\r\n @for (minute of minutes(); track minute) {\r\n <div\r\n class=\"time-option\"\r\n [class.selected]=\"minute === selectedMinute()\"\r\n (click)=\"setMinute(minute)\"\r\n >\r\n {{ minute.toString().padStart(2, \"0\") }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"time-column\">\r\n <div class=\"time-label\">AM/PM</div>\r\n <div class=\"time-scroll ampm\">\r\n <div\r\n class=\"time-option\"\r\n [class.selected]=\"selectedAmPm() === 'AM'\"\r\n (click)=\"setAmPm('AM')\"\r\n >\r\n AM\r\n </div>\r\n <div\r\n class=\"time-option\"\r\n [class.selected]=\"selectedAmPm() === 'PM'\"\r\n (click)=\"setAmPm('PM')\"\r\n >\r\n PM\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- botones -->\r\n <div class=\"action-buttons\">\r\n <button type=\"button\" class=\"action-btn secondary\" (click)=\"today()\">\r\n Hoy\r\n </button>\r\n\r\n @if (mode() === 'datetime') {\r\n <button type=\"button\" class=\"action-btn primary\" (click)=\"close()\">\r\n Aceptar\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n", styles: [".datetime-container{position:relative;width:100%}.datetime-header{width:100%;border:1px solid #787861;border-radius:5px;padding:15px;background-color:transparent;cursor:pointer;display:flex;justify-content:space-between;align-items:center;min-height:auto;transition:border-color .2s}.datetime-header:hover,.datetime-header:focus{outline:none;border-color:#a9a97f}.datetime-header.active{border-color:#a9a97f;outline:none}.datetime-header.disabled{cursor:not-allowed;opacity:.6}.selected-text{color:#454733;font-size:1.3rem;flex:1}.selected-text.placeholder{color:#787861}.header-icons{display:flex;align-items:center;gap:8px}.clear-icon{width:20px;height:20px;display:flex;align-items:center;justify-content:center;color:#787861;font-size:1.5rem;cursor:pointer;border-radius:50%;transition:all .2s}.clear-icon:hover{background-color:#7878611a;color:#454733}.arrow{width:15px;height:15px;background-image:url(\"data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e\");background-repeat:no-repeat;background-size:15px;background-position:center;color:#787861;flex-shrink:0;transition:transform .2s}.arrow.open{transform:rotate(180deg)}.dropdown{position:absolute;top:100%;left:0;right:0;background:#e3e3d1;border:1px solid #787861;border-top:none;border-radius:0 0 5px 5px;z-index:1000;box-shadow:0 4px 12px #00000026;min-width:400px}.datetime-content{display:flex}.calendar-section{flex:1;min-width:280px}.calendar-nav{display:flex;justify-content:space-between;align-items:center;padding:15px;border-bottom:1px solid rgba(120,120,97,.2)}.nav-section{display:flex;gap:5px}.nav-btn{background:none;border:none;color:#787861;cursor:pointer;font-size:1.2rem;padding:5px 10px;border-radius:3px;transition:all .2s}.nav-btn:hover{background-color:#a9a97f1a;color:#454733}.current-date{font-weight:500;color:#454733;font-size:1.1rem}.weekdays{display:grid;grid-template-columns:repeat(7,1fr);background:#7878611a}.weekday{padding:10px 5px;text-align:center;font-size:.9rem;font-weight:500;color:#787861}.calendar-grid{display:grid;grid-template-columns:repeat(7,1fr)}.calendar-day{padding:12px 5px;text-align:center;cursor:pointer;color:#454733;font-size:1rem;border-right:1px solid rgba(120,120,97,.1);border-bottom:1px solid rgba(120,120,97,.1);transition:all .2s}.calendar-day:hover:not(.disabled):not(.empty){background-color:#a9a97f33}.calendar-day.selected{background-color:#a9a97f;color:#e3e3d1;font-weight:500}.calendar-day.today:not(.selected){background-color:#a9a97f4d;font-weight:500}.calendar-day.disabled{color:#78786166;cursor:not-allowed}.calendar-day.empty{cursor:default}.calendar-day:nth-child(7n){border-right:none}.time-section{border-left:1px solid rgba(120,120,97,.2);min-width:140px;display:flex;flex-direction:column;background:#a9a97f0d}.time-header{padding:15px;border-bottom:1px solid rgba(120,120,97,.2);text-align:center;font-weight:500;color:#454733;background:#a9a97f1a}.time-selectors{display:flex;flex-direction:column;padding:15px;gap:20px;flex:1}.time-group{display:flex;align-items:center;gap:10px}.time-column{flex:1;display:flex;flex-direction:column;align-items:center}.time-label{font-size:.9rem;color:#787861;margin-bottom:10px;font-weight:500}.time-scroll{max-height:150px;overflow-y:auto;border:1px solid rgba(120,120,97,.2);border-radius:3px;width:50px;background:#a9a97f}.time-option{padding:8px 12px;text-align:center;cursor:pointer;color:#454733;font-size:1rem;transition:all .2s}.time-option:hover{background-color:#a9a97f1a}.time-option.selected{background-color:#a9a97f;color:#e3e3d1;font-weight:500}.time-separator-vertical{font-size:1.5rem;color:#787861;font-weight:700;align-self:flex-end;margin-bottom:10px}.time-scroll::-webkit-scrollbar{width:4px}.time-scroll::-webkit-scrollbar-track{background:#7878611a}.time-scroll::-webkit-scrollbar-thumb{background:#787861;border-radius:2px}.time-scroll::-webkit-scrollbar-thumb:hover{background:#a9a97f}.action-buttons{display:flex;justify-content:space-between;padding:15px;border-top:1px solid rgba(120,120,97,.2);gap:10px}.action-btn{padding:10px 20px;border:none;border-radius:3px;cursor:pointer;font-size:1rem;transition:all .2s}.action-btn.secondary{background:transparent;color:#787861;border:1px solid #787861}.action-btn.secondary:hover{background:#7878611a;color:#454733}.action-btn.primary{background:#a9a97f;color:#e3e3d1;border:1px solid #a9a97f}.action-btn.primary:hover{background:#969669;border-color:#969669}@media (max-width: 768px){.dropdown{min-width:320px}.datetime-content{flex-direction:column}.time-section{border-left:none;border-top:1px solid rgba(120,120,97,.2)}.time-selectors{flex-direction:row;justify-content:center;padding:15px}.time-group{gap:15px}.datetime-header{padding:12px 15px}.calendar-nav{padding:12px}.calendar-day{padding:10px 3px;font-size:.9rem}.action-buttons{padding:12px}}@media (max-width: 480px){.dropdown{min-width:280px}.time-section{min-width:auto}.time-scroll{width:45px}.time-selectors{padding:10px}}\n"] }]
436
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.NgZone }], propDecorators: { mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], maxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: true }] }], dateSelected: [{ type: i0.Output, args: ["dateSelected"] }], dateChange: [{ type: i0.Output, args: ["dateChange"] }] } });
14
437
 
15
438
  class PaginationComponent {
16
439
  page = 1;
@@ -118,5 +541,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImpo
118
541
  * Generated bundle index. Do not edit.
119
542
  */
120
543
 
121
- export { MyComponent, PaginationComponent, Table };
544
+ export { DateTimeFilter, PaginationComponent, Table };
122
545
  //# sourceMappingURL=sapenlinea-components.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"sapenlinea-components.mjs","sources":["../../../projects/sapenlinea-components/src/lib/components/my-component/my-component.ts","../../../projects/sapenlinea-components/src/lib/components/my-component/my-component.html","../../../projects/sapenlinea-components/src/lib/components/pagination/pagination.ts","../../../projects/sapenlinea-components/src/lib/components/pagination/pagination.html","../../../projects/sapenlinea-components/src/lib/components/table/table.ts","../../../projects/sapenlinea-components/src/lib/components/table/table.html","../../../projects/sapenlinea-components/src/public-api.ts","../../../projects/sapenlinea-components/src/sapenlinea-components.ts"],"sourcesContent":["import { Component } from '@angular/core';\r\n\r\n@Component({\r\n selector: 'lib-my-component',\r\n imports: [],\r\n templateUrl: './my-component.html',\r\n styleUrl: './my-component.css',\r\n})\r\nexport class MyComponent {\r\n\r\n}\r\n","<p>my-component works!</p>\r\n","import { Component, Input, Output, EventEmitter, computed, signal } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n@Component({\r\n selector: 'app-pagination',\r\n standalone: true,\r\n imports: [CommonModule],\r\n templateUrl: './pagination.html',\r\n styleUrls: ['./pagination.css']\r\n})\r\nexport class PaginationComponent {\r\n @Input() page = 1;\r\n @Input() pageSize = 10;\r\n @Input() totalItems = 0;\r\n\r\n @Input() showPageSizeSelector = false;\r\n @Input() pageSizeOptions: number[] = [5, 10, 20, 50];\r\n\r\n @Output() pageChange = new EventEmitter<number>();\r\n @Output() pageSizeChange = new EventEmitter<number>();\r\n\r\n pageSizeValue = signal(this.pageSize);\r\n isOpen = signal(false);\r\n isDisabled = signal(false);\r\n showPageSizeMenu = signal(false);\r\n\r\n totalPages = computed(() => {\r\n const size = this.pageSizeValue();\r\n const total = this.totalItems;\r\n return size > 0 ? Math.ceil(total / size) : 1;\r\n });\r\n\r\n pages = computed(() => {\r\n const tp = this.totalPages();\r\n return Array.from({ length: tp }, (_, i) => i + 1);\r\n });\r\n\r\n selectedPageSize = computed(() => this.pageSizeValue());\r\n\r\n goToPage(p: number) {\r\n if (p < 1 || p > this.totalPages()) return;\r\n this.pageChange.emit(p);\r\n }\r\n\r\n togglePageSizeMenu() {\r\n this.isOpen.update(v => !v);\r\n this.showPageSizeMenu.update(v => !v);\r\n }\r\n\r\n selectPageSize(size: number) {\r\n this.pageSizeValue.set(size);\r\n this.pageSizeChange.emit(size);\r\n this.showPageSizeMenu.set(false);\r\n this.isOpen.set(false);\r\n }\r\n}\r\n","<div class=\"pagination-container\">\r\n <div class=\"pagination\">\r\n <!-- Botón doble atrás -->\r\n <button class=\"icon-button\" (click)=\"goToPage(1)\" [disabled]=\"page === 1\">\r\n ««\r\n </button>\r\n\r\n <!-- Botón atrás -->\r\n <button class=\"icon-button\" (click)=\"goToPage(page - 1)\" [disabled]=\"page === 1\">\r\n «\r\n </button>\r\n\r\n <!-- Números de página -->\r\n <div class=\"pages\">\r\n <button\r\n class=\"page-btn\"\r\n *ngFor=\"let p of pages(); let idx = index\"\r\n [class.active]=\"page === idx + 1\"\r\n (click)=\"goToPage(idx + 1)\"\r\n >\r\n {{ idx + 1 }}\r\n </button>\r\n </div>\r\n\r\n <!-- Botón siguiente -->\r\n <button class=\"icon-button\" (click)=\"goToPage(page + 1)\" [disabled]=\"page === totalPages()\">\r\n »\r\n </button>\r\n\r\n <!-- Botón doble adelante -->\r\n <button class=\"icon-button\" (click)=\"goToPage(totalPages())\" [disabled]=\"page === totalPages()\">\r\n »»\r\n </button>\r\n </div>\r\n\r\n <!-- Selector Items por página -->\r\n <div *ngIf=\"showPageSizeSelector\">\r\n <div class=\"pagination-v-4\">\r\n <div class=\"label-pagination\">Items por página</div>\r\n <div class=\"elements-pagination\">\r\n <div class=\"split-button\" (click)=\"togglePageSizeMenu()\">\r\n <div class=\"leading-button\">\r\n <div class=\"state-layer\">\r\n <div class=\"label\">{{ pageSizeValue() }}</div>\r\n </div>\r\n </div>\r\n <div class=\"trailing-button\">\r\n <div class=\"arrow\" [class.open]=\"isOpen()\">\r\n <svg class=\"arrow\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Menú desplegable -->\r\n <div class=\"page-size-menu\" *ngIf=\"showPageSizeMenu()\">\r\n <div\r\n class=\"menu-option\"\r\n *ngFor=\"let opt of pageSizeOptions\"\r\n [class.active]=\"opt === pageSizeValue()\"\r\n (click)=\"selectPageSize(opt)\"\r\n >\r\n {{ opt }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n","import { Component, HostListener, input, output, signal } from '@angular/core';\r\nimport { TableAction, TableColumn, TableRow } from '../../interfaces/table';\r\n\r\n@Component({\r\n selector: 'lib-table',\r\n imports: [],\r\n standalone: true,\r\n templateUrl: './table.html',\r\n styleUrl: './table.css',\r\n})\r\nexport class Table {\r\n columns = input<TableColumn[]>([]);\r\n data = input<TableRow[]>([]);\r\n actions = input<TableAction[]>([]);\r\n\r\n openedMenu = signal<number | null>(null);\r\n selectedRow = signal<TableRow | null>(null);\r\n \r\n optionSelected = output<{ action: string; row: TableRow }>();\r\n\r\n toggleMenu(index: number) {\r\n this.openedMenu.set(this.openedMenu() === index ? null : index);\r\n }\r\n\r\n onOptionClick(option: TableAction, row: TableRow) {\r\n this.optionSelected.emit({ action: option.label, row });\r\n this.openedMenu.set(null);\r\n }\r\n\r\n openModal(row: TableRow, event?: MouseEvent) {\r\n event?.stopPropagation();\r\n\r\n if (this.selectedRow()?.['id'] === row['id']) {\r\n this.selectedRow.set(null);\r\n } else {\r\n this.selectedRow.set(row);\r\n }\r\n }\r\n\r\n @HostListener('document:click', ['$event'])\r\n onClickOutside(event: MouseEvent) {\r\n const target = event.target as HTMLElement;\r\n if (!target.closest('.menu-acciones')) {\r\n this.selectedRow.set(null);\r\n }\r\n }\r\n}\r\n","<div class=\"table-wrapper\">\r\n <table class=\"inner-table\">\r\n <thead>\r\n <tr>\r\n @for (col of columns(); track col.key) {\r\n <th>{{ col.label }}</th>\r\n }\r\n\r\n <!-- columna para acciones -->\r\n <th></th>\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n @for (row of data(); track $index) {\r\n <tr>\r\n @for (col of columns(); track col.key) {\r\n <td>{{ row[col.key] }}</td>\r\n }\r\n\r\n <!-- Celda de acciones -->\r\n <td class=\"acciones-cell\">\r\n <div class=\"menu-acciones\">\r\n <button class=\"icon-button\" (click)=\"openModal(row)\">\r\n <div class=\"content\">\r\n <div class=\"state-layer\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n class=\"more-vert\"\r\n width=\"20\"\r\n height=\"20\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <circle cx=\"12\" cy=\"5\" r=\"1\" />\r\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\r\n <circle cx=\"12\" cy=\"19\" r=\"1\" />\r\n </svg>\r\n </div>\r\n </div>\r\n </button>\r\n @if(selectedRow()?.['id'] === row['id']){\r\n <div class=\"modal-options\" (click)=\"$event.stopPropagation()\">\r\n \r\n <div class=\"modal-content\">\r\n <ul>\r\n @for (option of actions(); track $index) {\r\n <li\r\n class=\"option-item\"\r\n [style.color]=\"option.color\"\r\n (click)=\"onOptionClick(option, row)\"\r\n >\r\n <span class=\"icon\" [class]=\"option.icon\"></span>\r\n <span class=\"label\">{{ option.label }}</span>\r\n </li>\r\n }\r\n </ul>\r\n </div>\r\n \r\n </div>\r\n }\r\n </div>\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n</div>","// src/app/components/public-api.ts\r\n\r\n// Exportar el componente\r\nexport * from './lib/components/my-component/my-component';\r\nexport * from './lib/components/pagination/pagination';\r\nexport * from './lib/components/table/table';\r\n\r\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":"sapenlinea-components.mjs","sources":["../../../projects/sapenlinea-components/src/lib/components/date-time-filter/date-time-filter.ts","../../../projects/sapenlinea-components/src/lib/components/date-time-filter/date-time-filter.html","../../../projects/sapenlinea-components/src/lib/components/pagination/pagination.ts","../../../projects/sapenlinea-components/src/lib/components/pagination/pagination.html","../../../projects/sapenlinea-components/src/lib/components/table/table.ts","../../../projects/sapenlinea-components/src/lib/components/table/table.html","../../../projects/sapenlinea-components/src/public-api.ts","../../../projects/sapenlinea-components/src/sapenlinea-components.ts"],"sourcesContent":["import {\r\n Component,\r\n computed,\r\n ElementRef,\r\n input,\r\n output,\r\n signal,\r\n forwardRef,\r\n OnDestroy,\r\n NgZone,\r\n} from '@angular/core';\r\nimport { ControlValueAccessor, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms';\r\n\r\nexport interface FilterOption {\r\n label: string;\r\n value: string;\r\n type: 'date';\r\n}\r\n\r\nexport interface DateFilterSelection {\r\n filter: string;\r\n value: Date;\r\n}\r\n\r\nexport type DateTimeMode = 'date' | 'datetime';\r\n\r\ninterface Hour12 {\r\n value: number;\r\n display: string;\r\n}\r\n\r\nexport type FilterType = DateTimeMode;\r\n\r\n@Component({\r\n selector: 'app-date-time-filter',\r\n standalone: true,\r\n imports: [],\r\n templateUrl: './date-time-filter.html',\r\n styleUrl: './date-time-filter.css',\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: forwardRef(() => DateTimeFilter),\r\n multi: true,\r\n },\r\n ],\r\n})\r\nexport class DateTimeFilter implements ControlValueAccessor, OnDestroy {\r\n mode = input<DateTimeMode>('date');\r\n placeholder = input<string>('Seleccionar fecha');\r\n minDate = input<Date | null>(null);\r\n maxDate = input<Date | null>(null);\r\n filter = input.required<string>();\r\n dateSelected = output<DateFilterSelection>();\r\n\r\n filters: FilterOption[] = [\r\n { label: 'Fecha inicio', value: 'inicio', type: 'date' },\r\n { label: 'Fecha fin', value: 'fin', type: 'date' },\r\n { label: 'Fecha Nacimiento', value: 'born', type: 'date' },\r\n ];\r\n\r\n dateChange = output<Date | null>();\r\n\r\n isOpen = signal(false);\r\n selectedDate = signal<Date | null>(null);\r\n isDisabled = signal(false);\r\n isTouched = signal(false);\r\n\r\n // Navegación del calendario\r\n currentMonth = signal(new Date().getMonth());\r\n currentYear = signal(new Date().getFullYear());\r\n\r\n // Hora en formato 24h (para el backend)\r\n selectedHour = signal(0);\r\n selectedMinute = signal(0);\r\n\r\n // Estado AM/PM\r\n selectedAmPm = signal<'AM' | 'PM'>('AM');\r\n\r\n private documentClickListener?: (event: Event) => void;\r\n\r\n showFilters = false;\r\n showDatePicker = false;\r\n activeFilterType: string | null = null;\r\n\r\n selectDate(date: Date): void {\r\n this.dateSelected.emit({\r\n filter: this.filter(),\r\n value: date\r\n });\r\n }\r\n\r\n getDatePickerMode(type: FilterType): DateTimeMode {\r\n switch (type) {\r\n case 'date':\r\n return 'date';\r\n case 'datetime':\r\n return 'datetime';\r\n default:\r\n return 'date';\r\n }\r\n }\r\n\r\n displayValue = computed(() => {\r\n const date = this.selectedDate();\r\n if (!date) return '';\r\n\r\n const options: Intl.DateTimeFormatOptions = {\r\n day: '2-digit',\r\n month: '2-digit',\r\n year: 'numeric',\r\n };\r\n\r\n if (this.mode() === 'datetime') {\r\n options.hour = '2-digit';\r\n options.minute = '2-digit';\r\n options.hour12 = true; // Cambiado a formato 12 horas\r\n }\r\n\r\n return date.toLocaleDateString('es-ES', options);\r\n });\r\n\r\n monthName = computed(() => {\r\n const months = [\r\n 'Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio',\r\n 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'\r\n ];\r\n return months[this.currentMonth()];\r\n });\r\n\r\n calendarDays = computed(() => {\r\n const year = this.currentYear();\r\n const month = this.currentMonth();\r\n const firstDay = new Date(year, month, 1);\r\n const lastDay = new Date(year, month + 1, 0);\r\n const daysInMonth = lastDay.getDate();\r\n const startingDayOfWeek = firstDay.getDay();\r\n\r\n const days: (number | null)[] = [];\r\n\r\n // Días vacíos al inicio\r\n for (let i = 0; i < startingDayOfWeek; i++) {\r\n days.push(null);\r\n }\r\n\r\n // Días del mes\r\n for (let day = 1; day <= daysInMonth; day++) {\r\n days.push(day);\r\n }\r\n\r\n return days;\r\n });\r\n\r\n // Horas en formato 12h\r\n hours12 = computed((): Hour12[] => {\r\n return Array.from({ length: 12 }, (_, i) => {\r\n const hour12 = i === 0 ? 12 : i;\r\n return {\r\n value: hour12,\r\n display: hour12.toString().padStart(2, '0')\r\n };\r\n });\r\n });\r\n\r\n // Hora seleccionada en formato 12h\r\n selectedHour12 = computed(() => {\r\n const hour24 = this.selectedHour();\r\n if (hour24 === 0) return 12;\r\n if (hour24 > 12) return hour24 - 12;\r\n return hour24;\r\n });\r\n\r\n minutes = computed(() => Array.from({ length: 60 }, (_, i) => i));\r\n\r\n private onChange: (value: string | null) => void = () => { };\r\n private onTouched: () => void = () => { };\r\n\r\n constructor(private elementRef: ElementRef, private ngZone: NgZone) { }\r\n\r\n ngOnDestroy() {\r\n this.removeDocumentListener();\r\n }\r\n\r\n writeValue(value: string | Date | null): void {\r\n let date: Date | null = null;\r\n\r\n if (value instanceof Date) {\r\n date = value;\r\n } else if (typeof value === 'string' && value) {\r\n // Manejar tanto fechas ISO como otros formatos de string\r\n const parsedDate = new Date(value);\r\n if (!isNaN(parsedDate.getTime())) {\r\n date = parsedDate;\r\n }\r\n }\r\n\r\n if (date) {\r\n this.selectedDate.set(date);\r\n this.currentMonth.set(date.getMonth());\r\n this.currentYear.set(date.getFullYear());\r\n this.selectedHour.set(date.getHours());\r\n this.selectedMinute.set(date.getMinutes());\r\n this.selectedAmPm.set(date.getHours() >= 12 ? 'PM' : 'AM');\r\n } else {\r\n this.selectedDate.set(null);\r\n // Valores por defecto\r\n this.selectedHour.set(0);\r\n this.selectedMinute.set(0);\r\n this.selectedAmPm.set('AM');\r\n }\r\n }\r\n\r\n registerOnChange(fn: (value: string | null) => void): void {\r\n this.onChange = fn;\r\n }\r\n\r\n registerOnTouched(fn: () => void): void {\r\n this.onTouched = fn;\r\n }\r\n\r\n setDisabledState(isDisabled: boolean): void {\r\n this.isDisabled.set(isDisabled);\r\n }\r\n\r\n toggle() {\r\n if (this.isDisabled()) return;\r\n\r\n this.markAsTouched();\r\n\r\n if (this.isOpen()) {\r\n this.close();\r\n } else {\r\n this.open();\r\n }\r\n }\r\n\r\n open() {\r\n if (this.isDisabled()) return;\r\n\r\n this.markAsTouched();\r\n this.isOpen.set(true);\r\n this.addDocumentListener();\r\n\r\n // Si hay fecha seleccionada, navegar a ese mes/año\r\n const selected = this.selectedDate();\r\n if (selected) {\r\n this.currentMonth.set(selected.getMonth());\r\n this.currentYear.set(selected.getFullYear());\r\n }\r\n }\r\n\r\n close() {\r\n this.isOpen.set(false);\r\n this.removeDocumentListener();\r\n this.markAsTouched();\r\n }\r\n\r\n selectDay(day: number | null) {\r\n if (!day || this.isDisabled()) return;\r\n\r\n const newDate = new Date(\r\n this.currentYear(),\r\n this.currentMonth(),\r\n day,\r\n this.selectedHour(),\r\n this.selectedMinute()\r\n );\r\n\r\n if (this.isDateDisabled(newDate)) return;\r\n\r\n this.selectedDate.set(newDate);\r\n this.onChange(newDate.toISOString());\r\n this.markAsTouched();\r\n this.dateChange.emit(newDate);\r\n\r\n // Notificar selección de fecha al padre\r\n this.dateSelected.emit({\r\n filter: this.filter(),\r\n value: newDate,\r\n });\r\n\r\n // Solo cerrar automáticamente si es modo 'date'\r\n if (this.mode() === 'date') {\r\n this.close();\r\n }\r\n }\r\n\r\n setHour12(hour12: number) {\r\n if (this.isDisabled()) return;\r\n\r\n // Convertir de 12h a 24h\r\n let hour24: number;\r\n const amPm = this.selectedAmPm();\r\n\r\n if (hour12 === 12) {\r\n hour24 = amPm === 'AM' ? 0 : 12;\r\n } else {\r\n hour24 = amPm === 'AM' ? hour12 : hour12 + 12;\r\n }\r\n\r\n this.selectedHour.set(hour24);\r\n this.updateDateTime();\r\n }\r\n\r\n setMinute(minute: number) {\r\n if (this.isDisabled()) return;\r\n\r\n this.selectedMinute.set(minute);\r\n this.updateDateTime();\r\n }\r\n\r\n setAmPm(amPm: 'AM' | 'PM') {\r\n if (this.isDisabled()) return;\r\n\r\n const currentHour24 = this.selectedHour();\r\n const currentHour12 = this.selectedHour12();\r\n let newHour24: number;\r\n\r\n if (amPm === 'AM') {\r\n newHour24 = currentHour12 === 12 ? 0 : currentHour12;\r\n } else {\r\n newHour24 = currentHour12 === 12 ? 12 : currentHour12 + 12;\r\n }\r\n\r\n this.selectedAmPm.set(amPm);\r\n this.selectedHour.set(newHour24);\r\n this.updateDateTime();\r\n }\r\n\r\n previousMonth() {\r\n const currentMonth = this.currentMonth();\r\n const currentYear = this.currentYear();\r\n\r\n if (currentMonth === 0) {\r\n this.currentMonth.set(11);\r\n this.currentYear.set(currentYear - 1);\r\n } else {\r\n this.currentMonth.set(currentMonth - 1);\r\n }\r\n }\r\n\r\n nextMonth() {\r\n const currentMonth = this.currentMonth();\r\n const currentYear = this.currentYear();\r\n\r\n if (currentMonth === 11) {\r\n this.currentMonth.set(0);\r\n this.currentYear.set(currentYear + 1);\r\n } else {\r\n this.currentMonth.set(currentMonth + 1);\r\n }\r\n }\r\n\r\n previousYear() {\r\n this.currentYear.set(this.currentYear() - 1);\r\n }\r\n\r\n nextYear() {\r\n this.currentYear.set(this.currentYear() + 1);\r\n }\r\n\r\n today() {\r\n const today = new Date();\r\n this.currentMonth.set(today.getMonth());\r\n this.currentYear.set(today.getFullYear());\r\n this.selectedDate.set(today);\r\n this.selectedHour.set(today.getHours());\r\n this.selectedMinute.set(today.getMinutes());\r\n this.selectedAmPm.set(today.getHours() >= 12 ? 'PM' : 'AM');\r\n this.onChange(today.toISOString());\r\n this.markAsTouched();\r\n this.dateChange.emit(today);\r\n\r\n // Notificar selección de fecha al padre\r\n this.dateSelected.emit({\r\n filter: this.filter(),\r\n value: today,\r\n });\r\n\r\n if (this.mode() === 'date') {\r\n this.close();\r\n }\r\n }\r\n\r\n clear() {\r\n this.selectedDate.set(null);\r\n this.onChange(null);\r\n this.markAsTouched();\r\n this.dateChange.emit(null);\r\n this.close();\r\n }\r\n\r\n onKeyDown(event: KeyboardEvent) {\r\n if (this.isDisabled()) return;\r\n\r\n if (event.key === 'Escape') {\r\n this.close();\r\n } else if (event.key === 'Tab') {\r\n this.markAsTouched();\r\n this.close();\r\n }\r\n }\r\n\r\n isDaySelected(day: number | null): boolean {\r\n if (!day) return false;\r\n const selected = this.selectedDate();\r\n if (!selected) return false;\r\n\r\n return (\r\n selected.getDate() === day &&\r\n selected.getMonth() === this.currentMonth() &&\r\n selected.getFullYear() === this.currentYear()\r\n );\r\n }\r\n\r\n isToday(day: number | null): boolean {\r\n if (!day) return false;\r\n const today = new Date();\r\n return (\r\n today.getDate() === day &&\r\n today.getMonth() === this.currentMonth() &&\r\n today.getFullYear() === this.currentYear()\r\n );\r\n }\r\n\r\n isDayDisabled(day: number | null): boolean {\r\n if (!day) return true;\r\n\r\n const date = new Date(this.currentYear(), this.currentMonth(), day);\r\n return this.isDateDisabled(date);\r\n }\r\n\r\n isDateDisabled(date: Date): boolean {\r\n const minDate = this.minDate();\r\n const maxDate = this.maxDate();\r\n\r\n if (minDate && date < minDate) return true;\r\n if (maxDate && date > maxDate) return true;\r\n\r\n return false;\r\n }\r\n\r\n private updateDateTime() {\r\n const selected = this.selectedDate();\r\n if (!selected) return;\r\n\r\n const newDate = new Date(selected);\r\n newDate.setHours(this.selectedHour());\r\n newDate.setMinutes(this.selectedMinute());\r\n\r\n this.selectedDate.set(newDate);\r\n this.onChange(newDate.toISOString());\r\n this.markAsTouched();\r\n this.dateChange.emit(newDate);\r\n }\r\n\r\n private markAsTouched() {\r\n if (!this.isTouched()) {\r\n this.isTouched.set(true);\r\n this.onTouched();\r\n }\r\n }\r\n\r\n private addDocumentListener() {\r\n if (this.documentClickListener) {\r\n this.removeDocumentListener();\r\n }\r\n\r\n this.ngZone.runOutsideAngular(() => {\r\n this.documentClickListener = (event: Event) => {\r\n const target = event.target as Node;\r\n if (!this.elementRef.nativeElement.contains(target)) {\r\n this.ngZone.run(() => {\r\n if (this.isOpen()) {\r\n this.markAsTouched();\r\n this.close();\r\n }\r\n });\r\n }\r\n };\r\n\r\n setTimeout(() => {\r\n document.addEventListener('click', this.documentClickListener!, true);\r\n }, 10);\r\n });\r\n }\r\n\r\n private removeDocumentListener() {\r\n if (this.documentClickListener) {\r\n document.removeEventListener('click', this.documentClickListener, true);\r\n this.documentClickListener = undefined;\r\n }\r\n }\r\n\r\n public markTouched() {\r\n this.markAsTouched();\r\n }\r\n\r\n /**\r\n * Obtiene la fecha seleccionada en formato ISO string\r\n * @returns string ISO o null si no hay fecha seleccionada\r\n */\r\n public getISOString(): string | null {\r\n const date = this.selectedDate();\r\n return date ? date.toISOString() : null;\r\n }\r\n\r\n /**\r\n * Establece la fecha desde un string ISO\r\n * @param isoString - Fecha en formato ISO\r\n */\r\n public setFromISOString(isoString: string | null): void {\r\n if (isoString) {\r\n const date = new Date(isoString);\r\n if (!isNaN(date.getTime())) {\r\n this.writeValue(date);\r\n this.onChange(isoString);\r\n }\r\n } else {\r\n this.clear();\r\n }\r\n }\r\n}","<div class=\"datetime-container\">\r\n \r\n @if (isOpen()) {\r\n <div class=\"dropdown\">\r\n <div class=\"datetime-content\">\r\n <!-- Sección del calendario -->\r\n <div class=\"calendar-section\">\r\n <!-- Navegación -->\r\n <div class=\"calendar-nav\">\r\n <div class=\"nav-section\">\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"previousYear()\"\r\n title=\"Año anterior\"\r\n >\r\n ‹‹\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"previousMonth()\"\r\n title=\"Mes anterior\"\r\n >\r\n ‹\r\n </button>\r\n </div>\r\n\r\n <div class=\"current-date\">{{ monthName() }} {{ currentYear() }}</div>\r\n\r\n <div class=\"nav-section\">\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"nextMonth()\"\r\n title=\"Siguiente mes\"\r\n >\r\n ›\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"nav-btn\"\r\n (click)=\"nextYear()\"\r\n title=\"Siguiente año\"\r\n >\r\n ››\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- Días de la semana -->\r\n <div class=\"weekdays\">\r\n <div class=\"weekday\">Dom</div>\r\n <div class=\"weekday\">Lun</div>\r\n <div class=\"weekday\">Mar</div>\r\n <div class=\"weekday\">Mié</div>\r\n <div class=\"weekday\">Jue</div>\r\n <div class=\"weekday\">Vie</div>\r\n <div class=\"weekday\">Sáb</div>\r\n </div>\r\n\r\n <!-- Días -->\r\n <div class=\"calendar-grid\">\r\n @for (day of calendarDays(); track $index) {\r\n <div\r\n class=\"calendar-day\"\r\n [class.selected]=\"isDaySelected(day)\"\r\n [class.today]=\"isToday(day)\"\r\n [class.disabled]=\"isDayDisabled(day)\"\r\n [class.empty]=\"!day\"\r\n (click)=\"selectDay(day)\"\r\n >\r\n {{ day || \"\" }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- TIME PICKER -->\r\n @if (mode() === 'datetime') {\r\n <div class=\"time-section\">\r\n <div class=\"time-header\">Horario</div>\r\n\r\n <div class=\"time-selectors\">\r\n <div class=\"time-group\">\r\n <div class=\"time-column\">\r\n <div class=\"time-label\">Hora</div>\r\n <div class=\"time-scroll\">\r\n @for (hour of hours12(); track hour.value) {\r\n <div\r\n class=\"time-option\"\r\n [class.selected]=\"hour.value === selectedHour12()\"\r\n (click)=\"setHour12(hour.value)\"\r\n >\r\n {{ hour.display }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"time-separator-vertical\">:</div>\r\n\r\n <div class=\"time-column\">\r\n <div class=\"time-label\">Min</div>\r\n <div class=\"time-scroll\">\r\n @for (minute of minutes(); track minute) {\r\n <div\r\n class=\"time-option\"\r\n [class.selected]=\"minute === selectedMinute()\"\r\n (click)=\"setMinute(minute)\"\r\n >\r\n {{ minute.toString().padStart(2, \"0\") }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"time-column\">\r\n <div class=\"time-label\">AM/PM</div>\r\n <div class=\"time-scroll ampm\">\r\n <div\r\n class=\"time-option\"\r\n [class.selected]=\"selectedAmPm() === 'AM'\"\r\n (click)=\"setAmPm('AM')\"\r\n >\r\n AM\r\n </div>\r\n <div\r\n class=\"time-option\"\r\n [class.selected]=\"selectedAmPm() === 'PM'\"\r\n (click)=\"setAmPm('PM')\"\r\n >\r\n PM\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- botones -->\r\n <div class=\"action-buttons\">\r\n <button type=\"button\" class=\"action-btn secondary\" (click)=\"today()\">\r\n Hoy\r\n </button>\r\n\r\n @if (mode() === 'datetime') {\r\n <button type=\"button\" class=\"action-btn primary\" (click)=\"close()\">\r\n Aceptar\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n }\r\n</div>\r\n","import { Component, Input, Output, EventEmitter, computed, signal } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n@Component({\r\n selector: 'app-pagination',\r\n standalone: true,\r\n imports: [CommonModule],\r\n templateUrl: './pagination.html',\r\n styleUrls: ['./pagination.css']\r\n})\r\nexport class PaginationComponent {\r\n @Input() page = 1;\r\n @Input() pageSize = 10;\r\n @Input() totalItems = 0;\r\n\r\n @Input() showPageSizeSelector = false;\r\n @Input() pageSizeOptions: number[] = [5, 10, 20, 50];\r\n\r\n @Output() pageChange = new EventEmitter<number>();\r\n @Output() pageSizeChange = new EventEmitter<number>();\r\n\r\n pageSizeValue = signal(this.pageSize);\r\n isOpen = signal(false);\r\n isDisabled = signal(false);\r\n showPageSizeMenu = signal(false);\r\n\r\n totalPages = computed(() => {\r\n const size = this.pageSizeValue();\r\n const total = this.totalItems;\r\n return size > 0 ? Math.ceil(total / size) : 1;\r\n });\r\n\r\n pages = computed(() => {\r\n const tp = this.totalPages();\r\n return Array.from({ length: tp }, (_, i) => i + 1);\r\n });\r\n\r\n selectedPageSize = computed(() => this.pageSizeValue());\r\n\r\n goToPage(p: number) {\r\n if (p < 1 || p > this.totalPages()) return;\r\n this.pageChange.emit(p);\r\n }\r\n\r\n togglePageSizeMenu() {\r\n this.isOpen.update(v => !v);\r\n this.showPageSizeMenu.update(v => !v);\r\n }\r\n\r\n selectPageSize(size: number) {\r\n this.pageSizeValue.set(size);\r\n this.pageSizeChange.emit(size);\r\n this.showPageSizeMenu.set(false);\r\n this.isOpen.set(false);\r\n }\r\n}\r\n","<div class=\"pagination-container\">\r\n <div class=\"pagination\">\r\n <!-- Botón doble atrás -->\r\n <button class=\"icon-button\" (click)=\"goToPage(1)\" [disabled]=\"page === 1\">\r\n ««\r\n </button>\r\n\r\n <!-- Botón atrás -->\r\n <button class=\"icon-button\" (click)=\"goToPage(page - 1)\" [disabled]=\"page === 1\">\r\n «\r\n </button>\r\n\r\n <!-- Números de página -->\r\n <div class=\"pages\">\r\n <button\r\n class=\"page-btn\"\r\n *ngFor=\"let p of pages(); let idx = index\"\r\n [class.active]=\"page === idx + 1\"\r\n (click)=\"goToPage(idx + 1)\"\r\n >\r\n {{ idx + 1 }}\r\n </button>\r\n </div>\r\n\r\n <!-- Botón siguiente -->\r\n <button class=\"icon-button\" (click)=\"goToPage(page + 1)\" [disabled]=\"page === totalPages()\">\r\n »\r\n </button>\r\n\r\n <!-- Botón doble adelante -->\r\n <button class=\"icon-button\" (click)=\"goToPage(totalPages())\" [disabled]=\"page === totalPages()\">\r\n »»\r\n </button>\r\n </div>\r\n\r\n <!-- Selector Items por página -->\r\n <div *ngIf=\"showPageSizeSelector\">\r\n <div class=\"pagination-v-4\">\r\n <div class=\"label-pagination\">Items por página</div>\r\n <div class=\"elements-pagination\">\r\n <div class=\"split-button\" (click)=\"togglePageSizeMenu()\">\r\n <div class=\"leading-button\">\r\n <div class=\"state-layer\">\r\n <div class=\"label\">{{ pageSizeValue() }}</div>\r\n </div>\r\n </div>\r\n <div class=\"trailing-button\">\r\n <div class=\"arrow\" [class.open]=\"isOpen()\">\r\n <svg class=\"arrow\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\">\r\n <polyline points=\"6 9 12 15 18 9\"></polyline>\r\n </svg>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Menú desplegable -->\r\n <div class=\"page-size-menu\" *ngIf=\"showPageSizeMenu()\">\r\n <div\r\n class=\"menu-option\"\r\n *ngFor=\"let opt of pageSizeOptions\"\r\n [class.active]=\"opt === pageSizeValue()\"\r\n (click)=\"selectPageSize(opt)\"\r\n >\r\n {{ opt }}\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n","import { Component, HostListener, input, output, signal } from '@angular/core';\r\nimport { TableAction, TableColumn, TableRow } from '../../interfaces/table';\r\n\r\n@Component({\r\n selector: 'lib-table',\r\n imports: [],\r\n standalone: true,\r\n templateUrl: './table.html',\r\n styleUrl: './table.css',\r\n})\r\nexport class Table {\r\n columns = input<TableColumn[]>([]);\r\n data = input<TableRow[]>([]);\r\n actions = input<TableAction[]>([]);\r\n\r\n openedMenu = signal<number | null>(null);\r\n selectedRow = signal<TableRow | null>(null);\r\n \r\n optionSelected = output<{ action: string; row: TableRow }>();\r\n\r\n toggleMenu(index: number) {\r\n this.openedMenu.set(this.openedMenu() === index ? null : index);\r\n }\r\n\r\n onOptionClick(option: TableAction, row: TableRow) {\r\n this.optionSelected.emit({ action: option.label, row });\r\n this.openedMenu.set(null);\r\n }\r\n\r\n openModal(row: TableRow, event?: MouseEvent) {\r\n event?.stopPropagation();\r\n\r\n if (this.selectedRow()?.['id'] === row['id']) {\r\n this.selectedRow.set(null);\r\n } else {\r\n this.selectedRow.set(row);\r\n }\r\n }\r\n\r\n @HostListener('document:click', ['$event'])\r\n onClickOutside(event: MouseEvent) {\r\n const target = event.target as HTMLElement;\r\n if (!target.closest('.menu-acciones')) {\r\n this.selectedRow.set(null);\r\n }\r\n }\r\n}\r\n","<div class=\"table-wrapper\">\r\n <table class=\"inner-table\">\r\n <thead>\r\n <tr>\r\n @for (col of columns(); track col.key) {\r\n <th>{{ col.label }}</th>\r\n }\r\n\r\n <!-- columna para acciones -->\r\n <th></th>\r\n </tr>\r\n </thead>\r\n\r\n <tbody>\r\n @for (row of data(); track $index) {\r\n <tr>\r\n @for (col of columns(); track col.key) {\r\n <td>{{ row[col.key] }}</td>\r\n }\r\n\r\n <!-- Celda de acciones -->\r\n <td class=\"acciones-cell\">\r\n <div class=\"menu-acciones\">\r\n <button class=\"icon-button\" (click)=\"openModal(row)\">\r\n <div class=\"content\">\r\n <div class=\"state-layer\">\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n class=\"more-vert\"\r\n width=\"20\"\r\n height=\"20\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n >\r\n <circle cx=\"12\" cy=\"5\" r=\"1\" />\r\n <circle cx=\"12\" cy=\"12\" r=\"1\" />\r\n <circle cx=\"12\" cy=\"19\" r=\"1\" />\r\n </svg>\r\n </div>\r\n </div>\r\n </button>\r\n @if(selectedRow()?.['id'] === row['id']){\r\n <div class=\"modal-options\" (click)=\"$event.stopPropagation()\">\r\n \r\n <div class=\"modal-content\">\r\n <ul>\r\n @for (option of actions(); track $index) {\r\n <li\r\n class=\"option-item\"\r\n [style.color]=\"option.color\"\r\n (click)=\"onOptionClick(option, row)\"\r\n >\r\n <span class=\"icon\" [class]=\"option.icon\"></span>\r\n <span class=\"label\">{{ option.label }}</span>\r\n </li>\r\n }\r\n </ul>\r\n </div>\r\n \r\n </div>\r\n }\r\n </div>\r\n </td>\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n</div>","// src/app/components/public-api.ts\r\n\r\n// Exportar el componente\r\nexport * from './lib/components/date-time-filter/date-time-filter';\r\nexport * from './lib/components/pagination/pagination';\r\nexport * from './lib/components/table/table';\r\n\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
package/index.d.ts CHANGED
@@ -1,9 +1,97 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { EventEmitter } from '@angular/core';
2
+ import { OnDestroy, ElementRef, NgZone, EventEmitter } from '@angular/core';
3
+ import { ControlValueAccessor } from '@angular/forms';
3
4
 
4
- declare class MyComponent {
5
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<MyComponent, never>;
6
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<MyComponent, "lib-my-component", never, {}, {}, never, never, true, never>;
5
+ interface FilterOption {
6
+ label: string;
7
+ value: string;
8
+ type: 'date';
9
+ }
10
+ interface DateFilterSelection {
11
+ filter: string;
12
+ value: Date;
13
+ }
14
+ type DateTimeMode = 'date' | 'datetime';
15
+ interface Hour12 {
16
+ value: number;
17
+ display: string;
18
+ }
19
+ type FilterType = DateTimeMode;
20
+ declare class DateTimeFilter implements ControlValueAccessor, OnDestroy {
21
+ private elementRef;
22
+ private ngZone;
23
+ mode: _angular_core.InputSignal<DateTimeMode>;
24
+ placeholder: _angular_core.InputSignal<string>;
25
+ minDate: _angular_core.InputSignal<Date | null>;
26
+ maxDate: _angular_core.InputSignal<Date | null>;
27
+ filter: _angular_core.InputSignal<string>;
28
+ dateSelected: _angular_core.OutputEmitterRef<DateFilterSelection>;
29
+ filters: FilterOption[];
30
+ dateChange: _angular_core.OutputEmitterRef<Date | null>;
31
+ isOpen: _angular_core.WritableSignal<boolean>;
32
+ selectedDate: _angular_core.WritableSignal<Date | null>;
33
+ isDisabled: _angular_core.WritableSignal<boolean>;
34
+ isTouched: _angular_core.WritableSignal<boolean>;
35
+ currentMonth: _angular_core.WritableSignal<number>;
36
+ currentYear: _angular_core.WritableSignal<number>;
37
+ selectedHour: _angular_core.WritableSignal<number>;
38
+ selectedMinute: _angular_core.WritableSignal<number>;
39
+ selectedAmPm: _angular_core.WritableSignal<"AM" | "PM">;
40
+ private documentClickListener?;
41
+ showFilters: boolean;
42
+ showDatePicker: boolean;
43
+ activeFilterType: string | null;
44
+ selectDate(date: Date): void;
45
+ getDatePickerMode(type: FilterType): DateTimeMode;
46
+ displayValue: _angular_core.Signal<string>;
47
+ monthName: _angular_core.Signal<string>;
48
+ calendarDays: _angular_core.Signal<(number | null)[]>;
49
+ hours12: _angular_core.Signal<Hour12[]>;
50
+ selectedHour12: _angular_core.Signal<number>;
51
+ minutes: _angular_core.Signal<number[]>;
52
+ private onChange;
53
+ private onTouched;
54
+ constructor(elementRef: ElementRef, ngZone: NgZone);
55
+ ngOnDestroy(): void;
56
+ writeValue(value: string | Date | null): void;
57
+ registerOnChange(fn: (value: string | null) => void): void;
58
+ registerOnTouched(fn: () => void): void;
59
+ setDisabledState(isDisabled: boolean): void;
60
+ toggle(): void;
61
+ open(): void;
62
+ close(): void;
63
+ selectDay(day: number | null): void;
64
+ setHour12(hour12: number): void;
65
+ setMinute(minute: number): void;
66
+ setAmPm(amPm: 'AM' | 'PM'): void;
67
+ previousMonth(): void;
68
+ nextMonth(): void;
69
+ previousYear(): void;
70
+ nextYear(): void;
71
+ today(): void;
72
+ clear(): void;
73
+ onKeyDown(event: KeyboardEvent): void;
74
+ isDaySelected(day: number | null): boolean;
75
+ isToday(day: number | null): boolean;
76
+ isDayDisabled(day: number | null): boolean;
77
+ isDateDisabled(date: Date): boolean;
78
+ private updateDateTime;
79
+ private markAsTouched;
80
+ private addDocumentListener;
81
+ private removeDocumentListener;
82
+ markTouched(): void;
83
+ /**
84
+ * Obtiene la fecha seleccionada en formato ISO string
85
+ * @returns string ISO o null si no hay fecha seleccionada
86
+ */
87
+ getISOString(): string | null;
88
+ /**
89
+ * Establece la fecha desde un string ISO
90
+ * @param isoString - Fecha en formato ISO
91
+ */
92
+ setFromISOString(isoString: string | null): void;
93
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DateTimeFilter, never>;
94
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DateTimeFilter, "app-date-time-filter", never, { "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "minDate": { "alias": "minDate"; "required": false; "isSignal": true; }; "maxDate": { "alias": "maxDate"; "required": false; "isSignal": true; }; "filter": { "alias": "filter"; "required": true; "isSignal": true; }; }, { "dateSelected": "dateSelected"; "dateChange": "dateChange"; }, never, never, true, never>;
7
95
  }
8
96
 
9
97
  declare class PaginationComponent {
@@ -59,4 +147,5 @@ declare class Table {
59
147
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<Table, "lib-table", never, { "columns": { "alias": "columns"; "required": false; "isSignal": true; }; "data": { "alias": "data"; "required": false; "isSignal": true; }; "actions": { "alias": "actions"; "required": false; "isSignal": true; }; }, { "optionSelected": "optionSelected"; }, never, never, true, never>;
60
148
  }
61
149
 
62
- export { MyComponent, PaginationComponent, Table };
150
+ export { DateTimeFilter, PaginationComponent, Table };
151
+ export type { DateFilterSelection, DateTimeMode, FilterOption, FilterType };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sapenlinea-components",
3
- "version": "0.0.9",
3
+ "version": "0.0.10",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^20.3.0",
6
6
  "@angular/core": "^20.3.0"