shirkasoft-ui-components 1.3.7 → 1.3.9

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.
Files changed (32) hide show
  1. package/README.md +38 -13
  2. package/fesm2022/shirkasoft-ui-components-button.mjs +2 -2
  3. package/fesm2022/shirkasoft-ui-components-button.mjs.map +1 -1
  4. package/fesm2022/shirkasoft-ui-components-confirm-dialog.mjs +2 -2
  5. package/fesm2022/shirkasoft-ui-components-confirm-dialog.mjs.map +1 -1
  6. package/fesm2022/shirkasoft-ui-components-date-picker.mjs +90 -9
  7. package/fesm2022/shirkasoft-ui-components-date-picker.mjs.map +1 -1
  8. package/fesm2022/shirkasoft-ui-components-loading.mjs +2 -2
  9. package/fesm2022/shirkasoft-ui-components-loading.mjs.map +1 -1
  10. package/fesm2022/shirkasoft-ui-components-modal.mjs +2 -2
  11. package/fesm2022/shirkasoft-ui-components-modal.mjs.map +1 -1
  12. package/fesm2022/shirkasoft-ui-components-notification.mjs +2 -2
  13. package/fesm2022/shirkasoft-ui-components-notification.mjs.map +1 -1
  14. package/fesm2022/shirkasoft-ui-components-price-input.mjs +2 -2
  15. package/fesm2022/shirkasoft-ui-components-price-input.mjs.map +1 -1
  16. package/fesm2022/shirkasoft-ui-components-select.mjs +2 -2
  17. package/fesm2022/shirkasoft-ui-components-select.mjs.map +1 -1
  18. package/fesm2022/shirkasoft-ui-components-table.mjs +198 -12
  19. package/fesm2022/shirkasoft-ui-components-table.mjs.map +1 -1
  20. package/fesm2022/shirkasoft-ui-components-tabs.mjs +7 -12
  21. package/fesm2022/shirkasoft-ui-components-tabs.mjs.map +1 -1
  22. package/fesm2022/shirkasoft-ui-components-tag.mjs +3 -3
  23. package/fesm2022/shirkasoft-ui-components-tag.mjs.map +1 -1
  24. package/fesm2022/shirkasoft-ui-components-text-field.mjs +2 -2
  25. package/fesm2022/shirkasoft-ui-components-text-field.mjs.map +1 -1
  26. package/fesm2022/shirkasoft-ui-components-toggle.mjs +61 -24
  27. package/fesm2022/shirkasoft-ui-components-toggle.mjs.map +1 -1
  28. package/package.json +2 -2
  29. package/src/theme.css +80 -0
  30. package/types/shirkasoft-ui-components-date-picker.d.ts +24 -4
  31. package/types/shirkasoft-ui-components-table.d.ts +86 -9
  32. package/types/shirkasoft-ui-components-toggle.d.ts +7 -1
@@ -18,6 +18,22 @@ import { TranslocoService } from '@jsverse/transloco';
18
18
  * min/max constraints and locale-aware labels.
19
19
  */
