shirkasoft-ui-components 1.3.5 → 1.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/shirkasoft-ui-components-breadcrumb.mjs +6 -6
- package/fesm2022/shirkasoft-ui-components-button.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-chart.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-confirm-dialog.mjs +6 -6
- package/fesm2022/shirkasoft-ui-components-date-picker.mjs +49 -50
- package/fesm2022/shirkasoft-ui-components-date-picker.mjs.map +1 -1
- package/fesm2022/shirkasoft-ui-components-fieldset.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-file-upload.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-knob.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-loading.mjs +12 -12
- package/fesm2022/shirkasoft-ui-components-modal.mjs +6 -6
- package/fesm2022/shirkasoft-ui-components-notification.mjs +6 -6
- package/fesm2022/shirkasoft-ui-components-price-input.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-rail-sidebar.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-select.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-sidebar.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-skeleton.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-table.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-tabs.mjs +18 -18
- package/fesm2022/shirkasoft-ui-components-tag.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-text-field.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-timeline.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-toggle.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-tooltip.mjs +3 -3
- package/fesm2022/shirkasoft-ui-components-wizard.mjs +6 -6
- package/package.json +1 -1
- package/types/shirkasoft-ui-components-date-picker.d.ts +10 -12
|
@@ -75,10 +75,14 @@ class DatePickerComponent {
|
|
|
75
75
|
this.viewMeridiem = signal('AM', ...(ngDevMode ? [{ debugName: "viewMeridiem" }] : /* istanbul ignore next */ []));
|
|
76
76
|
/** Date part selected but not yet committed until the time is confirmed. */
|
|
77
77
|
this.pendingDate = signal(null, ...(ngDevMode ? [{ debugName: "pendingDate" }] : /* istanbul ignore next */ []));
|
|
78
|
+
/** Selected year during the selection flow (year -> month -> day). */
|
|
79
|
+
this.selectedYearValue = signal(null, ...(ngDevMode ? [{ debugName: "selectedYearValue" }] : /* istanbul ignore next */ []));
|
|
80
|
+
/** Selected month during the selection flow. */
|
|
81
|
+
this.selectedMonthValue = signal(null, ...(ngDevMode ? [{ debugName: "selectedMonthValue" }] : /* istanbul ignore next */ []));
|
|
78
82
|
/** Analog clock mode: 'hours' or 'minutes'. */
|
|
79
83
|
this.clockMode = signal('hours', ...(ngDevMode ? [{ debugName: "clockMode" }] : /* istanbul ignore next */ []));
|
|
80
84
|
/** Internal view state for drill-down navigation (separates from input `view`). */
|
|
81
|
-
this.currentView = signal('
|
|
85
|
+
this.currentView = signal('year', ...(ngDevMode ? [{ debugName: "currentView" }] : /* istanbul ignore next */ []));
|
|
82
86
|
/** Whether the user is typing in the input field. */
|
|
83
87
|
this.isTyping = signal(false, ...(ngDevMode ? [{ debugName: "isTyping" }] : /* istanbul ignore next */ []));
|
|
84
88
|
/** The raw text being typed by the user. */
|
|
@@ -232,7 +236,7 @@ class DatePickerComponent {
|
|
|
232
236
|
}, ...(ngDevMode ? [{ debugName: "calendarDays" }] : /* istanbul ignore next */ []));
|
|
233
237
|
/** Whether the prev navigation button is allowed by `minValue`. */
|
|
234
238
|
this.canGoPrev = computed(() => {
|
|
235
|
-
const v = this.
|
|
239
|
+
const v = this.currentView();
|
|
236
240
|
const min = this.minValue();
|
|
237
241
|
if (v === 'date') {
|
|
238
242
|
if (!min)
|
|
@@ -244,12 +248,13 @@ class DatePickerComponent {
|
|
|
244
248
|
const minY = min ? Number(min.split('-')[0]) : undefined;
|
|
245
249
|
return minY === undefined || this.viewYear() > minY;
|
|
246
250
|
}
|
|
247
|
-
|
|
251
|
+
// year view
|
|
252
|
+
const minY = min ? Number(min.split('-')[0]) : undefined;
|
|
248
253
|
return minY === undefined || this.viewYear() > minY;
|
|
249
254
|
}, ...(ngDevMode ? [{ debugName: "canGoPrev" }] : /* istanbul ignore next */ []));
|
|
250
255
|
/** Whether the next navigation button is allowed by `maxValue`. */
|
|
251
256
|
this.canGoNext = computed(() => {
|
|
252
|
-
const v = this.
|
|
257
|
+
const v = this.currentView();
|
|
253
258
|
const max = this.maxValue();
|
|
254
259
|
if (v === 'date') {
|
|
255
260
|
if (!max)
|
|
@@ -261,7 +266,8 @@ class DatePickerComponent {
|
|
|
261
266
|
const maxY = max ? Number(max.split('-')[0]) : undefined;
|
|
262
267
|
return maxY === undefined || this.viewYear() < maxY;
|
|
263
268
|
}
|
|
264
|
-
|
|
269
|
+
// year view
|
|
270
|
+
const maxY = max ? Number(max.split('-')[0]) : undefined;
|
|
265
271
|
return maxY === undefined || this.viewYear() < maxY;
|
|
266
272
|
}, ...(ngDevMode ? [{ debugName: "canGoNext" }] : /* istanbul ignore next */ []));
|
|
267
273
|
/** Year of the displayed date, if any. */
|
|
@@ -302,8 +308,6 @@ class DatePickerComponent {
|
|
|
302
308
|
const loc = this.locale();
|
|
303
309
|
return loc === 'en' ? 'MM/DD/YYYY' : 'DD/MM/YYYY';
|
|
304
310
|
}, ...(ngDevMode ? [{ debugName: "inputFormat" }] : /* istanbul ignore next */ []));
|
|
305
|
-
/** Whether the drill-down navigation is active (view differs from input). */
|
|
306
|
-
this.isDrilledDown = computed(() => this.currentView() !== this.view(), ...(ngDevMode ? [{ debugName: "isDrilledDown" }] : /* istanbul ignore next */ []));
|
|
307
311
|
/** (Unused legacy placeholder) plain year list. */
|
|
308
312
|
this.years = [];
|
|
309
313
|
// Attach error-state subscriptions to the validated control once found.
|
|
@@ -363,7 +367,9 @@ class DatePickerComponent {
|
|
|
363
367
|
}
|
|
364
368
|
else {
|
|
365
369
|
this.syncViewToValue();
|
|
366
|
-
this.currentView.set(
|
|
370
|
+
this.currentView.set('year');
|
|
371
|
+
this.selectedYearValue.set(null);
|
|
372
|
+
this.selectedMonthValue.set(null);
|
|
367
373
|
this.clockMode.set('hours');
|
|
368
374
|
this.isTyping.set(false);
|
|
369
375
|
this.isOpen.set(true);
|
|
@@ -388,6 +394,7 @@ class DatePickerComponent {
|
|
|
388
394
|
const timePart = val.includes('T') ? val.split('T')[1] : undefined;
|
|
389
395
|
if (v === 'year') {
|
|
390
396
|
this.viewYear.set(Number(datePart));
|
|
397
|
+
this.viewDecade.set(Math.floor(Number(datePart) / 10) * 10);
|
|
391
398
|
}
|
|
392
399
|
else if (v === 'month') {
|
|
393
400
|
this.viewYear.set(Number(datePart.split('-')[0]));
|
|
@@ -424,7 +431,7 @@ class DatePickerComponent {
|
|
|
424
431
|
}
|
|
425
432
|
/** Navigates the calendar to the previous year/month/decade. */
|
|
426
433
|
prev() {
|
|
427
|
-
const v = this.
|
|
434
|
+
const v = this.currentView();
|
|
428
435
|
if (v === 'year') {
|
|
429
436
|
this.viewDecade.update((d) => d - 12);
|
|
430
437
|
this.viewYear.update((y) => y - 12);
|
|
@@ -444,7 +451,7 @@ class DatePickerComponent {
|
|
|
444
451
|
}
|
|
445
452
|
/** Navigates the calendar to the next year/month/decade. */
|
|
446
453
|
next() {
|
|
447
|
-
const v = this.
|
|
454
|
+
const v = this.currentView();
|
|
448
455
|
if (v === 'year') {
|
|
449
456
|
this.viewDecade.update((d) => d + 12);
|
|
450
457
|
this.viewYear.update((y) => y + 12);
|
|
@@ -462,30 +469,25 @@ class DatePickerComponent {
|
|
|
462
469
|
});
|
|
463
470
|
}
|
|
464
471
|
}
|
|
465
|
-
/** Selects a
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
const value = `${y}-${m}-${d}`;
|
|
471
|
-
if (this.showTime()) {
|
|
472
|
-
this.pendingDate.set(value);
|
|
473
|
-
return;
|
|
474
|
-
}
|
|
475
|
-
this.setValue(value);
|
|
472
|
+
/** Selects a year - stores it and navigates to month selection. */
|
|
473
|
+
selectYear(year) {
|
|
474
|
+
this.selectedYearValue.set(year);
|
|
475
|
+
this.viewYear.set(year);
|
|
476
|
+
this.currentView.set('month');
|
|
476
477
|
}
|
|
477
|
-
/** Selects a month
|
|
478
|
+
/** Selects a month - stores it and navigates to day selection. */
|
|
478
479
|
selectMonth(monthIndex) {
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
return;
|
|
483
|
-
}
|
|
484
|
-
this.setValue(value);
|
|
480
|
+
this.selectedMonthValue.set(monthIndex);
|
|
481
|
+
this.viewMonth.set(monthIndex);
|
|
482
|
+
this.currentView.set('date');
|
|
485
483
|
}
|
|
486
|
-
/** Selects a
|
|
487
|
-
|
|
488
|
-
const
|
|
484
|
+
/** Selects a day - completes the date selection. */
|
|
485
|
+
selectDay(day) {
|
|
486
|
+
const year = this.selectedYearValue() ?? this.viewYear();
|
|
487
|
+
const month = this.selectedMonthValue() ?? this.viewMonth();
|
|
488
|
+
const m = String(month + 1).padStart(2, '0');
|
|
489
|
+
const d = String(day).padStart(2, '0');
|
|
490
|
+
const value = `${year}-${m}-${d}`;
|
|
489
491
|
if (this.showTime()) {
|
|
490
492
|
this.pendingDate.set(value);
|
|
491
493
|
return;
|
|
@@ -721,21 +723,15 @@ class DatePickerComponent {
|
|
|
721
723
|
y2: 100 + innerR * Math.sin(angle),
|
|
722
724
|
};
|
|
723
725
|
}
|
|
724
|
-
/** Switches the drill-down view to months (from date view). */
|
|
725
|
-
drillToMonths() {
|
|
726
|
-
this.currentView.set('month');
|
|
727
|
-
}
|
|
728
|
-
/** Switches the drill-down view to years (from month view). */
|
|
729
|
-
drillToYears() {
|
|
730
|
-
this.currentView.set('year');
|
|
731
|
-
}
|
|
732
726
|
/** Drills down from year view to month view for the selected year. */
|
|
733
727
|
drillDownToMonth(year) {
|
|
728
|
+
this.selectedYearValue.set(year);
|
|
734
729
|
this.viewYear.set(year);
|
|
735
730
|
this.currentView.set('month');
|
|
736
731
|
}
|
|
737
732
|
/** Drills down from month view to date view for the selected month. */
|
|
738
733
|
drillDownToDate(monthIndex) {
|
|
734
|
+
this.selectedMonthValue.set(monthIndex);
|
|
739
735
|
this.viewMonth.set(monthIndex);
|
|
740
736
|
this.currentView.set('date');
|
|
741
737
|
}
|
|
@@ -743,15 +739,19 @@ class DatePickerComponent {
|
|
|
743
739
|
drillUp() {
|
|
744
740
|
const v = this.currentView();
|
|
745
741
|
if (v === 'date') {
|
|
742
|
+
this.selectedMonthValue.set(null);
|
|
746
743
|
this.currentView.set('month');
|
|
747
744
|
}
|
|
748
745
|
else if (v === 'month') {
|
|
746
|
+
this.selectedYearValue.set(null);
|
|
749
747
|
this.currentView.set('year');
|
|
750
748
|
}
|
|
751
749
|
}
|
|
752
|
-
/** Returns to the initial view
|
|
750
|
+
/** Returns to the initial view (year selection). */
|
|
753
751
|
drillToInitial() {
|
|
754
|
-
this.
|
|
752
|
+
this.selectedYearValue.set(null);
|
|
753
|
+
this.selectedMonthValue.set(null);
|
|
754
|
+
this.currentView.set('year');
|
|
755
755
|
}
|
|
756
756
|
/** Formats input placeholder based on locale. */
|
|
757
757
|
inputPlaceholder() {
|
|
@@ -901,15 +901,14 @@ class DatePickerComponent {
|
|
|
901
901
|
}
|
|
902
902
|
/** Whether the given month matches the selected month and year. */
|
|
903
903
|
isSelectedMonth(monthIndex) {
|
|
904
|
-
return
|
|
905
|
-
this.selectedMonth() === monthIndex);
|
|
904
|
+
return this.selectedMonthValue() === monthIndex;
|
|
906
905
|
}
|
|
907
906
|
isCurrentMonth(monthIndex) {
|
|
908
907
|
const now = new Date();
|
|
909
|
-
return
|
|
908
|
+
return this.viewYear() === now.getFullYear() && monthIndex === now.getMonth();
|
|
910
909
|
}
|
|
911
910
|
isSelectedYear(year) {
|
|
912
|
-
return this.
|
|
911
|
+
return this.selectedYearValue() === year;
|
|
913
912
|
}
|
|
914
913
|
isCurrentYear(year) {
|
|
915
914
|
return new Date().getFullYear() === year;
|
|
@@ -927,16 +926,16 @@ class DatePickerComponent {
|
|
|
927
926
|
this._disabledState.set(isDisabled);
|
|
928
927
|
this.cdr.markForCheck();
|
|
929
928
|
}
|
|
930
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.
|
|
931
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.
|
|
929
|
+
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: [
|
|
932
931
|
{
|
|
933
932
|
provide: NG_VALUE_ACCESSOR,
|
|
934
933
|
useExisting: forwardRef(() => DatePickerComponent),
|
|
935
934
|
multi: true,
|
|
936
935
|
},
|
|
937
|
-
], 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)=\"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 <button\n type=\"button\"\n (click)=\"drillToMonths()\"\n class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)] hover:_shk-text-primary cursor-pointer hover:underline transition-colors\"\n >\n {{ monthNames()[viewMonth()] }} {{ viewYear() }}\n </button>\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-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)=\"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 <button\n type=\"button\"\n (click)=\"drillToYears()\"\n class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)] hover:_shk-text-primary cursor-pointer hover:underline transition-colors\"\n >\n {{ viewYear() }}\n </button>\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 (name of monthNames(); track $index) {\n <button\n type=\"button\"\n (click)=\"drillDownToDate($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)]': isSelectedMonth($index),\n 'ring-1 [--tw-ring-color:var(--shk-primary-500)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]': isCurrentMonth($index) && !isSelectedMonth($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)]': !isSelectedMonth($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)=\"drillDownToMonth(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)]': isSelectedYear(year),\n 'ring-1 [--tw-ring-color:var(--shk-primary-500)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]': isCurrentYear(year) && !isSelectedYear(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)]': !isSelectedYear(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 }); }
|
|
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 }); }
|
|
938
937
|
}
|
|
939
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.
|
|
938
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: DatePickerComponent, decorators: [{
|
|
940
939
|
type: Component,
|
|
941
940
|
args: [{ selector: 'shk-date-picker', standalone: true, imports: [CommonModule, ReactiveFormsModule], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
942
941
|
{
|
|
@@ -944,7 +943,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
|
|
|
944
943
|
useExisting: forwardRef(() => DatePickerComponent),
|
|
945
944
|
multi: true,
|
|
946
945
|
},
|
|
947
|
-
], 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)=\"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 <button\n type=\"button\"\n (click)=\"drillToMonths()\"\n class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)] hover:_shk-text-primary cursor-pointer hover:underline transition-colors\"\n >\n {{ monthNames()[viewMonth()] }} {{ viewYear() }}\n </button>\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-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)=\"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 <button\n type=\"button\"\n (click)=\"drillToYears()\"\n class=\"text-sm font-medium _shk-text-surface-700 dark:[color:var(--shk-surface-600)] hover:_shk-text-primary cursor-pointer hover:underline transition-colors\"\n >\n {{ viewYear() }}\n </button>\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 (name of monthNames(); track $index) {\n <button\n type=\"button\"\n (click)=\"drillDownToDate($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)]': isSelectedMonth($index),\n 'ring-1 [--tw-ring-color:var(--shk-primary-500)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]': isCurrentMonth($index) && !isSelectedMonth($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)]': !isSelectedMonth($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)=\"drillDownToMonth(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)]': isSelectedYear(year),\n 'ring-1 [--tw-ring-color:var(--shk-primary-500)] _shk-text-surface-700 dark:[color:var(--shk-surface-700)]': isCurrentYear(year) && !isSelectedYear(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)]': !isSelectedYear(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"] }]
|
|
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"] }]
|
|
948
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: [{
|
|
949
948
|
type: HostListener,
|
|
950
949
|
args: ['document:click', ['$event']]
|