20
20
  class DatePickerComponent {
21
+ /** Localized range label for a week (e.g. '2 — 8 feb'). */
22
+ formatWeekRange(start, end) {
23
+ const loc = this.locale();
24
+ const dayFmt = new Intl.DateTimeFormat(loc, { day: 'numeric' });
25
+ const monthFmt = new Intl.DateTimeFormat(loc, { month: 'short' });
26
+ const startLabel = `${dayFmt.format(start)} ${monthFmt.format(start).replace('.', '')}`;
27
+ if (start.getMonth() !== end.getMonth() || start.getFullYear() !== end.getFullYear()) {
28
+ const year = start.getFullYear() !== end.getFullYear() ? ` ${end.getFullYear()}` : '';
29
+ return `${startLabel} — ${dayFmt.format(end)} ${monthFmt.format(end).replace('.', '')}${year}`;
30
+ }
31
+ return `${startLabel} — ${dayFmt.format(end)}`;
32
+ }
33
+ /** Localized label for a week row ('Semana N' / 'Week N'). */
34
+ weekLabel(index) {
35
+ return this.locale() === 'en' ? `Week ${index}` : `Semana ${index}`;
36
+ }
21
37
  constructor() {
22
38
  this.elementRef = inject(ElementRef);
23
39
  this.cdr = inject(ChangeDetectorRef);
@@ -25,8 +41,10 @@ class DatePickerComponent {
25
41
  this.transloco = inject(TranslocoService);
26
42
  /** HTML id for the input (for label/for pairing). */
27
43
  this.id = input('', ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
28
- /** Granularity of the picker ('date' | 'month' | 'year'). */
44
+ /** Granularity of the picker ('date' | 'week' | 'month' | 'year'). */
29
45
  this.view = input('date', ...(ngDevMode ? [{ debugName: "view" }] : /* istanbul ignore next */ []));
46
+ /** First day of the week (0=Sunday ... 6=Saturday), used by week view. */
47
+ this.weekStart = input(0, ...(ngDevMode ? [{ debugName: "weekStart" }] : /* istanbul ignore next */ []));
30
48
  /** Label shown above the input. */
31
49
  this.label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
32
50
  /** Placeholder of the input. */
@@ -188,6 +206,10 @@ class DatePickerComponent {
188
206
  label = fmt.format(new Date(y, m - 1, 1));
189
207
  label = label.charAt(0).toUpperCase() + label.slice(1);
190
208
  }
209
+ else if (v === 'week') {
210
+ const start = new Date(datePart + 'T12:00:00');
211
+ label = this.formatWeekRange(start, new Date(start.getFullYear(), start.getMonth(), start.getDate() + 6));
212
+ }
191
213
  else {
192
214
  const fmt = new Intl.DateTimeFormat(this.locale(), {
193
215
  dateStyle: 'long',
@@ -234,11 +256,31 @@ class DatePickerComponent {
234
256
  days.push(i);
235
257
  return days;
236
258
  }, ...(ngDevMode ? [{ debugName: "calendarDays" }] : /* istanbul ignore next */ []));
259
+ /** Weeks of the viewed month (rows aligned to `weekStart`), for week view. */
260
+ this.monthWeeks = computed(() => {
261
+ const year = this.viewYear();
262
+ const month = this.viewMonth();
263
+ const ws = this.weekStart();
264
+ const first = new Date(year, month, 1);
265
+ const last = new Date(year, month + 1, 0);
266
+ const anchor = new Date(first.getFullYear(), first.getMonth(), first.getDate() - ((first.getDay() - ws + 7) % 7));
267
+ const weeks = [];
268
+ let cursor = anchor;
269
+ let index = 0;
270
+ while (cursor.getTime() <= last.getTime()) {
271
+ index++;
272
+ const start = cursor;
273
+ const end = new Date(start.getFullYear(), start.getMonth(), start.getDate() + 6);
274
+ weeks.push({ index, start, end, range: this.formatWeekRange(start, end) });
275
+ cursor = new Date(start.getFullYear(), start.getMonth(), start.getDate() + 7);
276
+ }
277
+ return weeks;
278
+ }, ...(ngDevMode ? [{ debugName: "monthWeeks" }] : /* istanbul ignore next */ []));
237
279
  /** Whether the prev navigation button is allowed by `minValue`. */
238
280
  this.canGoPrev = computed(() => {
239
281
  const v = this.currentView();
240
282
  const min = this.minValue();
241
- if (v === 'date') {
283
+ if (v === 'date' || v === 'week') {
242
284
  if (!min)
243
285
  return true;
244
286
  const prev = new Date(this.viewYear(), this.viewMonth() - 1, 1);
@@ -256,7 +298,7 @@ class DatePickerComponent {
256
298
  this.canGoNext = computed(() => {
257
299
  const v = this.currentView();
258
300
  const max = this.maxValue();
259
- if (v === 'date') {
301
+ if (v === 'date' || v === 'week') {
260
302
  if (!max)
261
303
  return true;
262
304
  const next = new Date(this.viewYear(), this.viewMonth() + 1, 1);
@@ -367,7 +409,7 @@ class DatePickerComponent {
367
409
  }
368
410
  else {
369
411
  this.syncViewToValue();
370
- this.currentView.set('year');
412
+ this.currentView.set(this.view() === 'week' ? 'week' : 'year');
371
413
  this.selectedYearValue.set(null);
372
414
  this.selectedMonthValue.set(null);
373
415
  this.clockMode.set('hours');
@@ -399,6 +441,11 @@ class DatePickerComponent {
399
441
  else if (v === 'month') {
400
442
  this.viewYear.set(Number(datePart.split('-')[0]));
401
443
  }
444
+ else if (v === 'week') {
445
+ const d = new Date(datePart + 'T12:00:00');
446
+ this.viewYear.set(d.getFullYear());
447
+ this.viewMonth.set(d.getMonth());
448
+ }
402
449
  else {
403
450
  const d = new Date(datePart + 'T12:00:00');
404
451
  this.viewYear.set(d.getFullYear());
@@ -494,7 +541,17 @@ class DatePickerComponent {
494
541
  }
495
542
  this.setValue(value);
496
543
  }
497
- /** Commits a value, updates the component, the control and the outputs. */
544
+ /** Selects a week - emits its start date (YYYY-MM-DD). */
545
+ selectWeek(start) {
546
+ const value = `${start.getFullYear()}-` +
547
+ `${String(start.getMonth() + 1).padStart(2, '0')}-` +
548
+ `${String(start.getDate()).padStart(2, '0')}`;
549
+ if (this.showTime()) {
550
+ this.pendingDate.set(value);
551
+ return;
552
+ }
553
+ this.setValue(value);
554
+ }
498
555
  setValue(value, close = true) {
499
556
  this._value.set(value);
500
557
  this.onChange(value);
@@ -761,6 +818,9 @@ class DatePickerComponent {
761
818
  return 'YYYY';
762
819
  if (this.view() === 'month')
763
820
  return 'MM/YYYY';
821
+ if (this.view() === 'week') {
822
+ return this.locale() === 'en' ? 'Week · MM/YYYY' : 'Semana · MM/YYYY';
823
+ }
764
824
  return this.inputFormat();
765
825
  }
766
826
  /** Handles text input in the date field. */
@@ -817,6 +877,8 @@ class DatePickerComponent {
817
877
  if (this.timeOnly()) {
818
878
  return this.parseTimeOnly(clean);
819
879
  }
880
+ if (this.view() === 'week')
881
+ return null;
820
882
  if (this.view() === 'year') {
821
883
  const y = Number(parts[0]);
822
884
  if (parts.length === 1 && y >= 1900 && y <= 2100)
@@ -899,6 +961,25 @@ class DatePickerComponent {
899
961
  this.viewMonth() === now.getMonth() &&
900
962
  day === now.getDate());
901
963
  }
964
+ /** ISO date (YYYY-MM-DD) of the week start containing the given date. */
965
+ weekStartISO(date) {
966
+ const ws = this.weekStart();
967
+ const start = new Date(date.getFullYear(), date.getMonth(), date.getDate() - ((date.getDay() - ws + 7) % 7));
968
+ return (`${start.getFullYear()}-` +
969
+ `${String(start.getMonth() + 1).padStart(2, '0')}-` +
970
+ `${String(start.getDate()).padStart(2, '0')}`);
971
+ }
972
+ /** Whether the given week row contains the displayed/selected date. */
973
+ isSelectedWeek(start) {
974
+ const date = this.displayedDate();
975
+ if (!date)
976
+ return false;
977
+ return this.weekStartISO(new Date(date + 'T12:00:00')) === this.weekStartISO(start);
978
+ }
979
+ /** Whether the given week row contains today's date. */
980
+ isCurrentWeek(start) {
981
+ return this.weekStartISO(new Date()) === this.weekStartISO(start);
982
+ }
902
983
  /** Whether the given month matches the selected month and year. */
903
984
  isSelectedMonth(monthIndex) {
904
985
  return this.selectedMonthValue() === monthIndex;
@@ -927,13 +1008,13 @@ class DatePickerComponent {
927
1008
  this.cdr.markForCheck();
928
1009
  }
929
1010
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: DatePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
930
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.23", type: DatePickerComponent, isStandalone: true, selector: "shk-date-picker", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, formGroup: { classPropertyName: "formGroup", publicName: "formGroup", isSignal: true, isRequired: false, transformFunction: null }, control: { classPropertyName: "control", publicName: "control", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, errorMessages: { classPropertyName: "errorMessages", publicName: "errorMessages", isSignal: true, isRequired: false, transformFunction: null }, minValue: { classPropertyName: "minValue", publicName: "minValue", isSignal: true, isRequired: false, transformFunction: null }, maxValue: { classPropertyName: "maxValue", publicName: "maxValue", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, timeOnly: { classPropertyName: "timeOnly", publicName: "timeOnly", isSignal: true, isRequired: false, transformFunction: null }, showTime: { classPropertyName: "showTime", publicName: "showTime", isSignal: true, isRequired: false, transformFunction: null }, hourFormat: { classPropertyName: "hourFormat", publicName: "hourFormat", isSignal: true, isRequired: false, transformFunction: null }, showSeconds: { classPropertyName: "showSeconds", publicName: "showSeconds", isSignal: true, isRequired: false, transformFunction: null }, minuteStep: { classPropertyName: "minuteStep", publicName: "minuteStep", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:click": "onDocumentClick($event)", "document:keydown.escape": "onEscape()" } }, providers: [
1011
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.23", type: DatePickerComponent, isStandalone: true, selector: "shk-date-picker", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null }, weekStart: { classPropertyName: "weekStart", publicName: "weekStart", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, formGroup: { classPropertyName: "formGroup", publicName: "formGroup", isSignal: true, isRequired: false, transformFunction: null }, control: { classPropertyName: "control", publicName: "control", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, errorMessages: { classPropertyName: "errorMessages", publicName: "errorMessages", isSignal: true, isRequired: false, transformFunction: null }, minValue: { classPropertyName: "minValue", publicName: "minValue", isSignal: true, isRequired: false, transformFunction: null }, maxValue: { classPropertyName: "maxValue", publicName: "maxValue", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, timeOnly: { classPropertyName: "timeOnly", publicName: "timeOnly", isSignal: true, isRequired: false, transformFunction: null }, showTime: { classPropertyName: "showTime", publicName: "showTime", isSignal: true, isRequired: false, transformFunction: null }, hourFormat: { classPropertyName: "hourFormat", publicName: "hourFormat", isSignal: true, isRequired: false, transformFunction: null }, showSeconds: { classPropertyName: "showSeconds", publicName: "showSeconds", isSignal: true, isRequired: false, transformFunction: null }, minuteStep: { classPropertyName: "minuteStep", publicName: "minuteStep", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:click": "onDocumentClick($event)", "document:keydown.escape": "onEscape()" } }, providers: [
931
1012
  {
932
1013
  provide: NG_VALUE_ACCESSOR,
933
1014
  useExisting: forwardRef(() => DatePickerComponent),
934
1015
  multi: true,
935
1016
  },
936
- ], ngImport: i0, template: "<div class=\"relative mb-4\">\n @if (label()) {\n <div class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)] mb-1\">\n {{ label() }}\n </div>\n }\n\n <div class=\"relative\">\n <div class=\"relative\">\n <input\n [id]=\"id()\"\n type=\"text\"\n [disabled]=\"isDisabled()\"\n [placeholder]=\"inputPlaceholder()\"\n [value]=\"isTyping() ? typedValue() : displayLabel()\"\n (input)=\"onInputText($event)\"\n (focus)=\"onInputFocus()\"\n (blur)=\"onInputBlur()\"\n (keydown.enter)=\"$any($event.target).blur()\"\n (keydown.escape)=\"cancelTyping()\"\n (click)=\"toggle()\"\n class=\"date-input-field\"\n [ngClass]=\"{\n 'input-error': shouldShowError() || typingValid() === false,\n 'input-valid': wasFixedError() || typingValid() === true,\n }\"\n [attr.aria-invalid]=\"shouldShowError()\"\n [attr.aria-describedby]=\"shouldShowError() ? id() + '-error' : null\"\n />\n <button\n type=\"button\"\n [disabled]=\"isDisabled()\"\n (click)=\"toggle()\"\n class=\"absolute right-2 top-1/2 -translate-y-1/2 p-1 _shk-text-surface-400 dark:[color:var(--shk-surface-400)] hover:[color:var(--shk-surface-600)] dark:hover:[color:var(--shk-surface-300)] transition-colors\"\n >\n <svg\n class=\"w-4 h-4\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\"></rect>\n <path d=\"M16 2v4M8 2v4M3 10h18\"></path>\n </svg>\n </button>\n </div>\n\n @if (isOpen()) {\n <div class=\"fixed inset-0 z-40 bg-black/30\" (click)=\"close()\"></div>\n <div\n class=\"fixed z-50 top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-72 p-4 bg-white dark:[background-color:var(--shk-surface-100)] _shk-border dark:[border-color:var(--shk-surface-200)] rounded-lg shadow-xl\"\n (click)=\"$event.stopPropagation()\"\n >\n <!-- DATE VIEW -->\n @if (!timeOnly() && currentView() === 'date') {\n <div class=\"flex items-center justify-between mb-3\">\n <button\n type=\"button\"\n (click)=\"drillUp()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M15 18l-6-6 6-6\"></path>\n </svg>\n </button>\n <span class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)]\">\n {{ monthNames()[viewMonth()] }} {{ selectedYearValue() ?? viewYear() }}\n </span>\n <button\n type=\"button\"\n (click)=\"drillToInitial()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M9 18l6-6-6-6\"></path>\n </svg>\n </button>\n </div>\n\n <div class=\"grid grid-cols-7 gap-0 mb-1\">\n @for (name of dayNames(); track $index) {\n <div class=\"text-center text-xs font-medium _shk-text-surface-400 dark:[color:var(--shk-surface-400)] py-1\">\n {{ name }}\n </div>\n }\n </div>\n\n <div class=\"grid grid-cols-7 gap-0\">\n @for (day of calendarDays(); track $index) {\n @if (day !== null) {\n <button\n type=\"button\"\n (click)=\"selectDay(day)\"\n class=\"py-1.5 text-sm rounded transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white hover:[background-color:var(--shk-primary-700)]': isSelectedDay(day),\n 'ring-1 [--tw-ring-color:var(--shk-primary-500)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]': isToday(day) && !isSelectedDay(day),\n '_shk-text-surface-700 dark:[color:var(--shk-surface-700)] hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': !isSelectedDay(day) && !isToday(day),\n }\"\n >\n {{ day }}\n </button>\n } @else {\n <div></div>\n }\n }\n </div>\n }\n\n <!-- MONTH VIEW -->\n @if (!timeOnly() && currentView() === 'month') {\n <div class=\"flex items-center justify-between mb-3\">\n <button\n type=\"button\"\n (click)=\"drillUp()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M15 18l-6-6 6-6\"></path>\n </svg>\n </button>\n <span class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)]\">\n {{ selectedYearValue() ?? viewYear() }}\n </span>\n <button\n type=\"button\"\n (click)=\"drillToInitial()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M9 18l6-6-6-6\"></path>\n </svg>\n </button>\n </div>\n\n <div class=\"grid grid-cols-3 gap-1\">\n @for (name of monthNames(); track $index) {\n <button\n type=\"button\"\n (click)=\"selectMonth($index)\"\n class=\"py-2 text-sm rounded transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white hover:[background-color:var(--shk-primary-700)]': selectedMonthValue() === $index,\n 'ring-1 [--tw-ring-color:var(--shk-primary-500)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]': isCurrentMonth($index) && selectedMonthValue() !== $index,\n '_shk-text-surface-700 dark:[color:var(--shk-surface-700)] hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': selectedMonthValue() !== $index && !isCurrentMonth($index),\n }\"\n >\n {{ name }}\n </button>\n }\n </div>\n }\n\n <!-- YEAR VIEW -->\n @if (!timeOnly() && currentView() === 'year') {\n <div class=\"flex items-center justify-between mb-3\">\n <button\n type=\"button\"\n (click)=\"prev()\"\n [disabled]=\"!canGoPrev()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M15 18l-6-6 6-6\"></path>\n </svg>\n </button>\n <span class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)]\">\n {{ viewDecade() }} - {{ viewDecade() + 11 }}\n </span>\n <button\n type=\"button\"\n (click)=\"next()\"\n [disabled]=\"!canGoNext()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M9 18l6-6-6-6\"></path>\n </svg>\n </button>\n </div>\n\n <div class=\"grid grid-cols-3 gap-1\">\n @for (year of decadeYears(); track year) {\n <button\n type=\"button\"\n (click)=\"selectYear(year)\"\n class=\"py-2 text-sm rounded transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white hover:[background-color:var(--shk-primary-700)]': selectedYearValue() === year,\n 'ring-1 [--tw-ring-color:var(--shk-primary-500)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]': isCurrentYear(year) && selectedYearValue() !== year,\n '_shk-text-surface-700 dark:[color:var(--shk-surface-700)] hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': selectedYearValue() !== year && !isCurrentYear(year),\n }\"\n >\n {{ year }}\n </button>\n }\n </div>\n }\n\n <!-- ANALOG CLOCK TIME PICKER -->\n @if (timeOnly() || showTime()) {\n <div class=\"mt-3 pt-3 _shk-border dark:[border-color:var(--shk-surface-200)]\">\n <!-- Clock display time -->\n <div class=\"text-center mb-2\">\n <span class=\"text-lg font-semibold _shk-text-surface-700 dark:[color:var(--shk-surface-700)]\">\n {{ clockDisplayTime() }}\n </span>\n </div>\n\n <!-- Analog clock face -->\n <div class=\"clock-container\">\n <svg\n viewBox=\"0 0 200 200\"\n class=\"w-full h-full cursor-pointer\"\n (click)=\"onClockClick($event, clockMode())\"\n >\n <!-- Clock face background -->\n <circle cx=\"100\" cy=\"100\" r=\"96\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1\"\n class=\"_shk-text-surface-200 dark:[color:var(--shk-surface-200)]\" />\n\n <!-- Minute markers -->\n @if (clockMode() === 'minutes') {\n @for (i of [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59]; track i) {\n <line\n [attr.x1]=\"clockMinuteMarker(i).x1\"\n [attr.y1]=\"clockMinuteMarker(i).y1\"\n [attr.x2]=\"clockMinuteMarker(i).x2\"\n [attr.y2]=\"clockMinuteMarker(i).y2\"\n [attr.stroke-width]=\"i % 5 === 0 ? 2 : 1\"\n [class]=\"i % 5 === 0 ? '_shk-text-surface-500 dark:[color:var(--shk-surface-500)]' : '_shk-text-surface-300 dark:[color:var(--shk-surface-400)]'\"\n stroke=\"currentColor\"\n />\n }\n <!-- Minute numbers (00, 05, 10, ...) -->\n @for (m of [0,5,10,15,20,25,30,35,40,45,50,55]; track m) {\n <text\n [attr.x]=\"clockMinutePos(m).x\"\n [attr.y]=\"clockMinutePos(m).y\"\n text-anchor=\"middle\"\n dominant-baseline=\"central\"\n class=\"text-[9px] _shk-text-surface-500 dark:[color:var(--shk-surface-400)]\"\n [class._shk-text-primary]=\"viewMinute() === m\"\n >\n {{ m.toString().padStart(2, '0') }}\n </text>\n }\n }\n\n <!-- Hour numbers -->\n @if (clockMode() === 'hours') {\n @for (h of clockHours(); track h) {\n <text\n [attr.x]=\"clockNumberPos(h).x\"\n [attr.y]=\"clockNumberPos(h).y\"\n text-anchor=\"middle\"\n dominant-baseline=\"central\"\n class=\"text-sm font-medium\"\n [class._shk-text-primary]=\"isClockHourSelected(h)\"\n [class._shk-text-surface-700]=\"!isClockHourSelected(h)\"\n >\n {{ h }}\n </text>\n }\n }\n\n <!-- Clock hand -->\n <line\n x1=\"100\" y1=\"100\"\n [attr.x2]=\"clockHandLine(60).x2\"\n [attr.y2]=\"clockHandLine(60).y2\"\n class=\"_shk-text-primary\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n\n <!-- Center dot -->\n <circle cx=\"100\" cy=\"100\" r=\"4\" class=\"fill-current _shk-text-primary\" />\n </svg>\n </div>\n\n <!-- Mode toggle: Hours / Minutes -->\n <div class=\"clock-mode-toggle\">\n <button\n type=\"button\"\n (click)=\"clockMode.set('hours')\"\n class=\"clock-mode-btn\"\n [class.active]=\"clockMode() === 'hours'\"\n >\n {{ 'Horas' }}\n </button>\n <button\n type=\"button\"\n (click)=\"clockMode.set('minutes')\"\n class=\"clock-mode-btn\"\n [class.active]=\"clockMode() === 'minutes'\"\n >\n {{ 'Minutos' }}\n </button>\n </div>\n\n <!-- AM/PM toggle for 12h format -->\n @if (hourFormat() === '12') {\n <div class=\"flex items-center justify-center gap-2 mt-2\">\n <button\n type=\"button\"\n (click)=\"viewMeridiem.set('AM')\"\n class=\"px-3 py-1 text-xs font-medium rounded-full transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white': viewMeridiem() === 'AM',\n '_shk-text-surface-500 hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': viewMeridiem() !== 'AM'\n }\"\n >\n AM\n </button>\n <button\n type=\"button\"\n (click)=\"viewMeridiem.set('PM')\"\n class=\"px-3 py-1 text-xs font-medium rounded-full transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white': viewMeridiem() === 'PM',\n '_shk-text-surface-500 hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': viewMeridiem() !== 'PM'\n }\"\n >\n PM\n </button>\n </div>\n }\n\n <!-- Seconds selector (if enabled) -->\n @if (showSeconds()) {\n <div class=\"flex items-center justify-center gap-1 mt-2\">\n <span class=\"text-xs _shk-text-surface-400\">Seg:</span>\n <select\n class=\"px-2 py-1 text-xs _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] _shk-border dark:[border-color:var(--shk-surface-200)] rounded-md\"\n [value]=\"viewSecond()\"\n (change)=\"onSecondChange($event)\"\n aria-label=\"Segundos\"\n >\n @for (seconds of secondsRange(); track seconds) {\n <option [value]=\"seconds\">{{ minutesLabel(seconds) }}</option>\n }\n </select>\n </div>\n }\n\n <!-- Confirm button -->\n <button\n type=\"button\"\n (click)=\"confirmTime()\"\n class=\"mt-3 w-full py-2 text-sm _shk-bg-primary _shk-text-white rounded-lg hover:[background-color:var(--shk-primary-700)] transition-colors\"\n >\n {{ timeOnly() ? 'Confirmar' : 'Introducir hora' }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n\n @if (shouldShowError()) {\n <div [id]=\"id() + '-error'\" class=\"mt-1 text-xs text-red-500 max-h-20 overflow-y-auto _shk-scrollbar\">\n <ul class=\"list-disc pl-4 space-y-1\">\n @for (error of getErrorMessages(); track error) {\n <li>{{ error }}</li>\n }\n </ul>\n </div>\n }\n</div>\n", styles: [".clock-container{position:relative;width:200px;height:200px;margin:0 auto}.clock-face{width:100%;height:100%;border-radius:50%;border:2px solid var(--shk-surface-200);position:relative;background-color:var(--shk-surface-50)}.dark .clock-face{border-color:var(--shk-surface-200);background-color:var(--shk-surface-100)}.clock-number{position:absolute;width:32px;height:32px;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:500;border-radius:50%;transform:translate(-50%,-50%);cursor:pointer;transition:background-color .15s,color .15s;-webkit-user-select:none;user-select:none;color:var(--shk-surface-700)}.dark .clock-number{color:var(--shk-surface-700)}.clock-number:hover{background-color:var(--shk-surface-100)}.dark .clock-number:hover{background-color:var(--shk-surface-200)}.clock-number.selected{background-color:var(--shk-primary-500);color:#fff}.clock-number.current{font-weight:700}.clock-hand{position:absolute;bottom:50%;left:50%;width:2px;background-color:var(--shk-primary-500);transform-origin:bottom center;border-radius:1px;pointer-events:none;transition:transform .2s ease-out}.clock-center{position:absolute;top:50%;left:50%;width:8px;height:8px;border-radius:50%;background-color:var(--shk-primary-500);transform:translate(-50%,-50%);pointer-events:none;z-index:2}.clock-minute-marker{position:absolute;width:1px;height:8px;background-color:var(--shk-surface-300);top:6px;left:50%;transform-origin:center 94px}.dark .clock-minute-marker{background-color:var(--shk-surface-400)}.clock-minute-marker.major{width:2px;height:12px;background-color:var(--shk-surface-400)}.dark .clock-minute-marker.major{background-color:var(--shk-surface-500)}.clock-mode-toggle{display:flex;align-items:center;justify-content:center;gap:.5rem;margin-top:.75rem}.clock-mode-btn{padding:.25rem .75rem;font-size:.75rem;font-weight:500;border-radius:9999px;cursor:pointer;transition:background-color .15s,color .15s;border:none;background:transparent;color:var(--shk-surface-500)}.dark .clock-mode-btn{color:var(--shk-surface-400)}.clock-mode-btn.active{background-color:var(--shk-primary-500);color:#fff}.clock-mode-btn:hover:not(.active){background-color:var(--shk-surface-100)}.dark .clock-mode-btn:hover:not(.active){background-color:var(--shk-surface-200)}.date-input-field{width:100%;padding:.5rem 2.5rem .5rem .75rem;font-size:.875rem;border-radius:.5rem;outline:none;transition:border-color .15s,box-shadow .15s;background-color:var(--shk-surface-50);color:var(--shk-surface-700);border:1px solid var(--shk-surface-200)}.dark .date-input-field{background-color:var(--shk-surface-100);color:var(--shk-surface-700);border-color:var(--shk-surface-200)}.date-input-field::placeholder{color:var(--shk-surface-400)}.dark .date-input-field::placeholder{color:var(--shk-surface-400)}.date-input-field:focus{border-color:var(--shk-primary-500);box-shadow:0 0 0 1px var(--shk-primary-500)}.date-input-field:disabled{opacity:.5;cursor:not-allowed}.date-input-field.input-error{border-color:#ef4444}.date-input-field.input-error:focus{border-color:#ef4444;box-shadow:0 0 0 1px #ef4444}.date-input-field.input-valid{border-color:#22c55e}.date-input-field.input-valid:focus{border-color:#22c55e;box-shadow:0 0 0 1px #22c55e}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1017
+ ], ngImport: i0, template: "<div class=\"relative mb-4\">\n @if (label()) {\n <div class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)] mb-1\">\n {{ label() }}\n </div>\n }\n\n <div class=\"relative\">\n <div class=\"relative\">\n <input\n [id]=\"id()\"\n type=\"text\"\n [disabled]=\"isDisabled()\"\n [placeholder]=\"inputPlaceholder()\"\n [value]=\"isTyping() ? typedValue() : displayLabel()\"\n (input)=\"onInputText($event)\"\n (focus)=\"onInputFocus()\"\n (blur)=\"onInputBlur()\"\n (keydown.enter)=\"$any($event.target).blur()\"\n (keydown.escape)=\"cancelTyping()\"\n (click)=\"toggle()\"\n class=\"date-input-field\"\n [ngClass]=\"{\n 'input-error': shouldShowError() || typingValid() === false,\n 'input-valid': wasFixedError() || typingValid() === true,\n }\"\n [attr.aria-invalid]=\"shouldShowError()\"\n [attr.aria-describedby]=\"shouldShowError() ? id() + '-error' : null\"\n />\n <button\n type=\"button\"\n [disabled]=\"isDisabled()\"\n (click)=\"toggle()\"\n class=\"absolute right-2 top-1/2 -translate-y-1/2 p-1 _shk-text-surface-400 dark:[color:var(--shk-surface-400)] hover:[color:var(--shk-surface-600)] dark:hover:[color:var(--shk-surface-300)] transition-colors\"\n >\n <svg\n class=\"w-4 h-4\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\"></rect>\n <path d=\"M16 2v4M8 2v4M3 10h18\"></path>\n </svg>\n </button>\n </div>\n\n @if (isOpen()) {\n <div class=\"fixed inset-0 z-40 bg-black/30\" (click)=\"close()\"></div>\n <div\n class=\"fixed z-50 top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-72 p-4 bg-white dark:[background-color:var(--shk-surface-100)] _shk-border dark:[border-color:var(--shk-surface-200)] rounded-lg shadow-xl\"\n (click)=\"$event.stopPropagation()\"\n >\n <!-- DATE VIEW -->\n @if (!timeOnly() && currentView() === 'date') {\n <div class=\"flex items-center justify-between mb-3\">\n <button\n type=\"button\"\n (click)=\"drillUp()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M15 18l-6-6 6-6\"></path>\n </svg>\n </button>\n <span class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)]\">\n {{ monthNames()[viewMonth()] }} {{ selectedYearValue() ?? viewYear() }}\n </span>\n <button\n type=\"button\"\n (click)=\"drillToInitial()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M9 18l6-6-6-6\"></path>\n </svg>\n </button>\n </div>\n\n <div class=\"grid grid-cols-7 gap-0 mb-1\">\n @for (name of dayNames(); track $index) {\n <div class=\"text-center text-xs font-medium _shk-text-surface-400 dark:[color:var(--shk-surface-400)] py-1\">\n {{ name }}\n </div>\n }\n </div>\n\n <div class=\"grid grid-cols-7 gap-0\">\n @for (day of calendarDays(); track $index) {\n @if (day !== null) {\n <button\n type=\"button\"\n (click)=\"selectDay(day)\"\n class=\"py-1.5 text-sm rounded transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white hover:[background-color:var(--shk-primary-700)]': isSelectedDay(day),\n 'ring-1 [--tw-ring-color:var(--shk-primary-500)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]': isToday(day) && !isSelectedDay(day),\n '_shk-text-surface-700 dark:[color:var(--shk-surface-700)] hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': !isSelectedDay(day) && !isToday(day),\n }\"\n >\n {{ day }}\n </button>\n } @else {\n <div></div>\n }\n }\n </div>\n }\n\n <!-- WEEK VIEW -->\n @if (!timeOnly() && currentView() === 'week') {\n <div class=\"flex items-center justify-between mb-3\">\n <button\n type=\"button\"\n (click)=\"prev()\"\n [disabled]=\"!canGoPrev()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M15 18l-6-6 6-6\"></path>\n </svg>\n </button>\n <span class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)]\">\n {{ monthNames()[viewMonth()] }} {{ viewYear() }}\n </span>\n <button\n type=\"button\"\n (click)=\"next()\"\n [disabled]=\"!canGoNext()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M9 18l6-6-6-6\"></path>\n </svg>\n </button>\n </div>\n\n <div class=\"space-y-1\">\n @for (week of monthWeeks(); track week.index) {\n <button\n type=\"button\"\n (click)=\"selectWeek(week.start)\"\n class=\"w-full flex items-center justify-between py-1.5 px-2 text-sm rounded transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white hover:[background-color:var(--shk-primary-700)]': isSelectedWeek(week.start),\n 'ring-1 [--tw-ring-color:var(--shk-primary-500)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]': isCurrentWeek(week.start) && !isSelectedWeek(week.start),\n '_shk-text-surface-700 dark:[color:var(--shk-surface-700)] hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': !isSelectedWeek(week.start) && !isCurrentWeek(week.start),\n }\"\n >\n <span class=\"font-medium\">{{ weekLabel(week.index) }}</span>\n <span class=\"text-xs opacity-80\">{{ week.range }}</span>\n </button>\n }\n </div>\n }\n\n <!-- MONTH VIEW -->\n @if (!timeOnly() && currentView() === 'month') {\n <div class=\"flex items-center justify-between mb-3\">\n <button\n type=\"button\"\n (click)=\"drillUp()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M15 18l-6-6 6-6\"></path>\n </svg>\n </button>\n <span class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)]\">\n {{ selectedYearValue() ?? viewYear() }}\n </span>\n <button\n type=\"button\"\n (click)=\"drillToInitial()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M9 18l6-6-6-6\"></path>\n </svg>\n </button>\n </div>\n\n <div class=\"grid grid-cols-3 gap-1\">\n @for (name of monthNames(); track $index) {\n <button\n type=\"button\"\n (click)=\"selectMonth($index)\"\n class=\"py-2 text-sm rounded transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white hover:[background-color:var(--shk-primary-700)]': selectedMonthValue() === $index,\n 'ring-1 [--tw-ring-color:var(--shk-primary-500)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]': isCurrentMonth($index) && selectedMonthValue() !== $index,\n '_shk-text-surface-700 dark:[color:var(--shk-surface-700)] hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': selectedMonthValue() !== $index && !isCurrentMonth($index),\n }\"\n >\n {{ name }}\n </button>\n }\n </div>\n }\n\n <!-- YEAR VIEW -->\n @if (!timeOnly() && currentView() === 'year') {\n <div class=\"flex items-center justify-between mb-3\">\n <button\n type=\"button\"\n (click)=\"prev()\"\n [disabled]=\"!canGoPrev()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M15 18l-6-6 6-6\"></path>\n </svg>\n </button>\n <span class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)]\">\n {{ viewDecade() }} - {{ viewDecade() + 11 }}\n </span>\n <button\n type=\"button\"\n (click)=\"next()\"\n [disabled]=\"!canGoNext()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M9 18l6-6-6-6\"></path>\n </svg>\n </button>\n </div>\n\n <div class=\"grid grid-cols-3 gap-1\">\n @for (year of decadeYears(); track year) {\n <button\n type=\"button\"\n (click)=\"selectYear(year)\"\n class=\"py-2 text-sm rounded transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white hover:[background-color:var(--shk-primary-700)]': selectedYearValue() === year,\n 'ring-1 [--tw-ring-color:var(--shk-primary-500)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]': isCurrentYear(year) && selectedYearValue() !== year,\n '_shk-text-surface-700 dark:[color:var(--shk-surface-700)] hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': selectedYearValue() !== year && !isCurrentYear(year),\n }\"\n >\n {{ year }}\n </button>\n }\n </div>\n }\n\n <!-- ANALOG CLOCK TIME PICKER -->\n @if (timeOnly() || showTime()) {\n <div class=\"mt-3 pt-3 _shk-border dark:[border-color:var(--shk-surface-200)]\">\n <!-- Clock display time -->\n <div class=\"text-center mb-2\">\n <span class=\"text-lg font-semibold _shk-text-surface-700 dark:[color:var(--shk-surface-700)]\">\n {{ clockDisplayTime() }}\n </span>\n </div>\n\n <!-- Analog clock face -->\n <div class=\"clock-container\">\n <svg\n viewBox=\"0 0 200 200\"\n class=\"w-full h-full cursor-pointer\"\n (click)=\"onClockClick($event, clockMode())\"\n >\n <!-- Clock face background -->\n <circle cx=\"100\" cy=\"100\" r=\"96\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1\"\n class=\"_shk-text-surface-200 dark:[color:var(--shk-surface-200)]\" />\n\n <!-- Minute markers -->\n @if (clockMode() === 'minutes') {\n @for (i of [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59]; track i) {\n <line\n [attr.x1]=\"clockMinuteMarker(i).x1\"\n [attr.y1]=\"clockMinuteMarker(i).y1\"\n [attr.x2]=\"clockMinuteMarker(i).x2\"\n [attr.y2]=\"clockMinuteMarker(i).y2\"\n [attr.stroke-width]=\"i % 5 === 0 ? 2 : 1\"\n [class]=\"i % 5 === 0 ? '_shk-text-surface-500 dark:[color:var(--shk-surface-500)]' : '_shk-text-surface-300 dark:[color:var(--shk-surface-400)]'\"\n stroke=\"currentColor\"\n />\n }\n <!-- Minute numbers (00, 05, 10, ...) -->\n @for (m of [0,5,10,15,20,25,30,35,40,45,50,55]; track m) {\n <text\n [attr.x]=\"clockMinutePos(m).x\"\n [attr.y]=\"clockMinutePos(m).y\"\n text-anchor=\"middle\"\n dominant-baseline=\"central\"\n class=\"text-[9px] _shk-text-surface-500 dark:[color:var(--shk-surface-400)]\"\n [class._shk-text-primary]=\"viewMinute() === m\"\n >\n {{ m.toString().padStart(2, '0') }}\n </text>\n }\n }\n\n <!-- Hour numbers -->\n @if (clockMode() === 'hours') {\n @for (h of clockHours(); track h) {\n <text\n [attr.x]=\"clockNumberPos(h).x\"\n [attr.y]=\"clockNumberPos(h).y\"\n text-anchor=\"middle\"\n dominant-baseline=\"central\"\n class=\"text-sm font-medium\"\n [class._shk-text-primary]=\"isClockHourSelected(h)\"\n [class._shk-text-surface-700]=\"!isClockHourSelected(h)\"\n >\n {{ h }}\n </text>\n }\n }\n\n <!-- Clock hand -->\n <line\n x1=\"100\" y1=\"100\"\n [attr.x2]=\"clockHandLine(60).x2\"\n [attr.y2]=\"clockHandLine(60).y2\"\n class=\"_shk-text-primary\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n\n <!-- Center dot -->\n <circle cx=\"100\" cy=\"100\" r=\"4\" class=\"fill-current _shk-text-primary\" />\n </svg>\n </div>\n\n <!-- Mode toggle: Hours / Minutes -->\n <div class=\"clock-mode-toggle\">\n <button\n type=\"button\"\n (click)=\"clockMode.set('hours')\"\n class=\"clock-mode-btn\"\n [class.active]=\"clockMode() === 'hours'\"\n >\n {{ 'Horas' }}\n </button>\n <button\n type=\"button\"\n (click)=\"clockMode.set('minutes')\"\n class=\"clock-mode-btn\"\n [class.active]=\"clockMode() === 'minutes'\"\n >\n {{ 'Minutos' }}\n </button>\n </div>\n\n <!-- AM/PM toggle for 12h format -->\n @if (hourFormat() === '12') {\n <div class=\"flex items-center justify-center gap-2 mt-2\">\n <button\n type=\"button\"\n (click)=\"viewMeridiem.set('AM')\"\n class=\"px-3 py-1 text-xs font-medium rounded-full transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white': viewMeridiem() === 'AM',\n '_shk-text-surface-500 hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': viewMeridiem() !== 'AM'\n }\"\n >\n AM\n </button>\n <button\n type=\"button\"\n (click)=\"viewMeridiem.set('PM')\"\n class=\"px-3 py-1 text-xs font-medium rounded-full transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white': viewMeridiem() === 'PM',\n '_shk-text-surface-500 hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': viewMeridiem() !== 'PM'\n }\"\n >\n PM\n </button>\n </div>\n }\n\n <!-- Seconds selector (if enabled) -->\n @if (showSeconds()) {\n <div class=\"flex items-center justify-center gap-1 mt-2\">\n <span class=\"text-xs _shk-text-surface-400\">Seg:</span>\n <select\n class=\"px-2 py-1 text-xs _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] _shk-border dark:[border-color:var(--shk-surface-200)] rounded-md\"\n [value]=\"viewSecond()\"\n (change)=\"onSecondChange($event)\"\n aria-label=\"Segundos\"\n >\n @for (seconds of secondsRange(); track seconds) {\n <option [value]=\"seconds\">{{ minutesLabel(seconds) }}</option>\n }\n </select>\n </div>\n }\n\n <!-- Confirm button -->\n <button\n type=\"button\"\n (click)=\"confirmTime()\"\n class=\"mt-3 w-full py-2 text-sm _shk-bg-primary _shk-text-white rounded-lg hover:[background-color:var(--shk-primary-700)] transition-colors\"\n >\n {{ timeOnly() ? 'Confirmar' : 'Introducir hora' }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n\n @if (shouldShowError()) {\n <div [id]=\"id() + '-error'\" class=\"mt-1 text-xs text-red-500 max-h-20 overflow-y-auto _shk-scrollbar\">\n <ul class=\"list-disc pl-4 space-y-1\">\n @for (error of getErrorMessages(); track error) {\n <li>{{ error }}</li>\n }\n </ul>\n </div>\n }\n</div>\n", styles: [".clock-container{position:relative;width:200px;height:200px;margin:0 auto}.clock-face{width:100%;height:100%;border-radius:50%;border:2px solid var(--shk-surface-200);position:relative;background-color:var(--shk-surface-50)}:host-context(.dark) .clock-face{border-color:var(--shk-surface-200);background-color:var(--shk-surface-100)}.clock-number{position:absolute;width:32px;height:32px;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:500;border-radius:50%;transform:translate(-50%,-50%);cursor:pointer;transition:background-color .15s,color .15s;-webkit-user-select:none;user-select:none;color:var(--shk-surface-700)}:host-context(.dark) .clock-number{color:var(--shk-surface-700)}.clock-number:hover{background-color:var(--shk-surface-100)}:host-context(.dark) .clock-number:hover{background-color:var(--shk-surface-200)}.clock-number.selected{background-color:var(--shk-primary-500);color:#fff}.clock-number.current{font-weight:700}.clock-hand{position:absolute;bottom:50%;left:50%;width:2px;background-color:var(--shk-primary-500);transform-origin:bottom center;border-radius:1px;pointer-events:none;transition:transform .2s ease-out}.clock-center{position:absolute;top:50%;left:50%;width:8px;height:8px;border-radius:50%;background-color:var(--shk-primary-500);transform:translate(-50%,-50%);pointer-events:none;z-index:2}.clock-minute-marker{position:absolute;width:1px;height:8px;background-color:var(--shk-surface-300);top:6px;left:50%;transform-origin:center 94px}:host-context(.dark) .clock-minute-marker{background-color:var(--shk-surface-400)}.clock-minute-marker.major{width:2px;height:12px;background-color:var(--shk-surface-400)}:host-context(.dark) .clock-minute-marker.major{background-color:var(--shk-surface-500)}.clock-mode-toggle{display:flex;align-items:center;justify-content:center;gap:.5rem;margin-top:.75rem}.clock-mode-btn{padding:.25rem .75rem;font-size:.75rem;font-weight:500;border-radius:9999px;cursor:pointer;transition:background-color .15s,color .15s;border:none;background:transparent;color:var(--shk-surface-500)}:host-context(.dark) .clock-mode-btn{color:var(--shk-surface-400)}.clock-mode-btn.active{background-color:var(--shk-primary-500);color:#fff}.clock-mode-btn:hover:not(.active){background-color:var(--shk-surface-100)}:host-context(.dark) .clock-mode-btn:hover:not(.active){background-color:var(--shk-surface-200)}.date-input-field{width:100%;padding:.5rem 2.5rem .5rem .75rem;font-size:.875rem;border-radius:.5rem;outline:none;transition:border-color .15s,box-shadow .15s;background-color:var(--shk-surface-50);color:var(--shk-surface-700);border:1px solid var(--shk-surface-200)}:host-context(.dark) .date-input-field{background-color:var(--shk-surface-100);color:var(--shk-surface-700);border-color:var(--shk-surface-200)}.date-input-field::placeholder{color:var(--shk-surface-400)}:host-context(.dark) .date-input-field::placeholder{color:var(--shk-surface-400)}.date-input-field:focus{border-color:var(--shk-primary-500);box-shadow:0 0 0 3px color-mix(in srgb,var(--shk-primary-500) 22%,transparent)}.date-input-field:disabled{background-color:var(--shk-surface-100);border-color:var(--shk-surface-200);color:var(--shk-surface-500);cursor:not-allowed}:host-context(.dark) .date-input-field:disabled{background-color:var(--shk-surface-50);color:var(--shk-surface-400)}.date-input-field.input-error{border-color:#ef4444}.date-input-field.input-error:focus{border-color:#ef4444;box-shadow:0 0 0 3px #ef444433}.date-input-field.input-valid{border-color:#22c55e}.date-input-field.input-valid:focus{border-color:#22c55e;box-shadow:0 0 0 3px #22c55e33}.date-input-field{text-overflow:ellipsis}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
937
1018
  }
938
1019
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: DatePickerComponent, decorators: [{
939
1020
  type: Component,
@@ -943,8 +1024,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImpo
943
1024
  useExisting: forwardRef(() => DatePickerComponent),
944
1025
  multi: true,
945
1026
  },
946
- ], template: "<div class=\"relative mb-4\">\n @if (label()) {\n <div class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)] mb-1\">\n {{ label() }}\n </div>\n }\n\n <div class=\"relative\">\n <div class=\"relative\">\n <input\n [id]=\"id()\"\n type=\"text\"\n [disabled]=\"isDisabled()\"\n [placeholder]=\"inputPlaceholder()\"\n [value]=\"isTyping() ? typedValue() : displayLabel()\"\n (input)=\"onInputText($event)\"\n (focus)=\"onInputFocus()\"\n (blur)=\"onInputBlur()\"\n (keydown.enter)=\"$any($event.target).blur()\"\n (keydown.escape)=\"cancelTyping()\"\n (click)=\"toggle()\"\n class=\"date-input-field\"\n [ngClass]=\"{\n 'input-error': shouldShowError() || typingValid() === false,\n 'input-valid': wasFixedError() || typingValid() === true,\n }\"\n [attr.aria-invalid]=\"shouldShowError()\"\n [attr.aria-describedby]=\"shouldShowError() ? id() + '-error' : null\"\n />\n <button\n type=\"button\"\n [disabled]=\"isDisabled()\"\n (click)=\"toggle()\"\n class=\"absolute right-2 top-1/2 -translate-y-1/2 p-1 _shk-text-surface-400 dark:[color:var(--shk-surface-400)] hover:[color:var(--shk-surface-600)] dark:hover:[color:var(--shk-surface-300)] transition-colors\"\n >\n <svg\n class=\"w-4 h-4\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\"></rect>\n <path d=\"M16 2v4M8 2v4M3 10h18\"></path>\n </svg>\n </button>\n </div>\n\n @if (isOpen()) {\n <div class=\"fixed inset-0 z-40 bg-black/30\" (click)=\"close()\"></div>\n <div\n class=\"fixed z-50 top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-72 p-4 bg-white dark:[background-color:var(--shk-surface-100)] _shk-border dark:[border-color:var(--shk-surface-200)] rounded-lg shadow-xl\"\n (click)=\"$event.stopPropagation()\"\n >\n <!-- DATE VIEW -->\n @if (!timeOnly() && currentView() === 'date') {\n <div class=\"flex items-center justify-between mb-3\">\n <button\n type=\"button\"\n (click)=\"drillUp()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M15 18l-6-6 6-6\"></path>\n </svg>\n </button>\n <span class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)]\">\n {{ monthNames()[viewMonth()] }} {{ selectedYearValue() ?? viewYear() }}\n </span>\n <button\n type=\"button\"\n (click)=\"drillToInitial()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M9 18l6-6-6-6\"></path>\n </svg>\n </button>\n </div>\n\n <div class=\"grid grid-cols-7 gap-0 mb-1\">\n @for (name of dayNames(); track $index) {\n <div class=\"text-center text-xs font-medium _shk-text-surface-400 dark:[color:var(--shk-surface-400)] py-1\">\n {{ name }}\n </div>\n }\n </div>\n\n <div class=\"grid grid-cols-7 gap-0\">\n @for (day of calendarDays(); track $index) {\n @if (day !== null) {\n <button\n type=\"button\"\n (click)=\"selectDay(day)\"\n class=\"py-1.5 text-sm rounded transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white hover:[background-color:var(--shk-primary-700)]': isSelectedDay(day),\n 'ring-1 [--tw-ring-color:var(--shk-primary-500)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]': isToday(day) && !isSelectedDay(day),\n '_shk-text-surface-700 dark:[color:var(--shk-surface-700)] hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': !isSelectedDay(day) && !isToday(day),\n }\"\n >\n {{ day }}\n </button>\n } @else {\n <div></div>\n }\n }\n </div>\n }\n\n <!-- MONTH VIEW -->\n @if (!timeOnly() && currentView() === 'month') {\n <div class=\"flex items-center justify-between mb-3\">\n <button\n type=\"button\"\n (click)=\"drillUp()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M15 18l-6-6 6-6\"></path>\n </svg>\n </button>\n <span class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)]\">\n {{ selectedYearValue() ?? viewYear() }}\n </span>\n <button\n type=\"button\"\n (click)=\"drillToInitial()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M9 18l6-6-6-6\"></path>\n </svg>\n </button>\n </div>\n\n <div class=\"grid grid-cols-3 gap-1\">\n @for (name of monthNames(); track $index) {\n <button\n type=\"button\"\n (click)=\"selectMonth($index)\"\n class=\"py-2 text-sm rounded transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white hover:[background-color:var(--shk-primary-700)]': selectedMonthValue() === $index,\n 'ring-1 [--tw-ring-color:var(--shk-primary-500)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]': isCurrentMonth($index) && selectedMonthValue() !== $index,\n '_shk-text-surface-700 dark:[color:var(--shk-surface-700)] hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': selectedMonthValue() !== $index && !isCurrentMonth($index),\n }\"\n >\n {{ name }}\n </button>\n }\n </div>\n }\n\n <!-- YEAR VIEW -->\n @if (!timeOnly() && currentView() === 'year') {\n <div class=\"flex items-center justify-between mb-3\">\n <button\n type=\"button\"\n (click)=\"prev()\"\n [disabled]=\"!canGoPrev()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M15 18l-6-6 6-6\"></path>\n </svg>\n </button>\n <span class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)]\">\n {{ viewDecade() }} - {{ viewDecade() + 11 }}\n </span>\n <button\n type=\"button\"\n (click)=\"next()\"\n [disabled]=\"!canGoNext()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M9 18l6-6-6-6\"></path>\n </svg>\n </button>\n </div>\n\n <div class=\"grid grid-cols-3 gap-1\">\n @for (year of decadeYears(); track year) {\n <button\n type=\"button\"\n (click)=\"selectYear(year)\"\n class=\"py-2 text-sm rounded transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white hover:[background-color:var(--shk-primary-700)]': selectedYearValue() === year,\n 'ring-1 [--tw-ring-color:var(--shk-primary-500)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]': isCurrentYear(year) && selectedYearValue() !== year,\n '_shk-text-surface-700 dark:[color:var(--shk-surface-700)] hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': selectedYearValue() !== year && !isCurrentYear(year),\n }\"\n >\n {{ year }}\n </button>\n }\n </div>\n }\n\n <!-- ANALOG CLOCK TIME PICKER -->\n @if (timeOnly() || showTime()) {\n <div class=\"mt-3 pt-3 _shk-border dark:[border-color:var(--shk-surface-200)]\">\n <!-- Clock display time -->\n <div class=\"text-center mb-2\">\n <span class=\"text-lg font-semibold _shk-text-surface-700 dark:[color:var(--shk-surface-700)]\">\n {{ clockDisplayTime() }}\n </span>\n </div>\n\n <!-- Analog clock face -->\n <div class=\"clock-container\">\n <svg\n viewBox=\"0 0 200 200\"\n class=\"w-full h-full cursor-pointer\"\n (click)=\"onClockClick($event, clockMode())\"\n >\n <!-- Clock face background -->\n <circle cx=\"100\" cy=\"100\" r=\"96\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1\"\n class=\"_shk-text-surface-200 dark:[color:var(--shk-surface-200)]\" />\n\n <!-- Minute markers -->\n @if (clockMode() === 'minutes') {\n @for (i of [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59]; track i) {\n <line\n [attr.x1]=\"clockMinuteMarker(i).x1\"\n [attr.y1]=\"clockMinuteMarker(i).y1\"\n [attr.x2]=\"clockMinuteMarker(i).x2\"\n [attr.y2]=\"clockMinuteMarker(i).y2\"\n [attr.stroke-width]=\"i % 5 === 0 ? 2 : 1\"\n [class]=\"i % 5 === 0 ? '_shk-text-surface-500 dark:[color:var(--shk-surface-500)]' : '_shk-text-surface-300 dark:[color:var(--shk-surface-400)]'\"\n stroke=\"currentColor\"\n />\n }\n <!-- Minute numbers (00, 05, 10, ...) -->\n @for (m of [0,5,10,15,20,25,30,35,40,45,50,55]; track m) {\n <text\n [attr.x]=\"clockMinutePos(m).x\"\n [attr.y]=\"clockMinutePos(m).y\"\n text-anchor=\"middle\"\n dominant-baseline=\"central\"\n class=\"text-[9px] _shk-text-surface-500 dark:[color:var(--shk-surface-400)]\"\n [class._shk-text-primary]=\"viewMinute() === m\"\n >\n {{ m.toString().padStart(2, '0') }}\n </text>\n }\n }\n\n <!-- Hour numbers -->\n @if (clockMode() === 'hours') {\n @for (h of clockHours(); track h) {\n <text\n [attr.x]=\"clockNumberPos(h).x\"\n [attr.y]=\"clockNumberPos(h).y\"\n text-anchor=\"middle\"\n dominant-baseline=\"central\"\n class=\"text-sm font-medium\"\n [class._shk-text-primary]=\"isClockHourSelected(h)\"\n [class._shk-text-surface-700]=\"!isClockHourSelected(h)\"\n >\n {{ h }}\n </text>\n }\n }\n\n <!-- Clock hand -->\n <line\n x1=\"100\" y1=\"100\"\n [attr.x2]=\"clockHandLine(60).x2\"\n [attr.y2]=\"clockHandLine(60).y2\"\n class=\"_shk-text-primary\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n\n <!-- Center dot -->\n <circle cx=\"100\" cy=\"100\" r=\"4\" class=\"fill-current _shk-text-primary\" />\n </svg>\n </div>\n\n <!-- Mode toggle: Hours / Minutes -->\n <div class=\"clock-mode-toggle\">\n <button\n type=\"button\"\n (click)=\"clockMode.set('hours')\"\n class=\"clock-mode-btn\"\n [class.active]=\"clockMode() === 'hours'\"\n >\n {{ 'Horas' }}\n </button>\n <button\n type=\"button\"\n (click)=\"clockMode.set('minutes')\"\n class=\"clock-mode-btn\"\n [class.active]=\"clockMode() === 'minutes'\"\n >\n {{ 'Minutos' }}\n </button>\n </div>\n\n <!-- AM/PM toggle for 12h format -->\n @if (hourFormat() === '12') {\n <div class=\"flex items-center justify-center gap-2 mt-2\">\n <button\n type=\"button\"\n (click)=\"viewMeridiem.set('AM')\"\n class=\"px-3 py-1 text-xs font-medium rounded-full transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white': viewMeridiem() === 'AM',\n '_shk-text-surface-500 hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': viewMeridiem() !== 'AM'\n }\"\n >\n AM\n </button>\n <button\n type=\"button\"\n (click)=\"viewMeridiem.set('PM')\"\n class=\"px-3 py-1 text-xs font-medium rounded-full transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white': viewMeridiem() === 'PM',\n '_shk-text-surface-500 hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': viewMeridiem() !== 'PM'\n }\"\n >\n PM\n </button>\n </div>\n }\n\n <!-- Seconds selector (if enabled) -->\n @if (showSeconds()) {\n <div class=\"flex items-center justify-center gap-1 mt-2\">\n <span class=\"text-xs _shk-text-surface-400\">Seg:</span>\n <select\n class=\"px-2 py-1 text-xs _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] _shk-border dark:[border-color:var(--shk-surface-200)] rounded-md\"\n [value]=\"viewSecond()\"\n (change)=\"onSecondChange($event)\"\n aria-label=\"Segundos\"\n >\n @for (seconds of secondsRange(); track seconds) {\n <option [value]=\"seconds\">{{ minutesLabel(seconds) }}</option>\n }\n </select>\n </div>\n }\n\n <!-- Confirm button -->\n <button\n type=\"button\"\n (click)=\"confirmTime()\"\n class=\"mt-3 w-full py-2 text-sm _shk-bg-primary _shk-text-white rounded-lg hover:[background-color:var(--shk-primary-700)] transition-colors\"\n >\n {{ timeOnly() ? 'Confirmar' : 'Introducir hora' }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n\n @if (shouldShowError()) {\n <div [id]=\"id() + '-error'\" class=\"mt-1 text-xs text-red-500 max-h-20 overflow-y-auto _shk-scrollbar\">\n <ul class=\"list-disc pl-4 space-y-1\">\n @for (error of getErrorMessages(); track error) {\n <li>{{ error }}</li>\n }\n </ul>\n </div>\n }\n</div>\n", styles: [".clock-container{position:relative;width:200px;height:200px;margin:0 auto}.clock-face{width:100%;height:100%;border-radius:50%;border:2px solid var(--shk-surface-200);position:relative;background-color:var(--shk-surface-50)}.dark .clock-face{border-color:var(--shk-surface-200);background-color:var(--shk-surface-100)}.clock-number{position:absolute;width:32px;height:32px;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:500;border-radius:50%;transform:translate(-50%,-50%);cursor:pointer;transition:background-color .15s,color .15s;-webkit-user-select:none;user-select:none;color:var(--shk-surface-700)}.dark .clock-number{color:var(--shk-surface-700)}.clock-number:hover{background-color:var(--shk-surface-100)}.dark .clock-number:hover{background-color:var(--shk-surface-200)}.clock-number.selected{background-color:var(--shk-primary-500);color:#fff}.clock-number.current{font-weight:700}.clock-hand{position:absolute;bottom:50%;left:50%;width:2px;background-color:var(--shk-primary-500);transform-origin:bottom center;border-radius:1px;pointer-events:none;transition:transform .2s ease-out}.clock-center{position:absolute;top:50%;left:50%;width:8px;height:8px;border-radius:50%;background-color:var(--shk-primary-500);transform:translate(-50%,-50%);pointer-events:none;z-index:2}.clock-minute-marker{position:absolute;width:1px;height:8px;background-color:var(--shk-surface-300);top:6px;left:50%;transform-origin:center 94px}.dark .clock-minute-marker{background-color:var(--shk-surface-400)}.clock-minute-marker.major{width:2px;height:12px;background-color:var(--shk-surface-400)}.dark .clock-minute-marker.major{background-color:var(--shk-surface-500)}.clock-mode-toggle{display:flex;align-items:center;justify-content:center;gap:.5rem;margin-top:.75rem}.clock-mode-btn{padding:.25rem .75rem;font-size:.75rem;font-weight:500;border-radius:9999px;cursor:pointer;transition:background-color .15s,color .15s;border:none;background:transparent;color:var(--shk-surface-500)}.dark .clock-mode-btn{color:var(--shk-surface-400)}.clock-mode-btn.active{background-color:var(--shk-primary-500);color:#fff}.clock-mode-btn:hover:not(.active){background-color:var(--shk-surface-100)}.dark .clock-mode-btn:hover:not(.active){background-color:var(--shk-surface-200)}.date-input-field{width:100%;padding:.5rem 2.5rem .5rem .75rem;font-size:.875rem;border-radius:.5rem;outline:none;transition:border-color .15s,box-shadow .15s;background-color:var(--shk-surface-50);color:var(--shk-surface-700);border:1px solid var(--shk-surface-200)}.dark .date-input-field{background-color:var(--shk-surface-100);color:var(--shk-surface-700);border-color:var(--shk-surface-200)}.date-input-field::placeholder{color:var(--shk-surface-400)}.dark .date-input-field::placeholder{color:var(--shk-surface-400)}.date-input-field:focus{border-color:var(--shk-primary-500);box-shadow:0 0 0 1px var(--shk-primary-500)}.date-input-field:disabled{opacity:.5;cursor:not-allowed}.date-input-field.input-error{border-color:#ef4444}.date-input-field.input-error:focus{border-color:#ef4444;box-shadow:0 0 0 1px #ef4444}.date-input-field.input-valid{border-color:#22c55e}.date-input-field.input-valid:focus{border-color:#22c55e;box-shadow:0 0 0 1px #22c55e}\n"] }]
947
- }], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], formGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "formGroup", required: false }] }], control: [{ type: i0.Input, args: [{ isSignal: true, alias: "control", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], errorMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessages", required: false }] }], minValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "minValue", required: false }] }], maxValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxValue", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], timeOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeOnly", required: false }] }], showTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTime", required: false }] }], hourFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "hourFormat", required: false }] }], showSeconds: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSeconds", required: false }] }], minuteStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "minuteStep", required: false }] }], onDocumentClick: [{
1027
+ ], template: "<div class=\"relative mb-4\">\n @if (label()) {\n <div class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)] mb-1\">\n {{ label() }}\n </div>\n }\n\n <div class=\"relative\">\n <div class=\"relative\">\n <input\n [id]=\"id()\"\n type=\"text\"\n [disabled]=\"isDisabled()\"\n [placeholder]=\"inputPlaceholder()\"\n [value]=\"isTyping() ? typedValue() : displayLabel()\"\n (input)=\"onInputText($event)\"\n (focus)=\"onInputFocus()\"\n (blur)=\"onInputBlur()\"\n (keydown.enter)=\"$any($event.target).blur()\"\n (keydown.escape)=\"cancelTyping()\"\n (click)=\"toggle()\"\n class=\"date-input-field\"\n [ngClass]=\"{\n 'input-error': shouldShowError() || typingValid() === false,\n 'input-valid': wasFixedError() || typingValid() === true,\n }\"\n [attr.aria-invalid]=\"shouldShowError()\"\n [attr.aria-describedby]=\"shouldShowError() ? id() + '-error' : null\"\n />\n <button\n type=\"button\"\n [disabled]=\"isDisabled()\"\n (click)=\"toggle()\"\n class=\"absolute right-2 top-1/2 -translate-y-1/2 p-1 _shk-text-surface-400 dark:[color:var(--shk-surface-400)] hover:[color:var(--shk-surface-600)] dark:hover:[color:var(--shk-surface-300)] transition-colors\"\n >\n <svg\n class=\"w-4 h-4\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n >\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\"></rect>\n <path d=\"M16 2v4M8 2v4M3 10h18\"></path>\n </svg>\n </button>\n </div>\n\n @if (isOpen()) {\n <div class=\"fixed inset-0 z-40 bg-black/30\" (click)=\"close()\"></div>\n <div\n class=\"fixed z-50 top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-72 p-4 bg-white dark:[background-color:var(--shk-surface-100)] _shk-border dark:[border-color:var(--shk-surface-200)] rounded-lg shadow-xl\"\n (click)=\"$event.stopPropagation()\"\n >\n <!-- DATE VIEW -->\n @if (!timeOnly() && currentView() === 'date') {\n <div class=\"flex items-center justify-between mb-3\">\n <button\n type=\"button\"\n (click)=\"drillUp()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M15 18l-6-6 6-6\"></path>\n </svg>\n </button>\n <span class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)]\">\n {{ monthNames()[viewMonth()] }} {{ selectedYearValue() ?? viewYear() }}\n </span>\n <button\n type=\"button\"\n (click)=\"drillToInitial()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M9 18l6-6-6-6\"></path>\n </svg>\n </button>\n </div>\n\n <div class=\"grid grid-cols-7 gap-0 mb-1\">\n @for (name of dayNames(); track $index) {\n <div class=\"text-center text-xs font-medium _shk-text-surface-400 dark:[color:var(--shk-surface-400)] py-1\">\n {{ name }}\n </div>\n }\n </div>\n\n <div class=\"grid grid-cols-7 gap-0\">\n @for (day of calendarDays(); track $index) {\n @if (day !== null) {\n <button\n type=\"button\"\n (click)=\"selectDay(day)\"\n class=\"py-1.5 text-sm rounded transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white hover:[background-color:var(--shk-primary-700)]': isSelectedDay(day),\n 'ring-1 [--tw-ring-color:var(--shk-primary-500)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]': isToday(day) && !isSelectedDay(day),\n '_shk-text-surface-700 dark:[color:var(--shk-surface-700)] hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': !isSelectedDay(day) && !isToday(day),\n }\"\n >\n {{ day }}\n </button>\n } @else {\n <div></div>\n }\n }\n </div>\n }\n\n <!-- WEEK VIEW -->\n @if (!timeOnly() && currentView() === 'week') {\n <div class=\"flex items-center justify-between mb-3\">\n <button\n type=\"button\"\n (click)=\"prev()\"\n [disabled]=\"!canGoPrev()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M15 18l-6-6 6-6\"></path>\n </svg>\n </button>\n <span class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)]\">\n {{ monthNames()[viewMonth()] }} {{ viewYear() }}\n </span>\n <button\n type=\"button\"\n (click)=\"next()\"\n [disabled]=\"!canGoNext()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M9 18l6-6-6-6\"></path>\n </svg>\n </button>\n </div>\n\n <div class=\"space-y-1\">\n @for (week of monthWeeks(); track week.index) {\n <button\n type=\"button\"\n (click)=\"selectWeek(week.start)\"\n class=\"w-full flex items-center justify-between py-1.5 px-2 text-sm rounded transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white hover:[background-color:var(--shk-primary-700)]': isSelectedWeek(week.start),\n 'ring-1 [--tw-ring-color:var(--shk-primary-500)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]': isCurrentWeek(week.start) && !isSelectedWeek(week.start),\n '_shk-text-surface-700 dark:[color:var(--shk-surface-700)] hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': !isSelectedWeek(week.start) && !isCurrentWeek(week.start),\n }\"\n >\n <span class=\"font-medium\">{{ weekLabel(week.index) }}</span>\n <span class=\"text-xs opacity-80\">{{ week.range }}</span>\n </button>\n }\n </div>\n }\n\n <!-- MONTH VIEW -->\n @if (!timeOnly() && currentView() === 'month') {\n <div class=\"flex items-center justify-between mb-3\">\n <button\n type=\"button\"\n (click)=\"drillUp()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M15 18l-6-6 6-6\"></path>\n </svg>\n </button>\n <span class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)]\">\n {{ selectedYearValue() ?? viewYear() }}\n </span>\n <button\n type=\"button\"\n (click)=\"drillToInitial()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M9 18l6-6-6-6\"></path>\n </svg>\n </button>\n </div>\n\n <div class=\"grid grid-cols-3 gap-1\">\n @for (name of monthNames(); track $index) {\n <button\n type=\"button\"\n (click)=\"selectMonth($index)\"\n class=\"py-2 text-sm rounded transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white hover:[background-color:var(--shk-primary-700)]': selectedMonthValue() === $index,\n 'ring-1 [--tw-ring-color:var(--shk-primary-500)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]': isCurrentMonth($index) && selectedMonthValue() !== $index,\n '_shk-text-surface-700 dark:[color:var(--shk-surface-700)] hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': selectedMonthValue() !== $index && !isCurrentMonth($index),\n }\"\n >\n {{ name }}\n </button>\n }\n </div>\n }\n\n <!-- YEAR VIEW -->\n @if (!timeOnly() && currentView() === 'year') {\n <div class=\"flex items-center justify-between mb-3\">\n <button\n type=\"button\"\n (click)=\"prev()\"\n [disabled]=\"!canGoPrev()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M15 18l-6-6 6-6\"></path>\n </svg>\n </button>\n <span class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)]\">\n {{ viewDecade() }} - {{ viewDecade() + 11 }}\n </span>\n <button\n type=\"button\"\n (click)=\"next()\"\n [disabled]=\"!canGoNext()\"\n class=\"p-1 rounded hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)] disabled:opacity-30 disabled:cursor-not-allowed\"\n >\n <svg class=\"w-4 h-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M9 18l6-6-6-6\"></path>\n </svg>\n </button>\n </div>\n\n <div class=\"grid grid-cols-3 gap-1\">\n @for (year of decadeYears(); track year) {\n <button\n type=\"button\"\n (click)=\"selectYear(year)\"\n class=\"py-2 text-sm rounded transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white hover:[background-color:var(--shk-primary-700)]': selectedYearValue() === year,\n 'ring-1 [--tw-ring-color:var(--shk-primary-500)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]': isCurrentYear(year) && selectedYearValue() !== year,\n '_shk-text-surface-700 dark:[color:var(--shk-surface-700)] hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': selectedYearValue() !== year && !isCurrentYear(year),\n }\"\n >\n {{ year }}\n </button>\n }\n </div>\n }\n\n <!-- ANALOG CLOCK TIME PICKER -->\n @if (timeOnly() || showTime()) {\n <div class=\"mt-3 pt-3 _shk-border dark:[border-color:var(--shk-surface-200)]\">\n <!-- Clock display time -->\n <div class=\"text-center mb-2\">\n <span class=\"text-lg font-semibold _shk-text-surface-700 dark:[color:var(--shk-surface-700)]\">\n {{ clockDisplayTime() }}\n </span>\n </div>\n\n <!-- Analog clock face -->\n <div class=\"clock-container\">\n <svg\n viewBox=\"0 0 200 200\"\n class=\"w-full h-full cursor-pointer\"\n (click)=\"onClockClick($event, clockMode())\"\n >\n <!-- Clock face background -->\n <circle cx=\"100\" cy=\"100\" r=\"96\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1\"\n class=\"_shk-text-surface-200 dark:[color:var(--shk-surface-200)]\" />\n\n <!-- Minute markers -->\n @if (clockMode() === 'minutes') {\n @for (i of [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59]; track i) {\n <line\n [attr.x1]=\"clockMinuteMarker(i).x1\"\n [attr.y1]=\"clockMinuteMarker(i).y1\"\n [attr.x2]=\"clockMinuteMarker(i).x2\"\n [attr.y2]=\"clockMinuteMarker(i).y2\"\n [attr.stroke-width]=\"i % 5 === 0 ? 2 : 1\"\n [class]=\"i % 5 === 0 ? '_shk-text-surface-500 dark:[color:var(--shk-surface-500)]' : '_shk-text-surface-300 dark:[color:var(--shk-surface-400)]'\"\n stroke=\"currentColor\"\n />\n }\n <!-- Minute numbers (00, 05, 10, ...) -->\n @for (m of [0,5,10,15,20,25,30,35,40,45,50,55]; track m) {\n <text\n [attr.x]=\"clockMinutePos(m).x\"\n [attr.y]=\"clockMinutePos(m).y\"\n text-anchor=\"middle\"\n dominant-baseline=\"central\"\n class=\"text-[9px] _shk-text-surface-500 dark:[color:var(--shk-surface-400)]\"\n [class._shk-text-primary]=\"viewMinute() === m\"\n >\n {{ m.toString().padStart(2, '0') }}\n </text>\n }\n }\n\n <!-- Hour numbers -->\n @if (clockMode() === 'hours') {\n @for (h of clockHours(); track h) {\n <text\n [attr.x]=\"clockNumberPos(h).x\"\n [attr.y]=\"clockNumberPos(h).y\"\n text-anchor=\"middle\"\n dominant-baseline=\"central\"\n class=\"text-sm font-medium\"\n [class._shk-text-primary]=\"isClockHourSelected(h)\"\n [class._shk-text-surface-700]=\"!isClockHourSelected(h)\"\n >\n {{ h }}\n </text>\n }\n }\n\n <!-- Clock hand -->\n <line\n x1=\"100\" y1=\"100\"\n [attr.x2]=\"clockHandLine(60).x2\"\n [attr.y2]=\"clockHandLine(60).y2\"\n class=\"_shk-text-primary\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n\n <!-- Center dot -->\n <circle cx=\"100\" cy=\"100\" r=\"4\" class=\"fill-current _shk-text-primary\" />\n </svg>\n </div>\n\n <!-- Mode toggle: Hours / Minutes -->\n <div class=\"clock-mode-toggle\">\n <button\n type=\"button\"\n (click)=\"clockMode.set('hours')\"\n class=\"clock-mode-btn\"\n [class.active]=\"clockMode() === 'hours'\"\n >\n {{ 'Horas' }}\n </button>\n <button\n type=\"button\"\n (click)=\"clockMode.set('minutes')\"\n class=\"clock-mode-btn\"\n [class.active]=\"clockMode() === 'minutes'\"\n >\n {{ 'Minutos' }}\n </button>\n </div>\n\n <!-- AM/PM toggle for 12h format -->\n @if (hourFormat() === '12') {\n <div class=\"flex items-center justify-center gap-2 mt-2\">\n <button\n type=\"button\"\n (click)=\"viewMeridiem.set('AM')\"\n class=\"px-3 py-1 text-xs font-medium rounded-full transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white': viewMeridiem() === 'AM',\n '_shk-text-surface-500 hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': viewMeridiem() !== 'AM'\n }\"\n >\n AM\n </button>\n <button\n type=\"button\"\n (click)=\"viewMeridiem.set('PM')\"\n class=\"px-3 py-1 text-xs font-medium rounded-full transition-colors\"\n [ngClass]=\"{\n '_shk-bg-primary _shk-text-white': viewMeridiem() === 'PM',\n '_shk-text-surface-500 hover:[background-color:var(--shk-surface-100)] dark:hover:[background-color:var(--shk-surface-200)]': viewMeridiem() !== 'PM'\n }\"\n >\n PM\n </button>\n </div>\n }\n\n <!-- Seconds selector (if enabled) -->\n @if (showSeconds()) {\n <div class=\"flex items-center justify-center gap-1 mt-2\">\n <span class=\"text-xs _shk-text-surface-400\">Seg:</span>\n <select\n class=\"px-2 py-1 text-xs _shk-bg-surface-50 dark:[background-color:var(--shk-surface-100)] _shk-border dark:[border-color:var(--shk-surface-200)] rounded-md\"\n [value]=\"viewSecond()\"\n (change)=\"onSecondChange($event)\"\n aria-label=\"Segundos\"\n >\n @for (seconds of secondsRange(); track seconds) {\n <option [value]=\"seconds\">{{ minutesLabel(seconds) }}</option>\n }\n </select>\n </div>\n }\n\n <!-- Confirm button -->\n <button\n type=\"button\"\n (click)=\"confirmTime()\"\n class=\"mt-3 w-full py-2 text-sm _shk-bg-primary _shk-text-white rounded-lg hover:[background-color:var(--shk-primary-700)] transition-colors\"\n >\n {{ timeOnly() ? 'Confirmar' : 'Introducir hora' }}\n </button>\n </div>\n }\n </div>\n }\n </div>\n\n @if (shouldShowError()) {\n <div [id]=\"id() + '-error'\" class=\"mt-1 text-xs text-red-500 max-h-20 overflow-y-auto _shk-scrollbar\">\n <ul class=\"list-disc pl-4 space-y-1\">\n @for (error of getErrorMessages(); track error) {\n <li>{{ error }}</li>\n }\n </ul>\n </div>\n }\n</div>\n", styles: [".clock-container{position:relative;width:200px;height:200px;margin:0 auto}.clock-face{width:100%;height:100%;border-radius:50%;border:2px solid var(--shk-surface-200);position:relative;background-color:var(--shk-surface-50)}:host-context(.dark) .clock-face{border-color:var(--shk-surface-200);background-color:var(--shk-surface-100)}.clock-number{position:absolute;width:32px;height:32px;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:500;border-radius:50%;transform:translate(-50%,-50%);cursor:pointer;transition:background-color .15s,color .15s;-webkit-user-select:none;user-select:none;color:var(--shk-surface-700)}:host-context(.dark) .clock-number{color:var(--shk-surface-700)}.clock-number:hover{background-color:var(--shk-surface-100)}:host-context(.dark) .clock-number:hover{background-color:var(--shk-surface-200)}.clock-number.selected{background-color:var(--shk-primary-500);color:#fff}.clock-number.current{font-weight:700}.clock-hand{position:absolute;bottom:50%;left:50%;width:2px;background-color:var(--shk-primary-500);transform-origin:bottom center;border-radius:1px;pointer-events:none;transition:transform .2s ease-out}.clock-center{position:absolute;top:50%;left:50%;width:8px;height:8px;border-radius:50%;background-color:var(--shk-primary-500);transform:translate(-50%,-50%);pointer-events:none;z-index:2}.clock-minute-marker{position:absolute;width:1px;height:8px;background-color:var(--shk-surface-300);top:6px;left:50%;transform-origin:center 94px}:host-context(.dark) .clock-minute-marker{background-color:var(--shk-surface-400)}.clock-minute-marker.major{width:2px;height:12px;background-color:var(--shk-surface-400)}:host-context(.dark) .clock-minute-marker.major{background-color:var(--shk-surface-500)}.clock-mode-toggle{display:flex;align-items:center;justify-content:center;gap:.5rem;margin-top:.75rem}.clock-mode-btn{padding:.25rem .75rem;font-size:.75rem;font-weight:500;border-radius:9999px;cursor:pointer;transition:background-color .15s,color .15s;border:none;background:transparent;color:var(--shk-surface-500)}:host-context(.dark) .clock-mode-btn{color:var(--shk-surface-400)}.clock-mode-btn.active{background-color:var(--shk-primary-500);color:#fff}.clock-mode-btn:hover:not(.active){background-color:var(--shk-surface-100)}:host-context(.dark) .clock-mode-btn:hover:not(.active){background-color:var(--shk-surface-200)}.date-input-field{width:100%;padding:.5rem 2.5rem .5rem .75rem;font-size:.875rem;border-radius:.5rem;outline:none;transition:border-color .15s,box-shadow .15s;background-color:var(--shk-surface-50);color:var(--shk-surface-700);border:1px solid var(--shk-surface-200)}:host-context(.dark) .date-input-field{background-color:var(--shk-surface-100);color:var(--shk-surface-700);border-color:var(--shk-surface-200)}.date-input-field::placeholder{color:var(--shk-surface-400)}:host-context(.dark) .date-input-field::placeholder{color:var(--shk-surface-400)}.date-input-field:focus{border-color:var(--shk-primary-500);box-shadow:0 0 0 3px color-mix(in srgb,var(--shk-primary-500) 22%,transparent)}.date-input-field:disabled{background-color:var(--shk-surface-100);border-color:var(--shk-surface-200);color:var(--shk-surface-500);cursor:not-allowed}:host-context(.dark) .date-input-field:disabled{background-color:var(--shk-surface-50);color:var(--shk-surface-400)}.date-input-field.input-error{border-color:#ef4444}.date-input-field.input-error:focus{border-color:#ef4444;box-shadow:0 0 0 3px #ef444433}.date-input-field.input-valid{border-color:#22c55e}.date-input-field.input-valid:focus{border-color:#22c55e;box-shadow:0 0 0 3px #22c55e33}.date-input-field{text-overflow:ellipsis}\n"] }]
1028
+ }], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: false }] }], weekStart: [{ type: i0.Input, args: [{ isSignal: true, alias: "weekStart", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], formGroup: [{ type: i0.Input, args: [{ isSignal: true, alias: "formGroup", required: false }] }], control: [{ type: i0.Input, args: [{ isSignal: true, alias: "control", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], errorMessages: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessages", required: false }] }], minValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "minValue", required: false }] }], maxValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxValue", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], timeOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeOnly", required: false }] }], showTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTime", required: false }] }], hourFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "hourFormat", required: false }] }], showSeconds: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSeconds", required: false }] }], minuteStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "minuteStep", required: false }] }], onDocumentClick: [{
948
1029
  type: HostListener,
949
1030
  args: ['document:click', ['$event']]
950
1031
  }], onEscape: [{