@brickclay-org/ui 0.0.58 → 0.0.60
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/brickclay-org-ui.mjs +465 -44
- package/fesm2022/brickclay-org-ui.mjs.map +1 -1
- package/index.d.ts +101 -18
- package/package.json +1 -1
- package/src/lib/ui-avatar/ui-avatar.css +71 -0
- package/src/styles.css +1 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Component, EventEmitter, HostListener, ViewChildren, Output, Input, Injectable,
|
|
2
|
+
import { Component, EventEmitter, HostListener, ViewChildren, Output, Input, Injectable, forwardRef, ViewChild, NgModule, ViewEncapsulation, Optional, Self, Directive, input, model, output, signal, computed, effect, inject, ElementRef, InjectionToken, createComponent, ChangeDetectionStrategy } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common';
|
|
4
4
|
import { CommonModule, NgClass } from '@angular/common';
|
|
5
5
|
import * as i1$1 from '@angular/forms';
|
|
6
|
-
import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
6
|
+
import { FormsModule, NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
|
|
7
7
|
import moment from 'moment';
|
|
8
8
|
import { Subject, filter } from 'rxjs';
|
|
9
9
|
import * as i2 from '@angular/cdk/drag-drop';
|
|
@@ -358,6 +358,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
358
358
|
}]
|
|
359
359
|
}] });
|
|
360
360
|
|
|
361
|
+
class CalendarSelection {
|
|
362
|
+
startDate = null;
|
|
363
|
+
endDate = null;
|
|
364
|
+
/** Start time in 12-hour format with AM/PM (e.g. "1:00 AM"). */
|
|
365
|
+
startTime = null;
|
|
366
|
+
/** End time in 12-hour format with AM/PM (e.g. "2:00 AM"). */
|
|
367
|
+
endTime = null;
|
|
368
|
+
selectedDates = []; // For multi-date selection
|
|
369
|
+
}
|
|
361
370
|
class BkCustomCalendar {
|
|
362
371
|
calendarManager;
|
|
363
372
|
// Basic Options
|
|
@@ -384,17 +393,31 @@ class BkCustomCalendar {
|
|
|
384
393
|
placeholder = 'Select date range'; // NEW: Custom placeholder
|
|
385
394
|
opens = 'left'; // NEW: Popup position
|
|
386
395
|
inline = false; // NEW: Always show calendar inline (no popup)
|
|
396
|
+
appendToBody = false; // When true, positions popup with fixed so it isn't clipped inside dialogs/overflow
|
|
387
397
|
isDisplayCrossIcon = true; // NEW: Show/Hide clear (X) icon
|
|
398
|
+
hasError = false; // NEW: Show/Hide clear (X) icon
|
|
399
|
+
errorMessage = '';
|
|
388
400
|
selected = new EventEmitter();
|
|
401
|
+
inputWrapper;
|
|
402
|
+
/** Used when appendToBody is true to position the popup in viewport coordinates */
|
|
403
|
+
dropdownStyle = {};
|
|
389
404
|
opened = new EventEmitter();
|
|
390
405
|
closed = new EventEmitter();
|
|
406
|
+
showCancelApply = true;
|
|
391
407
|
/**
|
|
392
|
-
* External value passed from parent
|
|
393
|
-
* Accepts { startDate:
|
|
408
|
+
* External value passed from parent / ngModel. When used with ngModel, this is the bound value.
|
|
409
|
+
* Accepts { startDate: string|null, endDate: string|null, selectedDates?: string[] }
|
|
394
410
|
*/
|
|
395
411
|
selectedValue = null;
|
|
396
412
|
/** Optional display format for the input value. Uses moment formatting tokens. */
|
|
397
413
|
displayFormat = 'MM/DD/YYYY';
|
|
414
|
+
/** When true, the control is required (used with ngModel for validation: dirty, touched, invalid). */
|
|
415
|
+
required = false;
|
|
416
|
+
/** CVA: called when form control value is set (e.g. ngModel binding) */
|
|
417
|
+
onChange = () => { };
|
|
418
|
+
/** CVA: called when control is touched (blur / close) */
|
|
419
|
+
onTouched = () => { };
|
|
420
|
+
disabled = false;
|
|
398
421
|
brickclayIcons = BrickclayIcons;
|
|
399
422
|
show = false;
|
|
400
423
|
today = new Date();
|
|
@@ -428,6 +451,10 @@ class BkCustomCalendar {
|
|
|
428
451
|
endMinute = 0;
|
|
429
452
|
endSecond = 0;
|
|
430
453
|
endAMPM = 'AM';
|
|
454
|
+
/** Current start time string in 12-hour format with AM/PM (e.g. "1:00 AM"). Synced with ngModel/CalendarSelection. */
|
|
455
|
+
startTime = null;
|
|
456
|
+
/** Current end time string in 12-hour format with AM/PM (e.g. "2:00 AM"). Synced with ngModel/CalendarSelection. */
|
|
457
|
+
endTime = null;
|
|
431
458
|
// Track open time-picker within this calendar (for single-open behavior)
|
|
432
459
|
openTimePickerId = null;
|
|
433
460
|
closePickerCounter = {};
|
|
@@ -440,6 +467,138 @@ class BkCustomCalendar {
|
|
|
440
467
|
constructor(calendarManager) {
|
|
441
468
|
this.calendarManager = calendarManager;
|
|
442
469
|
}
|
|
470
|
+
// --- ControlValueAccessor implementation ---
|
|
471
|
+
writeValue(value) {
|
|
472
|
+
this.selectedValue = value ?? null;
|
|
473
|
+
this.applyValueToState(this.selectedValue);
|
|
474
|
+
}
|
|
475
|
+
registerOnChange(fn) {
|
|
476
|
+
this.onChange = fn;
|
|
477
|
+
}
|
|
478
|
+
registerOnTouched(fn) {
|
|
479
|
+
this.onTouched = fn;
|
|
480
|
+
}
|
|
481
|
+
setDisabledState(isDisabled) {
|
|
482
|
+
this.disabled = isDisabled;
|
|
483
|
+
}
|
|
484
|
+
/** Call from template when control loses focus (for CVA touched state). */
|
|
485
|
+
markAsTouched() {
|
|
486
|
+
this.onTouched();
|
|
487
|
+
}
|
|
488
|
+
/** Apply CalendarSelection to internal state (startDate, endDate, startTime, endTime, selectedDates, calendar view). */
|
|
489
|
+
applyValueToState(value) {
|
|
490
|
+
if (!value) {
|
|
491
|
+
this.startDate = null;
|
|
492
|
+
this.endDate = null;
|
|
493
|
+
this.startTime = null;
|
|
494
|
+
this.endTime = null;
|
|
495
|
+
this.selectedDates = [];
|
|
496
|
+
this.month = this.today.getMonth();
|
|
497
|
+
this.year = this.today.getFullYear();
|
|
498
|
+
this.generateCalendar();
|
|
499
|
+
if (this.dualCalendar) {
|
|
500
|
+
this.initializeDual();
|
|
501
|
+
}
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
const s = value;
|
|
505
|
+
this.startDate = s.startDate ? new Date(s.startDate) : null;
|
|
506
|
+
this.endDate = s.endDate ? new Date(s.endDate) : null;
|
|
507
|
+
this.selectedDates = (s.selectedDates || []).map((d) => new Date(d));
|
|
508
|
+
this.startTime = s.startTime ?? null;
|
|
509
|
+
this.endTime = s.endTime ?? null;
|
|
510
|
+
const focusDate = this.startDate ?? this.endDate ?? new Date();
|
|
511
|
+
this.month = focusDate.getMonth();
|
|
512
|
+
this.year = focusDate.getFullYear();
|
|
513
|
+
if (this.dualCalendar) {
|
|
514
|
+
this.initializeDual();
|
|
515
|
+
if (this.startDate) {
|
|
516
|
+
this.leftMonth = this.startDate.getMonth();
|
|
517
|
+
this.leftYear = this.startDate.getFullYear();
|
|
518
|
+
}
|
|
519
|
+
if (this.endDate && this.startDate) {
|
|
520
|
+
const startMonth = this.startDate.getMonth();
|
|
521
|
+
const startYear = this.startDate.getFullYear();
|
|
522
|
+
const endMonth = this.endDate.getMonth();
|
|
523
|
+
const endYear = this.endDate.getFullYear();
|
|
524
|
+
if (endMonth !== startMonth || endYear !== startYear) {
|
|
525
|
+
this.rightMonth = endMonth;
|
|
526
|
+
this.rightYear = endYear;
|
|
527
|
+
}
|
|
528
|
+
else {
|
|
529
|
+
this.rightMonth = this.leftMonth + 1;
|
|
530
|
+
this.rightYear = this.leftYear;
|
|
531
|
+
if (this.rightMonth > 11) {
|
|
532
|
+
this.rightMonth = 0;
|
|
533
|
+
this.rightYear++;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
else if (this.endDate && !this.startDate) {
|
|
538
|
+
this.rightMonth = this.endDate.getMonth();
|
|
539
|
+
this.rightYear = this.endDate.getFullYear();
|
|
540
|
+
}
|
|
541
|
+
else {
|
|
542
|
+
this.rightMonth = this.leftMonth + 1;
|
|
543
|
+
this.rightYear = this.leftYear;
|
|
544
|
+
if (this.rightMonth > 11) {
|
|
545
|
+
this.rightMonth = 0;
|
|
546
|
+
this.rightYear++;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
this.generateDualCalendars();
|
|
550
|
+
}
|
|
551
|
+
else {
|
|
552
|
+
this.generateCalendar();
|
|
553
|
+
}
|
|
554
|
+
if (this.startTime) {
|
|
555
|
+
const startParsed = this.parsePickerTimeString(this.startTime);
|
|
556
|
+
this.startHour = startParsed.hour12;
|
|
557
|
+
this.startMinute = startParsed.minute;
|
|
558
|
+
this.startAMPM = startParsed.ampm;
|
|
559
|
+
if (this.startDate) {
|
|
560
|
+
let h24 = startParsed.hour12;
|
|
561
|
+
if (startParsed.ampm === 'PM' && h24 < 12)
|
|
562
|
+
h24 += 12;
|
|
563
|
+
if (startParsed.ampm === 'AM' && h24 === 12)
|
|
564
|
+
h24 = 0;
|
|
565
|
+
this.startDate.setHours(h24, startParsed.minute, this.startSecond);
|
|
566
|
+
}
|
|
567
|
+
this.selectedHour = this.startHour;
|
|
568
|
+
this.selectedMinute = this.startMinute;
|
|
569
|
+
this.selectedAMPM = this.startAMPM;
|
|
570
|
+
}
|
|
571
|
+
else if (this.startDate) {
|
|
572
|
+
this.initializeTimeFromDate(this.startDate, true);
|
|
573
|
+
this.startTime = this.formatTimeToAmPm(this.startHour, this.startMinute, this.startAMPM);
|
|
574
|
+
}
|
|
575
|
+
if (this.endTime) {
|
|
576
|
+
const endParsed = this.parsePickerTimeString(this.endTime);
|
|
577
|
+
this.endHour = endParsed.hour12;
|
|
578
|
+
this.endMinute = endParsed.minute;
|
|
579
|
+
this.endAMPM = endParsed.ampm;
|
|
580
|
+
if (this.endDate) {
|
|
581
|
+
let h24 = endParsed.hour12;
|
|
582
|
+
if (endParsed.ampm === 'PM' && h24 < 12)
|
|
583
|
+
h24 += 12;
|
|
584
|
+
if (endParsed.ampm === 'AM' && h24 === 12)
|
|
585
|
+
h24 = 0;
|
|
586
|
+
this.endDate.setHours(h24, endParsed.minute, this.endSecond);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
else if (this.endDate) {
|
|
590
|
+
this.initializeTimeFromDate(this.endDate, false);
|
|
591
|
+
this.endTime = this.formatTimeToAmPm(this.endHour, this.endMinute, this.endAMPM);
|
|
592
|
+
}
|
|
593
|
+
if (this.startDate && this.endDate) {
|
|
594
|
+
this.checkAndSetActiveRange();
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
/** Format to "H:MM AM/PM" string. */
|
|
598
|
+
formatTimeToAmPm(hour12, minute, ampm) {
|
|
599
|
+
const m = minute.toString().padStart(2, '0');
|
|
600
|
+
return `${hour12}:${m} ${ampm}`;
|
|
601
|
+
}
|
|
443
602
|
onClickOutside(event) {
|
|
444
603
|
// Don't handle click outside if inline mode is enabled
|
|
445
604
|
if (this.inline) {
|
|
@@ -450,6 +609,11 @@ class BkCustomCalendar {
|
|
|
450
609
|
this.close();
|
|
451
610
|
}
|
|
452
611
|
}
|
|
612
|
+
onWindowEvents() {
|
|
613
|
+
if (this.show && this.appendToBody) {
|
|
614
|
+
this.close();
|
|
615
|
+
}
|
|
616
|
+
}
|
|
453
617
|
ngOnInit() {
|
|
454
618
|
if (!this.customRanges) {
|
|
455
619
|
this.initializeDefaultRanges();
|
|
@@ -502,24 +666,8 @@ class BkCustomCalendar {
|
|
|
502
666
|
});
|
|
503
667
|
}
|
|
504
668
|
ngOnChanges(changes) {
|
|
505
|
-
if (changes['selectedValue']
|
|
506
|
-
|
|
507
|
-
const s = this.selectedValue;
|
|
508
|
-
this.startDate = s.startDate ? new Date(s.startDate) : null;
|
|
509
|
-
this.endDate = s.endDate ? new Date(s.endDate) : null;
|
|
510
|
-
this.selectedDates = (s.selectedDates || []).map((d) => new Date(d));
|
|
511
|
-
// Update calendar month/year to show the start date (or end date if start missing)
|
|
512
|
-
const focusDate = this.startDate ?? this.endDate ?? new Date();
|
|
513
|
-
this.month = focusDate.getMonth();
|
|
514
|
-
this.year = focusDate.getFullYear();
|
|
515
|
-
if (this.dualCalendar) {
|
|
516
|
-
this.initializeDual();
|
|
517
|
-
}
|
|
518
|
-
else {
|
|
519
|
-
this.generateCalendar();
|
|
520
|
-
}
|
|
521
|
-
// Re-evaluate active range if any
|
|
522
|
-
this.checkAndSetActiveRange();
|
|
669
|
+
if (changes['selectedValue']) {
|
|
670
|
+
this.applyValueToState(this.selectedValue ?? null);
|
|
523
671
|
}
|
|
524
672
|
}
|
|
525
673
|
ngOnDestroy() {
|
|
@@ -605,6 +753,8 @@ class BkCustomCalendar {
|
|
|
605
753
|
}
|
|
606
754
|
}
|
|
607
755
|
toggle() {
|
|
756
|
+
if (this.disabled)
|
|
757
|
+
return;
|
|
608
758
|
// Don't toggle if inline mode is enabled
|
|
609
759
|
if (this.inline) {
|
|
610
760
|
return;
|
|
@@ -612,6 +762,9 @@ class BkCustomCalendar {
|
|
|
612
762
|
const wasOpen = this.show;
|
|
613
763
|
this.show = !this.show;
|
|
614
764
|
if (this.show) {
|
|
765
|
+
if (this.appendToBody && this.inputWrapper?.nativeElement) {
|
|
766
|
+
this.updatePosition();
|
|
767
|
+
}
|
|
615
768
|
// If opening, close all other calendars first
|
|
616
769
|
if (!wasOpen && this.closeFn) {
|
|
617
770
|
this.calendarManager.closeAllExcept(this.closeFn);
|
|
@@ -623,12 +776,31 @@ class BkCustomCalendar {
|
|
|
623
776
|
this.closed.emit();
|
|
624
777
|
}
|
|
625
778
|
}
|
|
779
|
+
/** Update popup position when appendToBody is true (fixed positioning relative to viewport). */
|
|
780
|
+
updatePosition() {
|
|
781
|
+
if (!this.inputWrapper?.nativeElement)
|
|
782
|
+
return;
|
|
783
|
+
const rect = this.inputWrapper.nativeElement.getBoundingClientRect();
|
|
784
|
+
if (this.drop === 'up') {
|
|
785
|
+
this.dropdownStyle = {
|
|
786
|
+
bottom: `${window.innerHeight - rect.top + 4}px`,
|
|
787
|
+
left: `${rect.left}px`
|
|
788
|
+
};
|
|
789
|
+
}
|
|
790
|
+
else {
|
|
791
|
+
this.dropdownStyle = {
|
|
792
|
+
top: `${rect.bottom + 4}px`,
|
|
793
|
+
left: `${rect.left}px`
|
|
794
|
+
};
|
|
795
|
+
}
|
|
796
|
+
}
|
|
626
797
|
close() {
|
|
627
798
|
// Don't close if inline mode is enabled
|
|
628
799
|
if (this.inline) {
|
|
629
800
|
return;
|
|
630
801
|
}
|
|
631
802
|
this.show = false;
|
|
803
|
+
this.onTouched();
|
|
632
804
|
this.closed.emit();
|
|
633
805
|
}
|
|
634
806
|
onDateHover(day, fromRight = false) {
|
|
@@ -654,7 +826,7 @@ class BkCustomCalendar {
|
|
|
654
826
|
this.hoveredDate = null;
|
|
655
827
|
}
|
|
656
828
|
selectDate(day, fromRight = false) {
|
|
657
|
-
if (!day)
|
|
829
|
+
if (!day || this.disabled)
|
|
658
830
|
return;
|
|
659
831
|
let selected;
|
|
660
832
|
if (!this.dualCalendar) {
|
|
@@ -838,6 +1010,8 @@ class BkCustomCalendar {
|
|
|
838
1010
|
return this.selectedDates.some(d => this.getDateString(d) === this.getDateString(cellDate));
|
|
839
1011
|
}
|
|
840
1012
|
apply() {
|
|
1013
|
+
if (this.disabled)
|
|
1014
|
+
return;
|
|
841
1015
|
// Format minute inputs to 2 digits before applying
|
|
842
1016
|
this.formatAllMinuteInputs();
|
|
843
1017
|
// Apply time to dates
|
|
@@ -865,17 +1039,38 @@ class BkCustomCalendar {
|
|
|
865
1039
|
this.checkAndSetActiveRange();
|
|
866
1040
|
this.emitSelection();
|
|
867
1041
|
this.disableHighlight = true;
|
|
1042
|
+
this.onTouched();
|
|
868
1043
|
this.close();
|
|
869
1044
|
}
|
|
870
1045
|
cancel() {
|
|
1046
|
+
if (this.disabled)
|
|
1047
|
+
return;
|
|
871
1048
|
this.startDate = null;
|
|
872
1049
|
this.endDate = null;
|
|
873
1050
|
this.selectedDates = [];
|
|
874
1051
|
this.close();
|
|
875
1052
|
}
|
|
876
1053
|
clear() {
|
|
1054
|
+
if (this.disabled)
|
|
1055
|
+
return;
|
|
877
1056
|
this.startDate = null;
|
|
878
1057
|
this.endDate = null;
|
|
1058
|
+
this.startTime = null;
|
|
1059
|
+
this.endTime = null;
|
|
1060
|
+
// Time picker for single calendar (12-hour format: 1-12)
|
|
1061
|
+
this.selectedHour = 1;
|
|
1062
|
+
this.selectedMinute = 0;
|
|
1063
|
+
this.selectedSecond = 0;
|
|
1064
|
+
this.selectedAMPM = 'AM';
|
|
1065
|
+
// NEW: Separate time pickers for dual calendar (12-hour format: 1-12)
|
|
1066
|
+
this.startHour = 1;
|
|
1067
|
+
this.startMinute = 0;
|
|
1068
|
+
this.startSecond = 0;
|
|
1069
|
+
this.startAMPM = 'AM';
|
|
1070
|
+
this.endHour = 2;
|
|
1071
|
+
this.endMinute = 0;
|
|
1072
|
+
this.endSecond = 0;
|
|
1073
|
+
this.endAMPM = 'AM';
|
|
879
1074
|
this.selectedDates = [];
|
|
880
1075
|
this.activeRange = null; // Clear active range
|
|
881
1076
|
// Reset right calendar to original position (next month after left) when end date is cleared
|
|
@@ -891,7 +1086,7 @@ class BkCustomCalendar {
|
|
|
891
1086
|
this.emitSelection();
|
|
892
1087
|
}
|
|
893
1088
|
chooseRange(key) {
|
|
894
|
-
if (!this.customRanges)
|
|
1089
|
+
if (this.disabled || !this.customRanges)
|
|
895
1090
|
return;
|
|
896
1091
|
// Don't allow selecting "Custom Range" directly - it's only activated when manually selecting dates
|
|
897
1092
|
if (key === 'Custom Range')
|
|
@@ -975,13 +1170,32 @@ class BkCustomCalendar {
|
|
|
975
1170
|
// this.selected.emit(selection);
|
|
976
1171
|
// }
|
|
977
1172
|
emitSelection() {
|
|
1173
|
+
const hasValue = this.startDate != null ||
|
|
1174
|
+
this.endDate != null ||
|
|
1175
|
+
(this.multiDateSelection && this.selectedDates.length > 0);
|
|
1176
|
+
if (!hasValue) {
|
|
1177
|
+
this.selectedValue = null;
|
|
1178
|
+
this.onChange(null);
|
|
1179
|
+
this.selected.emit({
|
|
1180
|
+
startDate: null,
|
|
1181
|
+
endDate: null,
|
|
1182
|
+
startTime: null,
|
|
1183
|
+
endTime: null,
|
|
1184
|
+
selectedDates: [],
|
|
1185
|
+
});
|
|
1186
|
+
return;
|
|
1187
|
+
}
|
|
978
1188
|
const selection = {
|
|
979
1189
|
startDate: this.startDate ? this.formatDateToString(this.startDate) : null,
|
|
980
1190
|
endDate: this.endDate ? this.formatDateToString(this.endDate) : null,
|
|
1191
|
+
startTime: this.startTime ?? (this.startDate ? this.formatTimeToAmPm(this.startHour, this.startMinute, this.startAMPM) : null),
|
|
1192
|
+
endTime: this.endTime ?? (this.endDate ? this.formatTimeToAmPm(this.endHour, this.endMinute, this.endAMPM) : null),
|
|
981
1193
|
};
|
|
982
1194
|
if (this.multiDateSelection && this.selectedDates.length > 0) {
|
|
983
|
-
selection.selectedDates = this.selectedDates.map(d => this.formatDateToString(d));
|
|
1195
|
+
selection.selectedDates = this.selectedDates.map((d) => this.formatDateToString(d));
|
|
984
1196
|
}
|
|
1197
|
+
this.selectedValue = selection;
|
|
1198
|
+
this.onChange(selection);
|
|
985
1199
|
this.selected.emit(selection);
|
|
986
1200
|
}
|
|
987
1201
|
addDays(date, days) {
|
|
@@ -1316,6 +1530,8 @@ class BkCustomCalendar {
|
|
|
1316
1530
|
this.selectedHour = hour12;
|
|
1317
1531
|
this.selectedMinute = minute;
|
|
1318
1532
|
this.selectedAMPM = ampm;
|
|
1533
|
+
const timeStr = this.formatTimeToAmPm(hour12, minute, ampm);
|
|
1534
|
+
this.startTime = timeStr;
|
|
1319
1535
|
if (this.startDate) {
|
|
1320
1536
|
let h24 = hour12;
|
|
1321
1537
|
if (ampm === 'PM' && h24 < 12)
|
|
@@ -1323,16 +1539,18 @@ class BkCustomCalendar {
|
|
|
1323
1539
|
if (ampm === 'AM' && h24 === 12)
|
|
1324
1540
|
h24 = 0;
|
|
1325
1541
|
this.startDate.setHours(h24, minute, this.selectedSecond);
|
|
1326
|
-
this.emitSelection();
|
|
1327
1542
|
}
|
|
1543
|
+
this.emitSelection();
|
|
1328
1544
|
}
|
|
1329
1545
|
// NEW: Handle BkTimePicker change for dual calendar
|
|
1330
1546
|
onDualTimePickerChange(time, isStart = true) {
|
|
1331
1547
|
const { hour12, minute, ampm } = this.parsePickerTimeString(time);
|
|
1548
|
+
const timeStr = this.formatTimeToAmPm(hour12, minute, ampm);
|
|
1332
1549
|
if (isStart) {
|
|
1333
1550
|
this.startHour = hour12;
|
|
1334
1551
|
this.startMinute = minute;
|
|
1335
1552
|
this.startAMPM = ampm;
|
|
1553
|
+
this.startTime = timeStr;
|
|
1336
1554
|
if (this.startDate) {
|
|
1337
1555
|
let h24 = hour12;
|
|
1338
1556
|
if (ampm === 'PM' && h24 < 12)
|
|
@@ -1346,6 +1564,7 @@ class BkCustomCalendar {
|
|
|
1346
1564
|
this.endHour = hour12;
|
|
1347
1565
|
this.endMinute = minute;
|
|
1348
1566
|
this.endAMPM = ampm;
|
|
1567
|
+
this.endTime = timeStr;
|
|
1349
1568
|
if (this.endDate) {
|
|
1350
1569
|
let h24 = hour12;
|
|
1351
1570
|
if (ampm === 'PM' && h24 < 12)
|
|
@@ -1875,11 +2094,23 @@ class BkCustomCalendar {
|
|
|
1875
2094
|
return `${yyyy}-${mm}-${dd}`;
|
|
1876
2095
|
}
|
|
1877
2096
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkCustomCalendar, deps: [{ token: CalendarManagerService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1878
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: BkCustomCalendar, isStandalone: true, selector: "bk-custom-calendar", inputs: { enableTimepicker: "enableTimepicker", autoApply: "autoApply", closeOnAutoApply: "closeOnAutoApply", showCancel: "showCancel", linkedCalendars: "linkedCalendars", singleDatePicker: "singleDatePicker", showWeekNumbers: "showWeekNumbers", showISOWeekNumbers: "showISOWeekNumbers", customRangeDirection: "customRangeDirection", lockStartDate: "lockStartDate", position: "position", drop: "drop", dualCalendar: "dualCalendar", showRanges: "showRanges", timeFormat: "timeFormat", enableSeconds: "enableSeconds", customRanges: "customRanges", multiDateSelection: "multiDateSelection", maxDate: "maxDate", minDate: "minDate", placeholder: "placeholder", opens: "opens", inline: "inline", isDisplayCrossIcon: "isDisplayCrossIcon", selectedValue: "selectedValue", displayFormat: "displayFormat", startDate: "startDate", endDate: "endDate" }, outputs: { selected: "selected", opened: "opened", closed: "closed" }, host: { listeners: { "document:click": "onClickOutside($event)" } }, usesOnChanges: true, ngImport: i0, template: "<div class=\"calendar-container relative\" [class.open]=\"show\" [class.inline-mode]=\"inline\">\r\n <!-- Input field -->\r\n <div class=\"input-wrapper\" *ngIf=\"!inline\">\r\n <input\r\n type=\"text\"\r\n (click)=\"toggle()\"\r\n readonly\r\n [value]=\"getDisplayValue()\"\r\n [placeholder]=\"placeholder\"\r\n class=\"calendar-input\">\r\n <!-- *ngIf=\"!getDisplayValue()\" -->\r\n\r\n <span class=\"calendar-icon\" >\r\n <img alt=\"calendar\" class=\"calendar-icon-img\" [src]='brickclayIcons.calenderIcon'/>\r\n </span>\r\n <button class=\"clear-btn\" *ngIf=\"getDisplayValue() && isDisplayCrossIcon\" (click)=\"clear(); $event.stopPropagation()\" title=\"Clear\">\u00D7</button>\r\n </div>\r\n\r\n <!-- Calendar Popup / Inline -->\r\n <div class=\"calendar-popup\"\r\n [class.inline-calendar]=\"inline\"\r\n [ngClass]=\"{\r\n 'position-right': !inline && opens === 'right',\r\n 'position-center': !inline && opens === 'center',\r\n 'drop-up': !inline && drop === 'up',\r\n 'has-ranges': showRanges && customRanges,\r\n 'dual-calendar-mode': dualCalendar\r\n }\"\r\n *ngIf=\"inline || show\">\r\n\r\n <!-- RANGES -->\r\n <div class=\"ranges\" *ngIf=\"showRanges && customRanges\">\r\n <button\r\n *ngFor=\"let rangeKey of rangeOrder\"\r\n (click)=\"chooseRange(rangeKey)\"\r\n [class.active]=\"activeRange === rangeKey\"\r\n [class.custom-range]=\"rangeKey === 'Custom Range'\"\r\n class=\"range-btn\"\r\n [disabled]=\"rangeKey === 'Custom Range'\">\r\n {{ rangeKey }}\r\n </button>\r\n </div>\r\n<div class=\"\" [ngClass]=\"showRanges ? 'w-100 flex-grow-1' : ''\">\r\n\r\n\r\n <!-- SINGLE CALENDAR -->\r\n <div *ngIf=\"!dualCalendar\" class=\"calendar-wrapper\">\r\n <div class=\"header\">\r\n <!-- <button (click)=\"prevMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img src=\"assets/calender/pagination-left-gray.svg\" alt=\"arrow-left\" class=\"arrow-left\">\r\n </button> -->\r\n <button class=\"nav-btn\" type=\"button\" (click)=\"prevMonth()\" matTooltip=\"Prev month\"\r\n >\r\n <img alt=\"prev\" class=\"h-3 w-3\" [src]=\"brickclayIcons.arrowleft\"/>\r\n </button>\r\n <span class=\"month-year\">{{ getMonthName(month) }} {{ year }}</span>\r\n <!-- <button (click)=\"nextMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img src=\"assets/calender/pagination-right-gray.svg\" alt=\"arrow-right\" class=\"arrow-right\">\r\n </button> -->\r\n <button class=\"nav-btn\" type=\"button\" (click)=\"nextMonth()\" matTooltip=\"Next month\"\r\n >\r\n <img alt=\"next\" class=\"h-3 w-3\" [src]='brickclayIcons.arrowRight'/>\r\n <!--<img src=\"assets/calender/pagination-right-gray.svg\" alt=\"next\" class=\"h-3 w-3\" /> -->\r\n </button>\r\n </div>\r\n\r\n <table class=\"calendar-table\">\r\n <thead>\r\n <tr>\r\n <th *ngFor=\"let d of ['Mo','Tu','We','Th','Fr','Sa','Su']\" class=\"weekday-header\">{{ d }}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let week of calendar\">\r\n <td\r\n *ngFor=\"let dayObj of week\"\r\n (click)=\"dayObj.currentMonth && !isDateDisabled(year, month, dayObj.day) && selectDate(dayObj.day)\"\r\n (mouseenter)=\"dayObj.currentMonth && !isDateDisabled(year, month, dayObj.day) && onDateHover(dayObj.day, false)\"\r\n (mouseleave)=\"onDateLeave()\"\r\n [class.active]=\"dayObj.currentMonth && isDateSelected(year, month, dayObj.day)\"\r\n [class.in-range]=\"dayObj.currentMonth && isDateInRange(year, month, dayObj.day)\"\r\n [class.other-month]=\"!dayObj.currentMonth\"\r\n [class.disabled]=\"isDateDisabled(year, month, dayObj.day)\"\r\n [class.multi-selected]=\"multiDateSelection && isDateInMultiSelection(year, month, dayObj.day)\"\r\n [class.today]=\"dayObj.currentMonth && isToday(year, month, dayObj.day)\"\r\n class=\"calendar-day\">\r\n {{ dayObj.day }}\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <!-- Single Calendar Time Picker -->\r\n <div *ngIf=\"enableTimepicker\" class=\"timepicker-section\">\r\n <div class=\"timepicker-label\">Time</div>\r\n <div class=\"timepicker-controls\">\r\n <bk-time-picker\r\n pickerId=\"single-time\"\r\n [label]=\"''\"\r\n [value]=\"getSingleTimePickerDisplay()\"\r\n [closePicker]=\"shouldClosePicker('single-time')\"\r\n (timeChange)=\"onSingleTimePickerChange($event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- DUAL CALENDAR -->\r\n <div class=\"dual-calendar\" *ngIf=\"dualCalendar\">\r\n <!-- LEFT CALENDAR -->\r\n <div class=\"calendar-left\">\r\n <div class=\"header\">\r\n <button (click)=\"prevLeftMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-left\" class=\"arrow-left\" [src]=\"brickclayIcons.arrowleft\"/>\r\n </button>\r\n <span class=\"month-year\">{{ getMonthName(leftMonth) }} {{ leftYear }}</span>\r\n <button (click)=\"nextLeftMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-right\" class=\"arrow-right\" [src]='brickclayIcons.arrowRight'/>\r\n </button>\r\n </div>\r\n <table class=\"calendar-table\">\r\n <thead>\r\n <tr>\r\n <th *ngFor=\"let d of ['Mo','Tu','We','Th','Fr','Sa','Su']\" class=\"weekday-header\">{{ d }}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let week of leftCalendar\">\r\n <td\r\n *ngFor=\"let dayObj of week\"\r\n (click)=\"dayObj.currentMonth && !isDateDisabled(leftYear, leftMonth, dayObj.day) && selectDate(dayObj.day, false)\"\r\n (mouseenter)=\"dayObj.currentMonth && !isDateDisabled(leftYear, leftMonth, dayObj.day) && onDateHover(dayObj.day, false)\"\r\n (mouseleave)=\"onDateLeave()\"\r\n [class.active]=\"dayObj.currentMonth && isDateSelected(leftYear, leftMonth, dayObj.day)\"\r\n [class.in-range]=\"dayObj.currentMonth && isDateInRange(leftYear, leftMonth, dayObj.day)\"\r\n [class.other-month]=\"!dayObj.currentMonth\"\r\n [class.disabled]=\"isDateDisabled(leftYear, leftMonth, dayObj.day)\"\r\n [class.multi-selected]=\"multiDateSelection && isDateInMultiSelection(leftYear, leftMonth, dayObj.day)\"\r\n [class.today]=\"dayObj.currentMonth && isToday(leftYear, leftMonth, dayObj.day)\"\r\n class=\"calendar-day\">\r\n {{ dayObj.day }}\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <!-- Start Time Picker for Dual Calendar -->\r\n <div *ngIf=\"enableTimepicker\" class=\"timepicker-section\">\r\n <div class=\"timepicker-label\">Start Time</div>\r\n <div class=\"timepicker-controls\">\r\n <bk-time-picker\r\n pickerId=\"dual-start\"\r\n [label]=\"''\"\r\n [value]=\"getDualTimePickerDisplay(true)\"\r\n [closePicker]=\"shouldClosePicker('dual-start')\"\r\n (timeChange)=\"onDualTimePickerChange($event, true)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT CALENDAR -->\r\n <div class=\"calendar-right\">\r\n <div class=\"header\">\r\n <button (click)=\"prevRightMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-left\" class=\"arrow-left\" [src]=\"brickclayIcons.arrowleft\"/>\r\n </button>\r\n <span class=\"month-year\">{{ getMonthName(rightMonth) }} {{ rightYear }}</span>\r\n <button (click)=\"nextRightMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-right\" class=\"arrow-right\" [src]='brickclayIcons.arrowRight'/>\r\n </button>\r\n </div>\r\n <table class=\"calendar-table\">\r\n <thead>\r\n <tr>\r\n <th *ngFor=\"let d of ['Mo','Tu','We','Th','Fr','Sa','Su']\" class=\"weekday-header\">{{ d }}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let week of rightCalendar\">\r\n <td\r\n *ngFor=\"let dayObj of week\"\r\n (click)=\"dayObj.currentMonth && !isDateDisabled(rightYear, rightMonth, dayObj.day) && selectDate(dayObj.day, true)\"\r\n (mouseenter)=\"dayObj.currentMonth && !isDateDisabled(rightYear, rightMonth, dayObj.day) && onDateHover(dayObj.day, true)\"\r\n (mouseleave)=\"onDateLeave()\"\r\n [class.active]=\"dayObj.currentMonth && isDateSelected(rightYear, rightMonth, dayObj.day)\"\r\n [class.in-range]=\"dayObj.currentMonth && isDateInRange(rightYear, rightMonth, dayObj.day)\"\r\n [class.other-month]=\"!dayObj.currentMonth\"\r\n [class.disabled]=\"isDateDisabled(rightYear, rightMonth, dayObj.day)\"\r\n [class.multi-selected]=\"multiDateSelection && isDateInMultiSelection(rightYear, rightMonth, dayObj.day)\"\r\n [class.today]=\"dayObj.currentMonth && isToday(rightYear, rightMonth, dayObj.day)\"\r\n class=\"calendar-day\">\r\n {{ dayObj.day }}\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <!-- End Time Picker for Dual Calendar -->\r\n <div *ngIf=\"enableTimepicker\" class=\"timepicker-section\">\r\n <div class=\"timepicker-label\">End Time</div>\r\n <div class=\"timepicker-controls\">\r\n <bk-time-picker\r\n pickerId=\"dual-end\"\r\n [label]=\"''\"\r\n [value]=\"getDualTimePickerDisplay(false)\"\r\n [closePicker]=\"shouldClosePicker('dual-end')\"\r\n (timeChange)=\"onDualTimePickerChange($event, false)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- FOOTER -->\r\n <div class=\"footer\" *ngIf=\"!inline\">\r\n <button *ngIf=\"showCancel\" (click)=\"cancel()\" class=\"btn-cancel\" type=\"button\">Cancel</button>\r\n <button (click)=\"apply()\" class=\"btn-apply\" type=\"button\">Apply</button>\r\n </div>\r\n\r\n </div>\r\n\r\n </div>\r\n</div>\r\n", styles: [".calendar-container,.calendar-container *{font-family:Inter,sans-serif!important}.calendar-container{position:relative;display:inline-block;width:100%}.input-wrapper{position:relative;display:flex;align-items:center}.calendar-input{width:100%;padding:9px 14px 9px 40px;border:1px solid #ddd;border-radius:8px;font-size:14px;cursor:pointer;background:#fff;transition:all .2s}.calendar-input:hover{border-color:#999}.calendar-input:focus{outline:none;border-color:#999;box-shadow:0 0 0 3px #6a6a6a1a}.calendar-icon{position:absolute;left:12px;pointer-events:none;font-size:18px}.clear-btn{position:absolute;right:9px;background:none;border:none;font-size:20px;color:#999;cursor:pointer;padding:0;width:20px;height:20px;display:flex;align-items:center;justify-content:center;line-height:1;transition:color .2s;top:8px}.clear-btn:hover{color:#333}.calendar-popup{position:absolute;top:110%;left:0;width:320px;background:#fff;border-radius:12px;box-shadow:0 10px 40px #00000026;z-index:1000;animation:slideDown .2s ease-out}.calendar-popup.inline-calendar{position:relative;top:0;left:0;width:100%;margin-top:0;animation:none;box-shadow:0 2px 8px #0000001a}.calendar-container.inline-mode{display:block;width:100%}.calendar-popup.dual-calendar-mode{width:600px}.calendar-popup.dual-calendar-mode.has-ranges{width:730px}.calendar-popup.has-ranges{width:450px}.calendar-popup.dual-calendar-mode.has-ranges .dual-calendar{border-left:1px solid #eee}.calendar-popup.drop-up{top:auto;bottom:110%;animation:slideUp .2s ease-out}.calendar-popup.position-right{left:auto;right:0}.calendar-popup.position-center{left:50%;transform:translate(-50%)}@keyframes slideDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes slideUp{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.ranges{display:flex;flex-direction:column;gap:4px;margin-bottom:16px;padding-bottom:16px;border-bottom:1px solid #eee;min-width:150px;padding-right:8px}.range-btn{padding:7px 10px;border:1px solid transparent;background:transparent;border-radius:4px;cursor:pointer;text-align:left;font-size:14px;transition:all .2s;color:#838383;font-weight:500}.range-btn:hover{background:#f5f5f5;color:#000}.range-btn.active{background:#f0f0f0;color:#000;font-weight:500}.calendar-wrapper{padding:0 12px 12px;border-left:1px solid #eee}.header{display:flex;justify-content:space-between;align-items:center;padding:12px 0}.month-year{font-size:15px;font-weight:500;color:#333;flex:1;text-align:center;text-transform:capitalize}.nav-btn{background:none;border:none;font-size:24px;cursor:pointer;padding:11.5px 14px;color:#666;border-radius:4px;transition:all .2s;line-height:1;height:30px;width:30px;display:flex;justify-content:center;align-items:center}.nav-btn:hover{background:#f0f0f0;color:#000}.nav-btn img{width:auto;max-width:none!important}.calendar-table{width:100%;border-collapse:collapse;text-align:center}.weekday-header{font-size:12px;color:#7e7e7e;font-weight:600;padding:8px 4px;letter-spacing:.3px}.calendar-day{padding:8px 4px;font-size:14px;cursor:pointer;border-radius:6px;transition:all .2s;position:relative;color:#333;font-weight:500;line-height:1.5}.calendar-day:hover:not(.disabled):not(.other-month){background:#efefef;color:#000}.calendar-day.other-month{color:#ccc;cursor:default}.calendar-day.disabled{color:#ddd;cursor:not-allowed;opacity:.5}.calendar-day.active{background:#000!important;color:#fff!important;font-weight:600}.calendar-day.today{font-weight:600}.calendar-day.today:not(.active){background:#e5e4e4}.calendar-day.active:hover{background:#000!important}.calendar-day.in-range{background:#f5f5f5;color:#333;border-radius:0;position:relative}.calendar-day.in-range:hover{background:#e8e8e8}.calendar-day.in-range:before{content:\"\";position:absolute;inset:0;background:#f5f5f5;z-index:-1}.calendar-day.in-range:hover:before{background:#e8e8e8}.calendar-day.multi-selected{background:#4caf50;color:#fff;font-weight:600;border-radius:6px}.calendar-day.multi-selected:hover{background:#45a049}.dual-calendar{display:flex;width:100%;border-left:1px solid #eee}.calendar-left,.calendar-right{flex:1;min-width:0;padding:0 12px 12px}.calendar-popup.has-ranges{display:flex;flex-direction:row}.calendar-popup.has-ranges .ranges{margin-bottom:0;border-bottom:none;padding:10px}.calendar-popup.has-ranges .dual-calendar,.calendar-popup.has-ranges .calendar-wrapper{flex:1}.calendar-right .header{justify-content:space-between}.calendar-right .header .month-year{text-align:center;flex:1}.timepicker-section{margin-top:12px;padding-top:12px;border-top:1px solid #eee}.timepicker-label{font-size:12px;font-weight:500;color:#000;margin-bottom:4px;letter-spacing:-.28px}.custom-time-picker{display:flex;flex-direction:column;gap:8px;align-items:start}.time-input-group{display:flex;align-items:center;justify-content:center;gap:8px;background:#f8f9fa;padding:12px;border-radius:8px;border:1px solid #e0e0e0}.time-control{display:flex;flex-direction:column;align-items:center}.time-btn{background:#fff;border:1px solid #ddd;width:28px;height:20px;cursor:pointer;font-size:10px;color:#666;border-radius:4px;transition:all .2s;display:flex;align-items:center;justify-content:center;padding:0;line-height:1}.time-btn:hover{background:#e4e4e4;color:#fff;border-color:#e4e4e4}.time-btn.up{border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom:none}.time-btn.down{border-top-left-radius:0;border-top-right-radius:0;border-top:none}.time-input{width:40px;height:32px;text-align:center;border:1px solid #ddd;border-radius:4px;font-size:16px;font-weight:600;background:#fff;color:#333}.time-separator{font-size:18px;font-weight:600;color:#666;margin:0 2px}.ampm-control{display:flex;flex-direction:column;gap:4px;margin-left:8px}.ampm-btn{padding:6px 12px;border:1px solid #ddd;background:#fff;border-radius:4px;cursor:pointer;font-size:12px;font-weight:600;color:#666;transition:all .2s;min-width:45px}.ampm-btn:hover{background:#f0f0f0}.ampm-btn.active{background:#000;color:#fff;border-color:#000}.html5-time-input{margin-top:8px;padding:8px;border:1px solid #ddd;border-radius:6px;font-size:14px;width:100%;max-width:120px}.footer{padding:12px;display:flex;justify-content:flex-end;gap:8px;border-top:1px solid #eee}.btn-cancel,.btn-apply{padding:8px 16px;border:none;border-radius:4px;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s;min-width:80px}.btn-cancel{background:#fff;color:#666;border:1px solid #ddd}.btn-cancel:hover{background:#f5f5f5;border-color:#bbb}.btn-apply{background:#000;color:#fff}.btn-apply:hover{background:#333}.btn-apply:active{transform:translateY(0)}@media (max-width: 768px){.calendar-popup{width:100%;max-width:320px}.calendar-popup.dual-calendar-mode{width:100%;max-width:100%}.calendar-popup.has-ranges{flex-direction:column}.calendar-popup.has-ranges .ranges{border-right:none;border-bottom:1px solid #eee;padding-right:0;margin-right:0;padding-bottom:16px;margin-bottom:16px}.dual-calendar{flex-direction:column}.time-input-group{flex-wrap:wrap;justify-content:center}}.ranges::-webkit-scrollbar{width:6px}.ranges::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}.ranges::-webkit-scrollbar-thumb{background:#888;border-radius:3px}.ranges::-webkit-scrollbar-thumb:hover{background:#555}.w-100{width:100%}.flex-grow-1{flex-grow:1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: BkTimePicker, selector: "bk-time-picker", inputs: ["value", "label", "placeholder", "position", "pickerId", "closePicker", "timeFormat", "showSeconds"], outputs: ["timeChange", "pickerOpened", "pickerClosed"] }] });
|
|
2097
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkCustomCalendar, isStandalone: true, selector: "bk-custom-calendar", inputs: { enableTimepicker: "enableTimepicker", autoApply: "autoApply", closeOnAutoApply: "closeOnAutoApply", showCancel: "showCancel", linkedCalendars: "linkedCalendars", singleDatePicker: "singleDatePicker", showWeekNumbers: "showWeekNumbers", showISOWeekNumbers: "showISOWeekNumbers", customRangeDirection: "customRangeDirection", lockStartDate: "lockStartDate", position: "position", drop: "drop", dualCalendar: "dualCalendar", showRanges: "showRanges", timeFormat: "timeFormat", enableSeconds: "enableSeconds", customRanges: "customRanges", multiDateSelection: "multiDateSelection", maxDate: "maxDate", minDate: "minDate", placeholder: "placeholder", opens: "opens", inline: "inline", appendToBody: "appendToBody", isDisplayCrossIcon: "isDisplayCrossIcon", hasError: "hasError", errorMessage: "errorMessage", showCancelApply: "showCancelApply", selectedValue: "selectedValue", displayFormat: "displayFormat", required: "required" }, outputs: { selected: "selected", opened: "opened", closed: "closed" }, host: { listeners: { "document:click": "onClickOutside($event)", "window:scroll": "onWindowEvents()", "window:resize": "onWindowEvents()" } }, providers: [
|
|
2098
|
+
{
|
|
2099
|
+
provide: NG_VALUE_ACCESSOR,
|
|
2100
|
+
useExisting: forwardRef(() => BkCustomCalendar),
|
|
2101
|
+
multi: true,
|
|
2102
|
+
},
|
|
2103
|
+
], viewQueries: [{ propertyName: "inputWrapper", first: true, predicate: ["inputWrapper"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"calendar-container relative\" [class.open]=\"show\" [class.inline-mode]=\"inline\" [class.disabled]=\"disabled\">\r\n <!-- Input field -->\r\n <div #inputWrapper class=\"input-wrapper\" *ngIf=\"!inline\">\r\n <input\r\n type=\"text\"\r\n (click)=\"!disabled && toggle()\"\r\n (blur)=\"markAsTouched()\"\r\n readonly\r\n [value]=\"getDisplayValue()\"\r\n [placeholder]=\"placeholder\"\r\n [attr.disabled]=\"disabled ? true : null\"\r\n [class.hasError]=\"hasError\"\r\n class=\"calendar-input\">\r\n <!-- *ngIf=\"!getDisplayValue()\" -->\r\n\r\n <span class=\"calendar-icon\" >\r\n <img alt=\"calendar\" class=\"calendar-icon-img\" [src]='brickclayIcons.calenderIcon'/>\r\n </span>\r\n <button class=\"clear-btn\" *ngIf=\"getDisplayValue() && isDisplayCrossIcon\" (click)=\"clear(); $event.stopPropagation()\" title=\"Clear\">\u00D7</button>\r\n </div>\r\n\r\n <!-- Calendar Popup / Inline -->\r\n <div class=\"calendar-popup\"\r\n [class.inline-calendar]=\"inline\"\r\n [class.append-to-body]=\"appendToBody && !inline\"\r\n [style.position]=\"appendToBody && !inline ? 'fixed' : null\"\r\n [style.top]=\"appendToBody && !inline && drop !== 'up' ? dropdownStyle.top : null\"\r\n [style.bottom]=\"appendToBody && !inline && drop === 'up' ? dropdownStyle.bottom : null\"\r\n [style.left]=\"appendToBody && !inline ? dropdownStyle.left : null\"\r\n [ngClass]=\"{\r\n 'position-right': !inline && !appendToBody && opens === 'right',\r\n 'position-center': !inline && !appendToBody && opens === 'center',\r\n 'drop-up': !inline && drop === 'up',\r\n 'has-ranges': showRanges && customRanges,\r\n 'dual-calendar-mode': dualCalendar\r\n }\"\r\n *ngIf=\"inline || show\">\r\n\r\n <!-- RANGES -->\r\n <div class=\"ranges\" *ngIf=\"showRanges && customRanges\">\r\n <button\r\n *ngFor=\"let rangeKey of rangeOrder\"\r\n (click)=\"chooseRange(rangeKey)\"\r\n [class.active]=\"activeRange === rangeKey\"\r\n [class.custom-range]=\"rangeKey === 'Custom Range'\"\r\n class=\"range-btn\"\r\n [disabled]=\"rangeKey === 'Custom Range'\">\r\n {{ rangeKey }}\r\n </button>\r\n </div>\r\n<div class=\"\" [ngClass]=\"showRanges ? 'w-100 flex-grow-1' : ''\">\r\n\r\n\r\n <!-- SINGLE CALENDAR -->\r\n <div *ngIf=\"!dualCalendar\" class=\"calendar-wrapper\">\r\n <div class=\"header\">\r\n <!-- <button (click)=\"prevMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img src=\"assets/calender/pagination-left-gray.svg\" alt=\"arrow-left\" class=\"arrow-left\">\r\n </button> -->\r\n <button class=\"nav-btn\" type=\"button\" (click)=\"prevMonth()\" matTooltip=\"Prev month\"\r\n >\r\n <img alt=\"prev\" class=\"h-3 w-3\" [src]=\"brickclayIcons.arrowleft\"/>\r\n </button>\r\n <span class=\"month-year\">{{ getMonthName(month) }} {{ year }}</span>\r\n <!-- <button (click)=\"nextMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img src=\"assets/calender/pagination-right-gray.svg\" alt=\"arrow-right\" class=\"arrow-right\">\r\n </button> -->\r\n <button class=\"nav-btn\" type=\"button\" (click)=\"nextMonth()\" matTooltip=\"Next month\"\r\n >\r\n <img alt=\"next\" class=\"h-3 w-3\" [src]='brickclayIcons.arrowRight'/>\r\n <!--<img src=\"assets/calender/pagination-right-gray.svg\" alt=\"next\" class=\"h-3 w-3\" /> -->\r\n </button>\r\n </div>\r\n\r\n <table class=\"calendar-table\">\r\n <thead>\r\n <tr>\r\n <th *ngFor=\"let d of ['Mo','Tu','We','Th','Fr','Sa','Su']\" class=\"weekday-header\">{{ d }}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let week of calendar\">\r\n <td\r\n *ngFor=\"let dayObj of week\"\r\n (click)=\"dayObj.currentMonth && !isDateDisabled(year, month, dayObj.day) && selectDate(dayObj.day)\"\r\n (mouseenter)=\"dayObj.currentMonth && !isDateDisabled(year, month, dayObj.day) && onDateHover(dayObj.day, false)\"\r\n (mouseleave)=\"onDateLeave()\"\r\n [class.active]=\"dayObj.currentMonth && isDateSelected(year, month, dayObj.day)\"\r\n [class.in-range]=\"dayObj.currentMonth && isDateInRange(year, month, dayObj.day)\"\r\n [class.other-month]=\"!dayObj.currentMonth\"\r\n [class.disabled]=\"isDateDisabled(year, month, dayObj.day)\"\r\n [class.multi-selected]=\"multiDateSelection && isDateInMultiSelection(year, month, dayObj.day)\"\r\n [class.today]=\"dayObj.currentMonth && isToday(year, month, dayObj.day)\"\r\n class=\"calendar-day\">\r\n {{ dayObj.day }}\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <!-- Single Calendar Time Picker -->\r\n <div *ngIf=\"enableTimepicker\" class=\"timepicker-section\">\r\n <div class=\"timepicker-label\">Time</div>\r\n <div class=\"timepicker-controls\">\r\n <bk-time-picker\r\n pickerId=\"single-time\"\r\n [label]=\"''\"\r\n [value]=\"getSingleTimePickerDisplay()\"\r\n [closePicker]=\"shouldClosePicker('single-time')\"\r\n (timeChange)=\"onSingleTimePickerChange($event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- DUAL CALENDAR -->\r\n <div class=\"dual-calendar\" *ngIf=\"dualCalendar\">\r\n <!-- LEFT CALENDAR -->\r\n <div class=\"calendar-left\">\r\n <div class=\"header\">\r\n <button (click)=\"prevLeftMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-left\" class=\"arrow-left\" [src]=\"brickclayIcons.arrowleft\"/>\r\n </button>\r\n <span class=\"month-year\">{{ getMonthName(leftMonth) }} {{ leftYear }}</span>\r\n <button (click)=\"nextLeftMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-right\" class=\"arrow-right\" [src]='brickclayIcons.arrowRight'/>\r\n </button>\r\n </div>\r\n <table class=\"calendar-table\">\r\n <thead>\r\n <tr>\r\n <th *ngFor=\"let d of ['Mo','Tu','We','Th','Fr','Sa','Su']\" class=\"weekday-header\">{{ d }}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let week of leftCalendar\">\r\n <td\r\n *ngFor=\"let dayObj of week\"\r\n (click)=\"dayObj.currentMonth && !isDateDisabled(leftYear, leftMonth, dayObj.day) && selectDate(dayObj.day, false)\"\r\n (mouseenter)=\"dayObj.currentMonth && !isDateDisabled(leftYear, leftMonth, dayObj.day) && onDateHover(dayObj.day, false)\"\r\n (mouseleave)=\"onDateLeave()\"\r\n [class.active]=\"dayObj.currentMonth && isDateSelected(leftYear, leftMonth, dayObj.day)\"\r\n [class.in-range]=\"dayObj.currentMonth && isDateInRange(leftYear, leftMonth, dayObj.day)\"\r\n [class.other-month]=\"!dayObj.currentMonth\"\r\n [class.disabled]=\"isDateDisabled(leftYear, leftMonth, dayObj.day)\"\r\n [class.multi-selected]=\"multiDateSelection && isDateInMultiSelection(leftYear, leftMonth, dayObj.day)\"\r\n [class.today]=\"dayObj.currentMonth && isToday(leftYear, leftMonth, dayObj.day)\"\r\n class=\"calendar-day\">\r\n {{ dayObj.day }}\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <!-- Start Time Picker for Dual Calendar -->\r\n <div *ngIf=\"enableTimepicker\" class=\"timepicker-section\">\r\n <div class=\"timepicker-label\">Start Time</div>\r\n <div class=\"timepicker-controls\">\r\n <bk-time-picker\r\n pickerId=\"dual-start\"\r\n [label]=\"''\"\r\n [value]=\"getDualTimePickerDisplay(true)\"\r\n [closePicker]=\"shouldClosePicker('dual-start')\"\r\n (timeChange)=\"onDualTimePickerChange($event, true)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT CALENDAR -->\r\n <div class=\"calendar-right\">\r\n <div class=\"header\">\r\n <button (click)=\"prevRightMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-left\" class=\"arrow-left\" [src]=\"brickclayIcons.arrowleft\"/>\r\n </button>\r\n <span class=\"month-year\">{{ getMonthName(rightMonth) }} {{ rightYear }}</span>\r\n <button (click)=\"nextRightMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-right\" class=\"arrow-right\" [src]='brickclayIcons.arrowRight'/>\r\n </button>\r\n </div>\r\n <table class=\"calendar-table\">\r\n <thead>\r\n <tr>\r\n <th *ngFor=\"let d of ['Mo','Tu','We','Th','Fr','Sa','Su']\" class=\"weekday-header\">{{ d }}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let week of rightCalendar\">\r\n <td\r\n *ngFor=\"let dayObj of week\"\r\n (click)=\"dayObj.currentMonth && !isDateDisabled(rightYear, rightMonth, dayObj.day) && selectDate(dayObj.day, true)\"\r\n (mouseenter)=\"dayObj.currentMonth && !isDateDisabled(rightYear, rightMonth, dayObj.day) && onDateHover(dayObj.day, true)\"\r\n (mouseleave)=\"onDateLeave()\"\r\n [class.active]=\"dayObj.currentMonth && isDateSelected(rightYear, rightMonth, dayObj.day)\"\r\n [class.in-range]=\"dayObj.currentMonth && isDateInRange(rightYear, rightMonth, dayObj.day)\"\r\n [class.other-month]=\"!dayObj.currentMonth\"\r\n [class.disabled]=\"isDateDisabled(rightYear, rightMonth, dayObj.day)\"\r\n [class.multi-selected]=\"multiDateSelection && isDateInMultiSelection(rightYear, rightMonth, dayObj.day)\"\r\n [class.today]=\"dayObj.currentMonth && isToday(rightYear, rightMonth, dayObj.day)\"\r\n class=\"calendar-day\">\r\n {{ dayObj.day }}\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <!-- End Time Picker for Dual Calendar -->\r\n <div *ngIf=\"enableTimepicker\" class=\"timepicker-section\">\r\n <div class=\"timepicker-label\">End Time</div>\r\n <div class=\"timepicker-controls\">\r\n <bk-time-picker\r\n pickerId=\"dual-end\"\r\n [label]=\"''\"\r\n [value]=\"getDualTimePickerDisplay(false)\"\r\n [closePicker]=\"shouldClosePicker('dual-end')\"\r\n (timeChange)=\"onDualTimePickerChange($event, false)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- FOOTER -->\r\n <div class=\"footer\" *ngIf=\"!inline && showCancelApply\">\r\n <button *ngIf=\"showCancel\" (click)=\"cancel()\" class=\"btn-cancel\" type=\"button\">Cancel</button>\r\n <button (click)=\"apply()\" class=\"btn-apply\" type=\"button\">Apply</button>\r\n </div>\r\n\r\n </div>\r\n\r\n </div>\r\n</div>\r\n\r\n@if (hasError){\r\n<p class=\"calender-error\">{{errorMessage}}</p>\r\n}\r\n", styles: [".calendar-container,.calendar-container *{font-family:Inter,sans-serif!important}.calendar-container{position:relative;display:inline-block;width:100%}.input-wrapper{position:relative;display:flex;align-items:center}.calendar-input{width:100%;padding:9px 12px 9px 36px;border:1px solid #E3E3E7;border-radius:4px;font-size:14px;line-height:20px;cursor:pointer;background:#fff;transition:all .2s}.calendar-input::placeholder{color:#6b7080}.calendar-input.hasError{border-color:#f34050}.calendar-input:focus{outline:none;border-color:#999}.calendar-icon{position:absolute;left:12px;pointer-events:none;font-size:18px}.clear-btn{position:absolute;right:9px;background:none;border:none;font-size:20px;color:#999;cursor:pointer;padding:0;width:20px;height:20px;display:flex;align-items:center;justify-content:center;line-height:1;transition:color .2s;top:8px}.clear-btn:hover{color:#333}.calendar-popup{position:absolute;top:110%;left:0;width:320px;background:#fff;border-radius:12px;box-shadow:0 10px 40px #00000026;z-index:1000;animation:slideDown .2s ease-out}.calendar-popup.inline-calendar{position:relative;top:0;left:0;width:100%;margin-top:0;animation:none;box-shadow:0 2px 8px #0000001a}.calendar-container.inline-mode{display:block;width:100%}.calendar-popup.dual-calendar-mode{width:600px}.calendar-popup.dual-calendar-mode.has-ranges{width:730px}.calendar-popup.has-ranges{width:450px}.calendar-popup.dual-calendar-mode.has-ranges .dual-calendar{border-left:1px solid #eee}.calendar-popup.drop-up{top:auto;bottom:110%;animation:slideUp .2s ease-out}.calendar-popup.position-right{left:auto;right:0}.calendar-popup.position-center{left:50%;transform:translate(-50%)}.calendar-popup.append-to-body{z-index:10000}@keyframes slideDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes slideUp{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.ranges{display:flex;flex-direction:column;gap:4px;margin-bottom:16px;padding-bottom:16px;border-bottom:1px solid #eee;min-width:150px;padding-right:8px}.range-btn{padding:7px 10px;border:1px solid transparent;background:transparent;border-radius:4px;cursor:pointer;text-align:left;font-size:14px;transition:all .2s;color:#838383;font-weight:500}.range-btn:hover{background:#f5f5f5;color:#000}.range-btn.active{background:#f0f0f0;color:#000;font-weight:500}.calendar-wrapper{padding:0 12px 12px;border-left:1px solid #eee}.header{display:flex;justify-content:space-between;align-items:center;padding:12px 0}.month-year{font-size:15px;font-weight:500;color:#333;flex:1;text-align:center;text-transform:capitalize}.nav-btn{background:none;border:none;font-size:24px;cursor:pointer;padding:11.5px 14px;color:#666;border-radius:4px;transition:all .2s;line-height:1;height:30px;width:30px;display:flex;justify-content:center;align-items:center}.nav-btn:hover{background:#f0f0f0;color:#000}.nav-btn img{width:auto;max-width:none!important}.calendar-table{width:100%;border-collapse:collapse;text-align:center}.weekday-header{font-size:12px;color:#7e7e7e;font-weight:600;padding:8px 4px;letter-spacing:.3px}.calendar-day{padding:8px 4px;font-size:14px;cursor:pointer;border-radius:6px;transition:all .2s;position:relative;color:#333;font-weight:500;line-height:1.5}.calendar-day:hover:not(.disabled):not(.other-month){background:#efefef;color:#000}.calendar-day.other-month{color:#ccc;cursor:default}.calendar-day.disabled{color:#ddd;cursor:not-allowed;opacity:.5}.calendar-day.active{background:#000!important;color:#fff!important;font-weight:600}.calendar-day.today{font-weight:600}.calendar-day.today:not(.active){background:#e5e4e4}.calendar-day.active:hover{background:#000!important}.calendar-day.in-range{background:#f5f5f5;color:#333;border-radius:0;position:relative}.calendar-day.in-range:hover{background:#e8e8e8}.calendar-day.in-range:before{content:\"\";position:absolute;inset:0;background:#f5f5f5;z-index:-1}.calendar-day.in-range:hover:before{background:#e8e8e8}.calendar-day.multi-selected{background:#4caf50;color:#fff;font-weight:600;border-radius:6px}.calendar-day.multi-selected:hover{background:#45a049}.dual-calendar{display:flex;width:100%;border-left:1px solid #eee}.calendar-left,.calendar-right{flex:1;min-width:0;padding:0 12px 12px}.calendar-popup.has-ranges{display:flex;flex-direction:row}.calendar-popup.has-ranges .ranges{margin-bottom:0;border-bottom:none;padding:10px}.calendar-popup.has-ranges .dual-calendar,.calendar-popup.has-ranges .calendar-wrapper{flex:1}.calendar-right .header{justify-content:space-between}.calendar-right .header .month-year{text-align:center;flex:1}.timepicker-section{margin-top:12px;padding-top:12px;border-top:1px solid #eee}.timepicker-label{font-size:12px;font-weight:500;color:#000;margin-bottom:4px;letter-spacing:-.28px}.custom-time-picker{display:flex;flex-direction:column;gap:8px;align-items:start}.time-input-group{display:flex;align-items:center;justify-content:center;gap:8px;background:#f8f9fa;padding:12px;border-radius:8px;border:1px solid #e0e0e0}.time-control{display:flex;flex-direction:column;align-items:center}.time-btn{background:#fff;border:1px solid #ddd;width:28px;height:20px;cursor:pointer;font-size:10px;color:#666;border-radius:4px;transition:all .2s;display:flex;align-items:center;justify-content:center;padding:0;line-height:1}.time-btn:hover{background:#e4e4e4;color:#fff;border-color:#e4e4e4}.time-btn.up{border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom:none}.time-btn.down{border-top-left-radius:0;border-top-right-radius:0;border-top:none}.time-input{width:40px;height:32px;text-align:center;border:1px solid #ddd;border-radius:4px;font-size:16px;font-weight:600;background:#fff;color:#333}.time-separator{font-size:18px;font-weight:600;color:#666;margin:0 2px}.ampm-control{display:flex;flex-direction:column;gap:4px;margin-left:8px}.ampm-btn{padding:6px 12px;border:1px solid #ddd;background:#fff;border-radius:4px;cursor:pointer;font-size:12px;font-weight:600;color:#666;transition:all .2s;min-width:45px}.ampm-btn:hover{background:#f0f0f0}.ampm-btn.active{background:#000;color:#fff;border-color:#000}.html5-time-input{margin-top:8px;padding:8px;border:1px solid #ddd;border-radius:6px;font-size:14px;width:100%;max-width:120px}.footer{padding:12px;display:flex;justify-content:flex-end;gap:8px;border-top:1px solid #eee}.btn-cancel,.btn-apply{padding:8px 16px;border:none;border-radius:4px;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s;min-width:80px}.btn-cancel{background:#fff;color:#666;border:1px solid #ddd}.btn-cancel:hover{background:#f5f5f5;border-color:#bbb}.btn-apply{background:#000;color:#fff}.btn-apply:hover{background:#333}.btn-apply:active{transform:translateY(0)}@media (max-width: 768px){.calendar-popup{width:100%;max-width:320px}.calendar-popup.dual-calendar-mode{width:100%;max-width:100%}.calendar-popup.has-ranges{flex-direction:column}.calendar-popup.has-ranges .ranges{border-right:none;border-bottom:1px solid #eee;padding-right:0;margin-right:0;padding-bottom:16px;margin-bottom:16px}.dual-calendar{flex-direction:column}.time-input-group{flex-wrap:wrap;justify-content:center}}.ranges::-webkit-scrollbar{width:6px}.ranges::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}.ranges::-webkit-scrollbar-thumb{background:#888;border-radius:3px}.ranges::-webkit-scrollbar-thumb:hover{background:#555}.w-100{width:100%}.flex-grow-1{flex-grow:1}.calender-error{margin-top:6px;color:#f34050;font-size:14px;line-height:20px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: BkTimePicker, selector: "bk-time-picker", inputs: ["value", "label", "placeholder", "position", "pickerId", "closePicker", "timeFormat", "showSeconds"], outputs: ["timeChange", "pickerOpened", "pickerClosed"] }] });
|
|
1879
2104
|
}
|
|
1880
2105
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkCustomCalendar, decorators: [{
|
|
1881
2106
|
type: Component,
|
|
1882
|
-
args: [{ selector: 'bk-custom-calendar', standalone: true, imports: [CommonModule, FormsModule, BkTimePicker], template: "<div class=\"calendar-container relative\" [class.open]=\"show\" [class.inline-mode]=\"inline\">\r\n <!-- Input field -->\r\n <div class=\"input-wrapper\" *ngIf=\"!inline\">\r\n <input\r\n type=\"text\"\r\n (click)=\"toggle()\"\r\n readonly\r\n [value]=\"getDisplayValue()\"\r\n [placeholder]=\"placeholder\"\r\n class=\"calendar-input\">\r\n <!-- *ngIf=\"!getDisplayValue()\" -->\r\n\r\n <span class=\"calendar-icon\" >\r\n <img alt=\"calendar\" class=\"calendar-icon-img\" [src]='brickclayIcons.calenderIcon'/>\r\n </span>\r\n <button class=\"clear-btn\" *ngIf=\"getDisplayValue() && isDisplayCrossIcon\" (click)=\"clear(); $event.stopPropagation()\" title=\"Clear\">\u00D7</button>\r\n </div>\r\n\r\n <!-- Calendar Popup / Inline -->\r\n <div class=\"calendar-popup\"\r\n [class.inline-calendar]=\"inline\"\r\n [ngClass]=\"{\r\n 'position-right': !inline && opens === 'right',\r\n 'position-center': !inline && opens === 'center',\r\n 'drop-up': !inline && drop === 'up',\r\n 'has-ranges': showRanges && customRanges,\r\n 'dual-calendar-mode': dualCalendar\r\n }\"\r\n *ngIf=\"inline || show\">\r\n\r\n <!-- RANGES -->\r\n <div class=\"ranges\" *ngIf=\"showRanges && customRanges\">\r\n <button\r\n *ngFor=\"let rangeKey of rangeOrder\"\r\n (click)=\"chooseRange(rangeKey)\"\r\n [class.active]=\"activeRange === rangeKey\"\r\n [class.custom-range]=\"rangeKey === 'Custom Range'\"\r\n class=\"range-btn\"\r\n [disabled]=\"rangeKey === 'Custom Range'\">\r\n {{ rangeKey }}\r\n </button>\r\n </div>\r\n<div class=\"\" [ngClass]=\"showRanges ? 'w-100 flex-grow-1' : ''\">\r\n\r\n\r\n <!-- SINGLE CALENDAR -->\r\n <div *ngIf=\"!dualCalendar\" class=\"calendar-wrapper\">\r\n <div class=\"header\">\r\n <!-- <button (click)=\"prevMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img src=\"assets/calender/pagination-left-gray.svg\" alt=\"arrow-left\" class=\"arrow-left\">\r\n </button> -->\r\n <button class=\"nav-btn\" type=\"button\" (click)=\"prevMonth()\" matTooltip=\"Prev month\"\r\n >\r\n <img alt=\"prev\" class=\"h-3 w-3\" [src]=\"brickclayIcons.arrowleft\"/>\r\n </button>\r\n <span class=\"month-year\">{{ getMonthName(month) }} {{ year }}</span>\r\n <!-- <button (click)=\"nextMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img src=\"assets/calender/pagination-right-gray.svg\" alt=\"arrow-right\" class=\"arrow-right\">\r\n </button> -->\r\n <button class=\"nav-btn\" type=\"button\" (click)=\"nextMonth()\" matTooltip=\"Next month\"\r\n >\r\n <img alt=\"next\" class=\"h-3 w-3\" [src]='brickclayIcons.arrowRight'/>\r\n <!--<img src=\"assets/calender/pagination-right-gray.svg\" alt=\"next\" class=\"h-3 w-3\" /> -->\r\n </button>\r\n </div>\r\n\r\n <table class=\"calendar-table\">\r\n <thead>\r\n <tr>\r\n <th *ngFor=\"let d of ['Mo','Tu','We','Th','Fr','Sa','Su']\" class=\"weekday-header\">{{ d }}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let week of calendar\">\r\n <td\r\n *ngFor=\"let dayObj of week\"\r\n (click)=\"dayObj.currentMonth && !isDateDisabled(year, month, dayObj.day) && selectDate(dayObj.day)\"\r\n (mouseenter)=\"dayObj.currentMonth && !isDateDisabled(year, month, dayObj.day) && onDateHover(dayObj.day, false)\"\r\n (mouseleave)=\"onDateLeave()\"\r\n [class.active]=\"dayObj.currentMonth && isDateSelected(year, month, dayObj.day)\"\r\n [class.in-range]=\"dayObj.currentMonth && isDateInRange(year, month, dayObj.day)\"\r\n [class.other-month]=\"!dayObj.currentMonth\"\r\n [class.disabled]=\"isDateDisabled(year, month, dayObj.day)\"\r\n [class.multi-selected]=\"multiDateSelection && isDateInMultiSelection(year, month, dayObj.day)\"\r\n [class.today]=\"dayObj.currentMonth && isToday(year, month, dayObj.day)\"\r\n class=\"calendar-day\">\r\n {{ dayObj.day }}\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <!-- Single Calendar Time Picker -->\r\n <div *ngIf=\"enableTimepicker\" class=\"timepicker-section\">\r\n <div class=\"timepicker-label\">Time</div>\r\n <div class=\"timepicker-controls\">\r\n <bk-time-picker\r\n pickerId=\"single-time\"\r\n [label]=\"''\"\r\n [value]=\"getSingleTimePickerDisplay()\"\r\n [closePicker]=\"shouldClosePicker('single-time')\"\r\n (timeChange)=\"onSingleTimePickerChange($event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- DUAL CALENDAR -->\r\n <div class=\"dual-calendar\" *ngIf=\"dualCalendar\">\r\n <!-- LEFT CALENDAR -->\r\n <div class=\"calendar-left\">\r\n <div class=\"header\">\r\n <button (click)=\"prevLeftMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-left\" class=\"arrow-left\" [src]=\"brickclayIcons.arrowleft\"/>\r\n </button>\r\n <span class=\"month-year\">{{ getMonthName(leftMonth) }} {{ leftYear }}</span>\r\n <button (click)=\"nextLeftMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-right\" class=\"arrow-right\" [src]='brickclayIcons.arrowRight'/>\r\n </button>\r\n </div>\r\n <table class=\"calendar-table\">\r\n <thead>\r\n <tr>\r\n <th *ngFor=\"let d of ['Mo','Tu','We','Th','Fr','Sa','Su']\" class=\"weekday-header\">{{ d }}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let week of leftCalendar\">\r\n <td\r\n *ngFor=\"let dayObj of week\"\r\n (click)=\"dayObj.currentMonth && !isDateDisabled(leftYear, leftMonth, dayObj.day) && selectDate(dayObj.day, false)\"\r\n (mouseenter)=\"dayObj.currentMonth && !isDateDisabled(leftYear, leftMonth, dayObj.day) && onDateHover(dayObj.day, false)\"\r\n (mouseleave)=\"onDateLeave()\"\r\n [class.active]=\"dayObj.currentMonth && isDateSelected(leftYear, leftMonth, dayObj.day)\"\r\n [class.in-range]=\"dayObj.currentMonth && isDateInRange(leftYear, leftMonth, dayObj.day)\"\r\n [class.other-month]=\"!dayObj.currentMonth\"\r\n [class.disabled]=\"isDateDisabled(leftYear, leftMonth, dayObj.day)\"\r\n [class.multi-selected]=\"multiDateSelection && isDateInMultiSelection(leftYear, leftMonth, dayObj.day)\"\r\n [class.today]=\"dayObj.currentMonth && isToday(leftYear, leftMonth, dayObj.day)\"\r\n class=\"calendar-day\">\r\n {{ dayObj.day }}\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <!-- Start Time Picker for Dual Calendar -->\r\n <div *ngIf=\"enableTimepicker\" class=\"timepicker-section\">\r\n <div class=\"timepicker-label\">Start Time</div>\r\n <div class=\"timepicker-controls\">\r\n <bk-time-picker\r\n pickerId=\"dual-start\"\r\n [label]=\"''\"\r\n [value]=\"getDualTimePickerDisplay(true)\"\r\n [closePicker]=\"shouldClosePicker('dual-start')\"\r\n (timeChange)=\"onDualTimePickerChange($event, true)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT CALENDAR -->\r\n <div class=\"calendar-right\">\r\n <div class=\"header\">\r\n <button (click)=\"prevRightMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-left\" class=\"arrow-left\" [src]=\"brickclayIcons.arrowleft\"/>\r\n </button>\r\n <span class=\"month-year\">{{ getMonthName(rightMonth) }} {{ rightYear }}</span>\r\n <button (click)=\"nextRightMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-right\" class=\"arrow-right\" [src]='brickclayIcons.arrowRight'/>\r\n </button>\r\n </div>\r\n <table class=\"calendar-table\">\r\n <thead>\r\n <tr>\r\n <th *ngFor=\"let d of ['Mo','Tu','We','Th','Fr','Sa','Su']\" class=\"weekday-header\">{{ d }}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let week of rightCalendar\">\r\n <td\r\n *ngFor=\"let dayObj of week\"\r\n (click)=\"dayObj.currentMonth && !isDateDisabled(rightYear, rightMonth, dayObj.day) && selectDate(dayObj.day, true)\"\r\n (mouseenter)=\"dayObj.currentMonth && !isDateDisabled(rightYear, rightMonth, dayObj.day) && onDateHover(dayObj.day, true)\"\r\n (mouseleave)=\"onDateLeave()\"\r\n [class.active]=\"dayObj.currentMonth && isDateSelected(rightYear, rightMonth, dayObj.day)\"\r\n [class.in-range]=\"dayObj.currentMonth && isDateInRange(rightYear, rightMonth, dayObj.day)\"\r\n [class.other-month]=\"!dayObj.currentMonth\"\r\n [class.disabled]=\"isDateDisabled(rightYear, rightMonth, dayObj.day)\"\r\n [class.multi-selected]=\"multiDateSelection && isDateInMultiSelection(rightYear, rightMonth, dayObj.day)\"\r\n [class.today]=\"dayObj.currentMonth && isToday(rightYear, rightMonth, dayObj.day)\"\r\n class=\"calendar-day\">\r\n {{ dayObj.day }}\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <!-- End Time Picker for Dual Calendar -->\r\n <div *ngIf=\"enableTimepicker\" class=\"timepicker-section\">\r\n <div class=\"timepicker-label\">End Time</div>\r\n <div class=\"timepicker-controls\">\r\n <bk-time-picker\r\n pickerId=\"dual-end\"\r\n [label]=\"''\"\r\n [value]=\"getDualTimePickerDisplay(false)\"\r\n [closePicker]=\"shouldClosePicker('dual-end')\"\r\n (timeChange)=\"onDualTimePickerChange($event, false)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- FOOTER -->\r\n <div class=\"footer\" *ngIf=\"!inline\">\r\n <button *ngIf=\"showCancel\" (click)=\"cancel()\" class=\"btn-cancel\" type=\"button\">Cancel</button>\r\n <button (click)=\"apply()\" class=\"btn-apply\" type=\"button\">Apply</button>\r\n </div>\r\n\r\n </div>\r\n\r\n </div>\r\n</div>\r\n", styles: [".calendar-container,.calendar-container *{font-family:Inter,sans-serif!important}.calendar-container{position:relative;display:inline-block;width:100%}.input-wrapper{position:relative;display:flex;align-items:center}.calendar-input{width:100%;padding:9px 14px 9px 40px;border:1px solid #ddd;border-radius:8px;font-size:14px;cursor:pointer;background:#fff;transition:all .2s}.calendar-input:hover{border-color:#999}.calendar-input:focus{outline:none;border-color:#999;box-shadow:0 0 0 3px #6a6a6a1a}.calendar-icon{position:absolute;left:12px;pointer-events:none;font-size:18px}.clear-btn{position:absolute;right:9px;background:none;border:none;font-size:20px;color:#999;cursor:pointer;padding:0;width:20px;height:20px;display:flex;align-items:center;justify-content:center;line-height:1;transition:color .2s;top:8px}.clear-btn:hover{color:#333}.calendar-popup{position:absolute;top:110%;left:0;width:320px;background:#fff;border-radius:12px;box-shadow:0 10px 40px #00000026;z-index:1000;animation:slideDown .2s ease-out}.calendar-popup.inline-calendar{position:relative;top:0;left:0;width:100%;margin-top:0;animation:none;box-shadow:0 2px 8px #0000001a}.calendar-container.inline-mode{display:block;width:100%}.calendar-popup.dual-calendar-mode{width:600px}.calendar-popup.dual-calendar-mode.has-ranges{width:730px}.calendar-popup.has-ranges{width:450px}.calendar-popup.dual-calendar-mode.has-ranges .dual-calendar{border-left:1px solid #eee}.calendar-popup.drop-up{top:auto;bottom:110%;animation:slideUp .2s ease-out}.calendar-popup.position-right{left:auto;right:0}.calendar-popup.position-center{left:50%;transform:translate(-50%)}@keyframes slideDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes slideUp{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.ranges{display:flex;flex-direction:column;gap:4px;margin-bottom:16px;padding-bottom:16px;border-bottom:1px solid #eee;min-width:150px;padding-right:8px}.range-btn{padding:7px 10px;border:1px solid transparent;background:transparent;border-radius:4px;cursor:pointer;text-align:left;font-size:14px;transition:all .2s;color:#838383;font-weight:500}.range-btn:hover{background:#f5f5f5;color:#000}.range-btn.active{background:#f0f0f0;color:#000;font-weight:500}.calendar-wrapper{padding:0 12px 12px;border-left:1px solid #eee}.header{display:flex;justify-content:space-between;align-items:center;padding:12px 0}.month-year{font-size:15px;font-weight:500;color:#333;flex:1;text-align:center;text-transform:capitalize}.nav-btn{background:none;border:none;font-size:24px;cursor:pointer;padding:11.5px 14px;color:#666;border-radius:4px;transition:all .2s;line-height:1;height:30px;width:30px;display:flex;justify-content:center;align-items:center}.nav-btn:hover{background:#f0f0f0;color:#000}.nav-btn img{width:auto;max-width:none!important}.calendar-table{width:100%;border-collapse:collapse;text-align:center}.weekday-header{font-size:12px;color:#7e7e7e;font-weight:600;padding:8px 4px;letter-spacing:.3px}.calendar-day{padding:8px 4px;font-size:14px;cursor:pointer;border-radius:6px;transition:all .2s;position:relative;color:#333;font-weight:500;line-height:1.5}.calendar-day:hover:not(.disabled):not(.other-month){background:#efefef;color:#000}.calendar-day.other-month{color:#ccc;cursor:default}.calendar-day.disabled{color:#ddd;cursor:not-allowed;opacity:.5}.calendar-day.active{background:#000!important;color:#fff!important;font-weight:600}.calendar-day.today{font-weight:600}.calendar-day.today:not(.active){background:#e5e4e4}.calendar-day.active:hover{background:#000!important}.calendar-day.in-range{background:#f5f5f5;color:#333;border-radius:0;position:relative}.calendar-day.in-range:hover{background:#e8e8e8}.calendar-day.in-range:before{content:\"\";position:absolute;inset:0;background:#f5f5f5;z-index:-1}.calendar-day.in-range:hover:before{background:#e8e8e8}.calendar-day.multi-selected{background:#4caf50;color:#fff;font-weight:600;border-radius:6px}.calendar-day.multi-selected:hover{background:#45a049}.dual-calendar{display:flex;width:100%;border-left:1px solid #eee}.calendar-left,.calendar-right{flex:1;min-width:0;padding:0 12px 12px}.calendar-popup.has-ranges{display:flex;flex-direction:row}.calendar-popup.has-ranges .ranges{margin-bottom:0;border-bottom:none;padding:10px}.calendar-popup.has-ranges .dual-calendar,.calendar-popup.has-ranges .calendar-wrapper{flex:1}.calendar-right .header{justify-content:space-between}.calendar-right .header .month-year{text-align:center;flex:1}.timepicker-section{margin-top:12px;padding-top:12px;border-top:1px solid #eee}.timepicker-label{font-size:12px;font-weight:500;color:#000;margin-bottom:4px;letter-spacing:-.28px}.custom-time-picker{display:flex;flex-direction:column;gap:8px;align-items:start}.time-input-group{display:flex;align-items:center;justify-content:center;gap:8px;background:#f8f9fa;padding:12px;border-radius:8px;border:1px solid #e0e0e0}.time-control{display:flex;flex-direction:column;align-items:center}.time-btn{background:#fff;border:1px solid #ddd;width:28px;height:20px;cursor:pointer;font-size:10px;color:#666;border-radius:4px;transition:all .2s;display:flex;align-items:center;justify-content:center;padding:0;line-height:1}.time-btn:hover{background:#e4e4e4;color:#fff;border-color:#e4e4e4}.time-btn.up{border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom:none}.time-btn.down{border-top-left-radius:0;border-top-right-radius:0;border-top:none}.time-input{width:40px;height:32px;text-align:center;border:1px solid #ddd;border-radius:4px;font-size:16px;font-weight:600;background:#fff;color:#333}.time-separator{font-size:18px;font-weight:600;color:#666;margin:0 2px}.ampm-control{display:flex;flex-direction:column;gap:4px;margin-left:8px}.ampm-btn{padding:6px 12px;border:1px solid #ddd;background:#fff;border-radius:4px;cursor:pointer;font-size:12px;font-weight:600;color:#666;transition:all .2s;min-width:45px}.ampm-btn:hover{background:#f0f0f0}.ampm-btn.active{background:#000;color:#fff;border-color:#000}.html5-time-input{margin-top:8px;padding:8px;border:1px solid #ddd;border-radius:6px;font-size:14px;width:100%;max-width:120px}.footer{padding:12px;display:flex;justify-content:flex-end;gap:8px;border-top:1px solid #eee}.btn-cancel,.btn-apply{padding:8px 16px;border:none;border-radius:4px;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s;min-width:80px}.btn-cancel{background:#fff;color:#666;border:1px solid #ddd}.btn-cancel:hover{background:#f5f5f5;border-color:#bbb}.btn-apply{background:#000;color:#fff}.btn-apply:hover{background:#333}.btn-apply:active{transform:translateY(0)}@media (max-width: 768px){.calendar-popup{width:100%;max-width:320px}.calendar-popup.dual-calendar-mode{width:100%;max-width:100%}.calendar-popup.has-ranges{flex-direction:column}.calendar-popup.has-ranges .ranges{border-right:none;border-bottom:1px solid #eee;padding-right:0;margin-right:0;padding-bottom:16px;margin-bottom:16px}.dual-calendar{flex-direction:column}.time-input-group{flex-wrap:wrap;justify-content:center}}.ranges::-webkit-scrollbar{width:6px}.ranges::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}.ranges::-webkit-scrollbar-thumb{background:#888;border-radius:3px}.ranges::-webkit-scrollbar-thumb:hover{background:#555}.w-100{width:100%}.flex-grow-1{flex-grow:1}\n"] }]
|
|
2107
|
+
args: [{ selector: 'bk-custom-calendar', standalone: true, imports: [CommonModule, FormsModule, BkTimePicker], providers: [
|
|
2108
|
+
{
|
|
2109
|
+
provide: NG_VALUE_ACCESSOR,
|
|
2110
|
+
useExisting: forwardRef(() => BkCustomCalendar),
|
|
2111
|
+
multi: true,
|
|
2112
|
+
},
|
|
2113
|
+
], template: "<div class=\"calendar-container relative\" [class.open]=\"show\" [class.inline-mode]=\"inline\" [class.disabled]=\"disabled\">\r\n <!-- Input field -->\r\n <div #inputWrapper class=\"input-wrapper\" *ngIf=\"!inline\">\r\n <input\r\n type=\"text\"\r\n (click)=\"!disabled && toggle()\"\r\n (blur)=\"markAsTouched()\"\r\n readonly\r\n [value]=\"getDisplayValue()\"\r\n [placeholder]=\"placeholder\"\r\n [attr.disabled]=\"disabled ? true : null\"\r\n [class.hasError]=\"hasError\"\r\n class=\"calendar-input\">\r\n <!-- *ngIf=\"!getDisplayValue()\" -->\r\n\r\n <span class=\"calendar-icon\" >\r\n <img alt=\"calendar\" class=\"calendar-icon-img\" [src]='brickclayIcons.calenderIcon'/>\r\n </span>\r\n <button class=\"clear-btn\" *ngIf=\"getDisplayValue() && isDisplayCrossIcon\" (click)=\"clear(); $event.stopPropagation()\" title=\"Clear\">\u00D7</button>\r\n </div>\r\n\r\n <!-- Calendar Popup / Inline -->\r\n <div class=\"calendar-popup\"\r\n [class.inline-calendar]=\"inline\"\r\n [class.append-to-body]=\"appendToBody && !inline\"\r\n [style.position]=\"appendToBody && !inline ? 'fixed' : null\"\r\n [style.top]=\"appendToBody && !inline && drop !== 'up' ? dropdownStyle.top : null\"\r\n [style.bottom]=\"appendToBody && !inline && drop === 'up' ? dropdownStyle.bottom : null\"\r\n [style.left]=\"appendToBody && !inline ? dropdownStyle.left : null\"\r\n [ngClass]=\"{\r\n 'position-right': !inline && !appendToBody && opens === 'right',\r\n 'position-center': !inline && !appendToBody && opens === 'center',\r\n 'drop-up': !inline && drop === 'up',\r\n 'has-ranges': showRanges && customRanges,\r\n 'dual-calendar-mode': dualCalendar\r\n }\"\r\n *ngIf=\"inline || show\">\r\n\r\n <!-- RANGES -->\r\n <div class=\"ranges\" *ngIf=\"showRanges && customRanges\">\r\n <button\r\n *ngFor=\"let rangeKey of rangeOrder\"\r\n (click)=\"chooseRange(rangeKey)\"\r\n [class.active]=\"activeRange === rangeKey\"\r\n [class.custom-range]=\"rangeKey === 'Custom Range'\"\r\n class=\"range-btn\"\r\n [disabled]=\"rangeKey === 'Custom Range'\">\r\n {{ rangeKey }}\r\n </button>\r\n </div>\r\n<div class=\"\" [ngClass]=\"showRanges ? 'w-100 flex-grow-1' : ''\">\r\n\r\n\r\n <!-- SINGLE CALENDAR -->\r\n <div *ngIf=\"!dualCalendar\" class=\"calendar-wrapper\">\r\n <div class=\"header\">\r\n <!-- <button (click)=\"prevMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img src=\"assets/calender/pagination-left-gray.svg\" alt=\"arrow-left\" class=\"arrow-left\">\r\n </button> -->\r\n <button class=\"nav-btn\" type=\"button\" (click)=\"prevMonth()\" matTooltip=\"Prev month\"\r\n >\r\n <img alt=\"prev\" class=\"h-3 w-3\" [src]=\"brickclayIcons.arrowleft\"/>\r\n </button>\r\n <span class=\"month-year\">{{ getMonthName(month) }} {{ year }}</span>\r\n <!-- <button (click)=\"nextMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img src=\"assets/calender/pagination-right-gray.svg\" alt=\"arrow-right\" class=\"arrow-right\">\r\n </button> -->\r\n <button class=\"nav-btn\" type=\"button\" (click)=\"nextMonth()\" matTooltip=\"Next month\"\r\n >\r\n <img alt=\"next\" class=\"h-3 w-3\" [src]='brickclayIcons.arrowRight'/>\r\n <!--<img src=\"assets/calender/pagination-right-gray.svg\" alt=\"next\" class=\"h-3 w-3\" /> -->\r\n </button>\r\n </div>\r\n\r\n <table class=\"calendar-table\">\r\n <thead>\r\n <tr>\r\n <th *ngFor=\"let d of ['Mo','Tu','We','Th','Fr','Sa','Su']\" class=\"weekday-header\">{{ d }}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let week of calendar\">\r\n <td\r\n *ngFor=\"let dayObj of week\"\r\n (click)=\"dayObj.currentMonth && !isDateDisabled(year, month, dayObj.day) && selectDate(dayObj.day)\"\r\n (mouseenter)=\"dayObj.currentMonth && !isDateDisabled(year, month, dayObj.day) && onDateHover(dayObj.day, false)\"\r\n (mouseleave)=\"onDateLeave()\"\r\n [class.active]=\"dayObj.currentMonth && isDateSelected(year, month, dayObj.day)\"\r\n [class.in-range]=\"dayObj.currentMonth && isDateInRange(year, month, dayObj.day)\"\r\n [class.other-month]=\"!dayObj.currentMonth\"\r\n [class.disabled]=\"isDateDisabled(year, month, dayObj.day)\"\r\n [class.multi-selected]=\"multiDateSelection && isDateInMultiSelection(year, month, dayObj.day)\"\r\n [class.today]=\"dayObj.currentMonth && isToday(year, month, dayObj.day)\"\r\n class=\"calendar-day\">\r\n {{ dayObj.day }}\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <!-- Single Calendar Time Picker -->\r\n <div *ngIf=\"enableTimepicker\" class=\"timepicker-section\">\r\n <div class=\"timepicker-label\">Time</div>\r\n <div class=\"timepicker-controls\">\r\n <bk-time-picker\r\n pickerId=\"single-time\"\r\n [label]=\"''\"\r\n [value]=\"getSingleTimePickerDisplay()\"\r\n [closePicker]=\"shouldClosePicker('single-time')\"\r\n (timeChange)=\"onSingleTimePickerChange($event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- DUAL CALENDAR -->\r\n <div class=\"dual-calendar\" *ngIf=\"dualCalendar\">\r\n <!-- LEFT CALENDAR -->\r\n <div class=\"calendar-left\">\r\n <div class=\"header\">\r\n <button (click)=\"prevLeftMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-left\" class=\"arrow-left\" [src]=\"brickclayIcons.arrowleft\"/>\r\n </button>\r\n <span class=\"month-year\">{{ getMonthName(leftMonth) }} {{ leftYear }}</span>\r\n <button (click)=\"nextLeftMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-right\" class=\"arrow-right\" [src]='brickclayIcons.arrowRight'/>\r\n </button>\r\n </div>\r\n <table class=\"calendar-table\">\r\n <thead>\r\n <tr>\r\n <th *ngFor=\"let d of ['Mo','Tu','We','Th','Fr','Sa','Su']\" class=\"weekday-header\">{{ d }}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let week of leftCalendar\">\r\n <td\r\n *ngFor=\"let dayObj of week\"\r\n (click)=\"dayObj.currentMonth && !isDateDisabled(leftYear, leftMonth, dayObj.day) && selectDate(dayObj.day, false)\"\r\n (mouseenter)=\"dayObj.currentMonth && !isDateDisabled(leftYear, leftMonth, dayObj.day) && onDateHover(dayObj.day, false)\"\r\n (mouseleave)=\"onDateLeave()\"\r\n [class.active]=\"dayObj.currentMonth && isDateSelected(leftYear, leftMonth, dayObj.day)\"\r\n [class.in-range]=\"dayObj.currentMonth && isDateInRange(leftYear, leftMonth, dayObj.day)\"\r\n [class.other-month]=\"!dayObj.currentMonth\"\r\n [class.disabled]=\"isDateDisabled(leftYear, leftMonth, dayObj.day)\"\r\n [class.multi-selected]=\"multiDateSelection && isDateInMultiSelection(leftYear, leftMonth, dayObj.day)\"\r\n [class.today]=\"dayObj.currentMonth && isToday(leftYear, leftMonth, dayObj.day)\"\r\n class=\"calendar-day\">\r\n {{ dayObj.day }}\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <!-- Start Time Picker for Dual Calendar -->\r\n <div *ngIf=\"enableTimepicker\" class=\"timepicker-section\">\r\n <div class=\"timepicker-label\">Start Time</div>\r\n <div class=\"timepicker-controls\">\r\n <bk-time-picker\r\n pickerId=\"dual-start\"\r\n [label]=\"''\"\r\n [value]=\"getDualTimePickerDisplay(true)\"\r\n [closePicker]=\"shouldClosePicker('dual-start')\"\r\n (timeChange)=\"onDualTimePickerChange($event, true)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT CALENDAR -->\r\n <div class=\"calendar-right\">\r\n <div class=\"header\">\r\n <button (click)=\"prevRightMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-left\" class=\"arrow-left\" [src]=\"brickclayIcons.arrowleft\"/>\r\n </button>\r\n <span class=\"month-year\">{{ getMonthName(rightMonth) }} {{ rightYear }}</span>\r\n <button (click)=\"nextRightMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-right\" class=\"arrow-right\" [src]='brickclayIcons.arrowRight'/>\r\n </button>\r\n </div>\r\n <table class=\"calendar-table\">\r\n <thead>\r\n <tr>\r\n <th *ngFor=\"let d of ['Mo','Tu','We','Th','Fr','Sa','Su']\" class=\"weekday-header\">{{ d }}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let week of rightCalendar\">\r\n <td\r\n *ngFor=\"let dayObj of week\"\r\n (click)=\"dayObj.currentMonth && !isDateDisabled(rightYear, rightMonth, dayObj.day) && selectDate(dayObj.day, true)\"\r\n (mouseenter)=\"dayObj.currentMonth && !isDateDisabled(rightYear, rightMonth, dayObj.day) && onDateHover(dayObj.day, true)\"\r\n (mouseleave)=\"onDateLeave()\"\r\n [class.active]=\"dayObj.currentMonth && isDateSelected(rightYear, rightMonth, dayObj.day)\"\r\n [class.in-range]=\"dayObj.currentMonth && isDateInRange(rightYear, rightMonth, dayObj.day)\"\r\n [class.other-month]=\"!dayObj.currentMonth\"\r\n [class.disabled]=\"isDateDisabled(rightYear, rightMonth, dayObj.day)\"\r\n [class.multi-selected]=\"multiDateSelection && isDateInMultiSelection(rightYear, rightMonth, dayObj.day)\"\r\n [class.today]=\"dayObj.currentMonth && isToday(rightYear, rightMonth, dayObj.day)\"\r\n class=\"calendar-day\">\r\n {{ dayObj.day }}\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <!-- End Time Picker for Dual Calendar -->\r\n <div *ngIf=\"enableTimepicker\" class=\"timepicker-section\">\r\n <div class=\"timepicker-label\">End Time</div>\r\n <div class=\"timepicker-controls\">\r\n <bk-time-picker\r\n pickerId=\"dual-end\"\r\n [label]=\"''\"\r\n [value]=\"getDualTimePickerDisplay(false)\"\r\n [closePicker]=\"shouldClosePicker('dual-end')\"\r\n (timeChange)=\"onDualTimePickerChange($event, false)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- FOOTER -->\r\n <div class=\"footer\" *ngIf=\"!inline && showCancelApply\">\r\n <button *ngIf=\"showCancel\" (click)=\"cancel()\" class=\"btn-cancel\" type=\"button\">Cancel</button>\r\n <button (click)=\"apply()\" class=\"btn-apply\" type=\"button\">Apply</button>\r\n </div>\r\n\r\n </div>\r\n\r\n </div>\r\n</div>\r\n\r\n@if (hasError){\r\n<p class=\"calender-error\">{{errorMessage}}</p>\r\n}\r\n", styles: [".calendar-container,.calendar-container *{font-family:Inter,sans-serif!important}.calendar-container{position:relative;display:inline-block;width:100%}.input-wrapper{position:relative;display:flex;align-items:center}.calendar-input{width:100%;padding:9px 12px 9px 36px;border:1px solid #E3E3E7;border-radius:4px;font-size:14px;line-height:20px;cursor:pointer;background:#fff;transition:all .2s}.calendar-input::placeholder{color:#6b7080}.calendar-input.hasError{border-color:#f34050}.calendar-input:focus{outline:none;border-color:#999}.calendar-icon{position:absolute;left:12px;pointer-events:none;font-size:18px}.clear-btn{position:absolute;right:9px;background:none;border:none;font-size:20px;color:#999;cursor:pointer;padding:0;width:20px;height:20px;display:flex;align-items:center;justify-content:center;line-height:1;transition:color .2s;top:8px}.clear-btn:hover{color:#333}.calendar-popup{position:absolute;top:110%;left:0;width:320px;background:#fff;border-radius:12px;box-shadow:0 10px 40px #00000026;z-index:1000;animation:slideDown .2s ease-out}.calendar-popup.inline-calendar{position:relative;top:0;left:0;width:100%;margin-top:0;animation:none;box-shadow:0 2px 8px #0000001a}.calendar-container.inline-mode{display:block;width:100%}.calendar-popup.dual-calendar-mode{width:600px}.calendar-popup.dual-calendar-mode.has-ranges{width:730px}.calendar-popup.has-ranges{width:450px}.calendar-popup.dual-calendar-mode.has-ranges .dual-calendar{border-left:1px solid #eee}.calendar-popup.drop-up{top:auto;bottom:110%;animation:slideUp .2s ease-out}.calendar-popup.position-right{left:auto;right:0}.calendar-popup.position-center{left:50%;transform:translate(-50%)}.calendar-popup.append-to-body{z-index:10000}@keyframes slideDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes slideUp{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.ranges{display:flex;flex-direction:column;gap:4px;margin-bottom:16px;padding-bottom:16px;border-bottom:1px solid #eee;min-width:150px;padding-right:8px}.range-btn{padding:7px 10px;border:1px solid transparent;background:transparent;border-radius:4px;cursor:pointer;text-align:left;font-size:14px;transition:all .2s;color:#838383;font-weight:500}.range-btn:hover{background:#f5f5f5;color:#000}.range-btn.active{background:#f0f0f0;color:#000;font-weight:500}.calendar-wrapper{padding:0 12px 12px;border-left:1px solid #eee}.header{display:flex;justify-content:space-between;align-items:center;padding:12px 0}.month-year{font-size:15px;font-weight:500;color:#333;flex:1;text-align:center;text-transform:capitalize}.nav-btn{background:none;border:none;font-size:24px;cursor:pointer;padding:11.5px 14px;color:#666;border-radius:4px;transition:all .2s;line-height:1;height:30px;width:30px;display:flex;justify-content:center;align-items:center}.nav-btn:hover{background:#f0f0f0;color:#000}.nav-btn img{width:auto;max-width:none!important}.calendar-table{width:100%;border-collapse:collapse;text-align:center}.weekday-header{font-size:12px;color:#7e7e7e;font-weight:600;padding:8px 4px;letter-spacing:.3px}.calendar-day{padding:8px 4px;font-size:14px;cursor:pointer;border-radius:6px;transition:all .2s;position:relative;color:#333;font-weight:500;line-height:1.5}.calendar-day:hover:not(.disabled):not(.other-month){background:#efefef;color:#000}.calendar-day.other-month{color:#ccc;cursor:default}.calendar-day.disabled{color:#ddd;cursor:not-allowed;opacity:.5}.calendar-day.active{background:#000!important;color:#fff!important;font-weight:600}.calendar-day.today{font-weight:600}.calendar-day.today:not(.active){background:#e5e4e4}.calendar-day.active:hover{background:#000!important}.calendar-day.in-range{background:#f5f5f5;color:#333;border-radius:0;position:relative}.calendar-day.in-range:hover{background:#e8e8e8}.calendar-day.in-range:before{content:\"\";position:absolute;inset:0;background:#f5f5f5;z-index:-1}.calendar-day.in-range:hover:before{background:#e8e8e8}.calendar-day.multi-selected{background:#4caf50;color:#fff;font-weight:600;border-radius:6px}.calendar-day.multi-selected:hover{background:#45a049}.dual-calendar{display:flex;width:100%;border-left:1px solid #eee}.calendar-left,.calendar-right{flex:1;min-width:0;padding:0 12px 12px}.calendar-popup.has-ranges{display:flex;flex-direction:row}.calendar-popup.has-ranges .ranges{margin-bottom:0;border-bottom:none;padding:10px}.calendar-popup.has-ranges .dual-calendar,.calendar-popup.has-ranges .calendar-wrapper{flex:1}.calendar-right .header{justify-content:space-between}.calendar-right .header .month-year{text-align:center;flex:1}.timepicker-section{margin-top:12px;padding-top:12px;border-top:1px solid #eee}.timepicker-label{font-size:12px;font-weight:500;color:#000;margin-bottom:4px;letter-spacing:-.28px}.custom-time-picker{display:flex;flex-direction:column;gap:8px;align-items:start}.time-input-group{display:flex;align-items:center;justify-content:center;gap:8px;background:#f8f9fa;padding:12px;border-radius:8px;border:1px solid #e0e0e0}.time-control{display:flex;flex-direction:column;align-items:center}.time-btn{background:#fff;border:1px solid #ddd;width:28px;height:20px;cursor:pointer;font-size:10px;color:#666;border-radius:4px;transition:all .2s;display:flex;align-items:center;justify-content:center;padding:0;line-height:1}.time-btn:hover{background:#e4e4e4;color:#fff;border-color:#e4e4e4}.time-btn.up{border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom:none}.time-btn.down{border-top-left-radius:0;border-top-right-radius:0;border-top:none}.time-input{width:40px;height:32px;text-align:center;border:1px solid #ddd;border-radius:4px;font-size:16px;font-weight:600;background:#fff;color:#333}.time-separator{font-size:18px;font-weight:600;color:#666;margin:0 2px}.ampm-control{display:flex;flex-direction:column;gap:4px;margin-left:8px}.ampm-btn{padding:6px 12px;border:1px solid #ddd;background:#fff;border-radius:4px;cursor:pointer;font-size:12px;font-weight:600;color:#666;transition:all .2s;min-width:45px}.ampm-btn:hover{background:#f0f0f0}.ampm-btn.active{background:#000;color:#fff;border-color:#000}.html5-time-input{margin-top:8px;padding:8px;border:1px solid #ddd;border-radius:6px;font-size:14px;width:100%;max-width:120px}.footer{padding:12px;display:flex;justify-content:flex-end;gap:8px;border-top:1px solid #eee}.btn-cancel,.btn-apply{padding:8px 16px;border:none;border-radius:4px;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s;min-width:80px}.btn-cancel{background:#fff;color:#666;border:1px solid #ddd}.btn-cancel:hover{background:#f5f5f5;border-color:#bbb}.btn-apply{background:#000;color:#fff}.btn-apply:hover{background:#333}.btn-apply:active{transform:translateY(0)}@media (max-width: 768px){.calendar-popup{width:100%;max-width:320px}.calendar-popup.dual-calendar-mode{width:100%;max-width:100%}.calendar-popup.has-ranges{flex-direction:column}.calendar-popup.has-ranges .ranges{border-right:none;border-bottom:1px solid #eee;padding-right:0;margin-right:0;padding-bottom:16px;margin-bottom:16px}.dual-calendar{flex-direction:column}.time-input-group{flex-wrap:wrap;justify-content:center}}.ranges::-webkit-scrollbar{width:6px}.ranges::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}.ranges::-webkit-scrollbar-thumb{background:#888;border-radius:3px}.ranges::-webkit-scrollbar-thumb:hover{background:#555}.w-100{width:100%}.flex-grow-1{flex-grow:1}.calender-error{margin-top:6px;color:#f34050;font-size:14px;line-height:20px}\n"] }]
|
|
1883
2114
|
}], ctorParameters: () => [{ type: CalendarManagerService }], propDecorators: { enableTimepicker: [{
|
|
1884
2115
|
type: Input
|
|
1885
2116
|
}], autoApply: [{
|
|
@@ -1926,25 +2157,40 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
1926
2157
|
type: Input
|
|
1927
2158
|
}], inline: [{
|
|
1928
2159
|
type: Input
|
|
2160
|
+
}], appendToBody: [{
|
|
2161
|
+
type: Input
|
|
1929
2162
|
}], isDisplayCrossIcon: [{
|
|
1930
2163
|
type: Input
|
|
2164
|
+
}], hasError: [{
|
|
2165
|
+
type: Input
|
|
2166
|
+
}], errorMessage: [{
|
|
2167
|
+
type: Input
|
|
1931
2168
|
}], selected: [{
|
|
1932
2169
|
type: Output
|
|
2170
|
+
}], inputWrapper: [{
|
|
2171
|
+
type: ViewChild,
|
|
2172
|
+
args: ['inputWrapper']
|
|
1933
2173
|
}], opened: [{
|
|
1934
2174
|
type: Output
|
|
1935
2175
|
}], closed: [{
|
|
1936
2176
|
type: Output
|
|
2177
|
+
}], showCancelApply: [{
|
|
2178
|
+
type: Input
|
|
1937
2179
|
}], selectedValue: [{
|
|
1938
2180
|
type: Input
|
|
1939
2181
|
}], displayFormat: [{
|
|
1940
2182
|
type: Input
|
|
1941
|
-
}],
|
|
1942
|
-
type: Input
|
|
1943
|
-
}], endDate: [{
|
|
2183
|
+
}], required: [{
|
|
1944
2184
|
type: Input
|
|
1945
2185
|
}], onClickOutside: [{
|
|
1946
2186
|
type: HostListener,
|
|
1947
2187
|
args: ['document:click', ['$event']]
|
|
2188
|
+
}], onWindowEvents: [{
|
|
2189
|
+
type: HostListener,
|
|
2190
|
+
args: ['window:scroll']
|
|
2191
|
+
}, {
|
|
2192
|
+
type: HostListener,
|
|
2193
|
+
args: ['window:resize']
|
|
1948
2194
|
}] } });
|
|
1949
2195
|
|
|
1950
2196
|
class BkScheduledDatePicker {
|
|
@@ -2239,7 +2485,7 @@ class BkScheduledDatePicker {
|
|
|
2239
2485
|
this.emitScheduled();
|
|
2240
2486
|
}
|
|
2241
2487
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkScheduledDatePicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2242
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: BkScheduledDatePicker, isStandalone: true, selector: "bk-scheduled-date-picker", inputs: { timeFormat: "timeFormat", enableSeconds: "enableSeconds" }, outputs: { scheduled: "scheduled", cleared: "cleared" }, ngImport: i0, template: "<div class=\"scheduled-date-picker-container\">\r\n <!-- Header with Tabs -->\r\n\r\n\r\n <!-- Main Content Area -->\r\n\r\n <div class=\"scheduled-content\">\r\n <!-- Left Side: Calendar -->\r\n <div class=\"calendar-section\">\r\n <h2 class=\"scheduled-title\">Scheduled Dates</h2>\r\n <div class=\"tabs\">\r\n <button\r\n class=\"tab-button\"\r\n [class.active]=\"activeTab === 'single'\"\r\n (click)=\"onTabChange('single')\">\r\n Single Date\r\n </button>\r\n <button\r\n class=\"tab-button\"\r\n [class.active]=\"activeTab === 'multiple'\"\r\n (click)=\"onTabChange('multiple')\">\r\n Multiple Dates\r\n </button>\r\n <button\r\n class=\"tab-button\"\r\n [class.active]=\"activeTab === 'range'\"\r\n (click)=\"onTabChange('range')\">\r\n Date Range\r\n </button>\r\n </div>\r\n <!-- Single Date Calendar -->\r\n <div *ngIf=\"activeTab === 'single'\" class=\"calendar-wrapper-inline\">\r\n <bk-custom-calendar\r\n [inline]=\"true\"\r\n [dualCalendar]=\"false\"\r\n [singleDatePicker]=\"true\"\r\n [showRanges]=\"false\"\r\n [enableTimepicker]=\"false\"\r\n [showCancel]=\"false\"\r\n placeholder=\"Select a date\"\r\n (selected)=\"onSingleDateSelected($event)\">\r\n </bk-custom-calendar>\r\n </div>\r\n\r\n <!-- Multiple Dates Calendar -->\r\n <div *ngIf=\"activeTab === 'multiple'\" class=\"calendar-wrapper-inline\">\r\n <bk-custom-calendar\r\n [inline]=\"true\"\r\n [dualCalendar]=\"false\"\r\n [singleDatePicker]=\"false\"\r\n [showRanges]=\"false\"\r\n [enableTimepicker]=\"false\"\r\n [multiDateSelection]=\"true\"\r\n [showCancel]=\"false\"\r\n placeholder=\"Select multiple dates\"\r\n (selected)=\"onMultipleDatesSelected($event)\">\r\n </bk-custom-calendar>\r\n </div>\r\n\r\n <!-- Date Range Calendar -->\r\n <div *ngIf=\"activeTab === 'range'\" class=\"calendar-wrapper-inline\">\r\n <bk-custom-calendar\r\n [inline]=\"true\"\r\n [dualCalendar]=\"false\"\r\n [singleDatePicker]=\"false\"\r\n [showRanges]=\"false\"\r\n [enableTimepicker]=\"false\"\r\n [showCancel]=\"false\"\r\n placeholder=\"Select date range\"\r\n (selected)=\"onRangeSelected($event)\">\r\n </bk-custom-calendar>\r\n </div>\r\n </div>\r\n\r\n <!-- Right Side: Time Configuration -->\r\n <div class=\"time-config-section\">\r\n <h3 class=\"time-config-title\">Time Configuration</h3>\r\n\r\n <!-- Single Date Time Configuration -->\r\n <div *ngIf=\"activeTab === 'single'\">\r\n <div *ngIf=\"singleDate\" class=\"time-config-item\">\r\n <div class=\"time-config-header\">\r\n <span class=\"date-label\">{{ formatDate(singleDate) }}</span>\r\n <label class=\"all-day-toggle\">\r\n <span class=\"toggle-label\">All Day</span>\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"singleAllDay\"\r\n (change)=\"onSingleAllDayChange()\">\r\n </label>\r\n </div>\r\n <div *ngIf=\"!singleAllDay\" class=\"time-inputs\">\r\n <bk-time-picker\r\n pickerId=\"single-start\"\r\n label=\"Start Time\"\r\n [value]=\"singleStartTime\"\r\n [position]=\"'left'\"\r\n [closePicker]=\"shouldClosePicker('single-start')\"\r\n (timeChange)=\"onSingleStartTimeChange($event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n <bk-time-picker\r\n pickerId=\"single-end\"\r\n label=\"End Time\"\r\n [value]=\"singleEndTime\"\r\n [position]=\"'right'\"\r\n [closePicker]=\"shouldClosePicker('single-end')\"\r\n (timeChange)=\"onSingleEndTimeChange($event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n <div *ngIf=\"!singleDate\" class=\"no-selection\">\r\n <p>No date selected. Select a date from the calendar.</p>\r\n </div>\r\n </div>\r\n\r\n <!-- Multiple Dates Time Configuration -->\r\n <div *ngIf=\"activeTab === 'multiple'\" class=\"time-config-list\">\r\n <div\r\n *ngFor=\"let dateConfig of multipleDates; let i = index\"\r\n class=\"time-config-item\">\r\n <div class=\"time-config-header\">\r\n <span class=\"date-label\">{{ formatDate(dateConfig.date) }}</span>\r\n <label class=\"all-day-toggle\">\r\n <span class=\"toggle-label\">All Day</span>\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"dateConfig.allDay\"\r\n (change)=\"onMultipleDateAllDayChange(i)\">\r\n </label>\r\n </div>\r\n <div *ngIf=\"!dateConfig.allDay\" class=\"time-inputs\">\r\n <bk-time-picker\r\n [pickerId]=\"'multiple-' + i + '-start'\"\r\n label=\"Start Time\"\r\n [value]=\"dateConfig.startTime\"\r\n [position]=\"'left'\"\r\n [closePicker]=\"shouldClosePicker('multiple-' + i + '-start')\"\r\n (timeChange)=\"onMultipleDateStartTimeChange(i, $event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n <bk-time-picker\r\n [pickerId]=\"'multiple-' + i + '-end'\"\r\n label=\"End Time\"\r\n [value]=\"dateConfig.endTime\"\r\n [position]=\"'right'\"\r\n [closePicker]=\"shouldClosePicker('multiple-' + i + '-end')\"\r\n (timeChange)=\"onMultipleDateEndTimeChange(i, $event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n <div *ngIf=\"multipleDates.length === 0\" class=\"no-selection\">\r\n <p>No dates selected. Select dates from the calendar.</p>\r\n </div>\r\n </div>\r\n\r\n <!-- Date Range Time Configuration -->\r\n <div *ngIf=\"activeTab === 'range' && rangeStartDate && rangeEndDate\" class=\"time-config-item\">\r\n <div class=\"time-config-header\">\r\n <span class=\"date-label\">{{ formatDate(rangeStartDate) }} - {{ formatDate(rangeEndDate) }}</span>\r\n <label class=\"all-day-toggle\">\r\n <span class=\"toggle-label\">All Day</span>\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"rangeAllDay\"\r\n (change)=\"onRangeAllDayChange()\">\r\n </label>\r\n </div>\r\n <div *ngIf=\"!rangeAllDay\" class=\"time-inputs\">\r\n <bk-time-picker\r\n pickerId=\"range-start\"\r\n label=\"Start Time\"\r\n [value]=\"rangeStartTime\"\r\n [position]=\"'left'\"\r\n [closePicker]=\"shouldClosePicker('range-start')\"\r\n (timeChange)=\"onRangeStartTimeChange($event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n <bk-time-picker\r\n pickerId=\"range-end\"\r\n label=\"End Time\"\r\n [value]=\"rangeEndTime\"\r\n [position]=\"'right'\"\r\n [closePicker]=\"shouldClosePicker('range-end')\"\r\n (timeChange)=\"onRangeEndTimeChange($event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n <div *ngIf=\"activeTab === 'range' && (!rangeStartDate || !rangeEndDate)\" class=\"no-selection\">\r\n <p>No date range selected. Select a date range from the calendar.</p>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Action Buttons -->\r\n <div class=\"action-buttons\">\r\n <button class=\"btn-clear\" (click)=\"clear()\">Clear</button>\r\n <button class=\"btn-apply\" (click)=\"apply()\">Apply</button>\r\n </div>\r\n</div>\r\n\r\n", styles: [".scheduled-date-picker-container{font-family:Inter,sans-serif;background:#fff;border-radius:12px;padding:0;box-shadow:0 2px 8px #0000001a;overflow:hidden;width:100%;max-width:100%;box-sizing:border-box}.scheduled-header{padding:24px 24px 16px;border-bottom:1px solid #e5e7eb;background:#fff}.scheduled-title{font-size:18px;font-weight:500;line-height:26px;color:#111827;letter-spacing:-.28px;margin:0 0 16px}.tabs{display:flex;margin-bottom:16px;border-radius:6px;padding:3px;background-color:#54578e12}.tab-button{padding:5px 11px;border:none;background:transparent;color:#6b7080;font-size:11px;font-weight:500;cursor:pointer;border:1px solid transparent;transition:all .2s;font-family:Inter,sans-serif;flex:1;border-radius:4px}.tab-button.active{color:#15191e;border-color:#42578a26;background:#fff}.scheduled-content{display:flex;gap:0;align-items:stretch}.calendar-section{flex:0 0 55%;max-width:55%;padding:12px;border-right:1px solid #e5e7eb;background:#fff;box-sizing:border-box}.calendar-wrapper-inline{width:100%}.calendar-wrapper-inline app-custom-calendar{width:100%}.time-config-section{flex:0 0 45%;max-width:45%;padding:12px;background:#fff;overflow-y:auto;max-height:600px;box-sizing:border-box}.time-config-title{font-size:16px;font-weight:600;color:#111827;margin:17px 0 14px}.time-config-item{padding:14px;border:1px solid #e5e7eb;border-radius:8px;background:#fff}.time-config-header{display:flex;justify-content:space-between;align-items:center}.date-label{font-size:12px;font-weight:500;color:#15191e;letter-spacing:-.28px}.all-day-toggle{display:flex;align-items:center;gap:5px;cursor:pointer;-webkit-user-select:none;user-select:none}.all-day-toggle input[type=checkbox]{width:28px;height:16px;appearance:none;background:#bbbdc5;border-radius:10px;position:relative;cursor:pointer;transition:background .2s;margin:0}.all-day-toggle input[type=checkbox]:checked{background:#22973f}.all-day-toggle input[type=checkbox]:before{content:\"\";position:absolute;width:12px;height:12px;border-radius:50%;background:#fff;top:1.5px;left:2.5px;transition:transform .2s;box-shadow:0 1px 3px #0003}.all-day-toggle input[type=checkbox]:checked:before{transform:translate(12px)}.toggle-label{font-size:12px;font-weight:500;color:#111827}.all-day-toggle input[type=checkbox]:checked+.toggle-label{color:#111827}.time-inputs{display:flex;gap:14px;margin-top:12px}.time-config-list{display:flex;flex-direction:column;gap:14px;max-height:350px;overflow-y:auto;padding-right:4px}.time-config-list::-webkit-scrollbar{width:6px;height:6px}.time-config-list::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}.time-config-list::-webkit-scrollbar-thumb{background:#b4b4b4;border-radius:3px}.time-config-list::-webkit-scrollbar-thumb:hover{background:#9b9b9b}.no-selection{padding:24px;text-align:center;color:#9ca3af;font-size:14px}.action-buttons{display:flex;justify-content:flex-end;gap:12px;padding:12px;border-top:1px solid #e5e7eb;background:#fff}.btn-clear,.btn-apply{padding:10px 20px;border:none;border-radius:6px;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s;font-family:Inter,sans-serif;min-width:80px}.btn-clear{background:#fff;color:#6b7280;border:1px solid #d1d5db}.btn-clear:hover{background:#f9fafb;border-color:#9ca3af}.btn-apply{background:#111827;color:#fff}.btn-apply:hover{background:#374151}@media (max-width: 1200px){.calendar-section{flex:0 0 52%;max-width:52%}.time-config-section{flex:0 0 48%;max-width:48%}}@media (max-width: 1024px){.scheduled-content{flex-direction:column}.calendar-section{flex:1 1 auto;max-width:100%;border-right:none;border-bottom:1px solid #e5e7eb}.time-config-section{flex:1 1 auto;max-width:100%;max-height:none}.time-config-list{max-height:320px}}@media (max-width: 768px){.scheduled-date-picker-container{border-radius:0}.scheduled-header{padding:16px}.calendar-section,.time-config-section{padding:12px 16px}.tabs{overflow-x:auto}.tab-button{white-space:nowrap;font-size:12px;padding:6px 10px}.time-inputs{flex-direction:column}.time-config-item{padding:12px}.action-buttons{padding:10px}}@media (max-width: 480px){.scheduled-title{font-size:16px}.time-config-title{font-size:14px}.date-label{font-size:11px}.time-config-list{max-height:260px}.btn-clear,.btn-apply{padding:8px 14px;font-size:13px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: BkCustomCalendar, selector: "bk-custom-calendar", inputs: ["enableTimepicker", "autoApply", "closeOnAutoApply", "showCancel", "linkedCalendars", "singleDatePicker", "showWeekNumbers", "showISOWeekNumbers", "customRangeDirection", "lockStartDate", "position", "drop", "dualCalendar", "showRanges", "timeFormat", "enableSeconds", "customRanges", "multiDateSelection", "maxDate", "minDate", "placeholder", "opens", "inline", "isDisplayCrossIcon", "selectedValue", "displayFormat", "startDate", "endDate"], outputs: ["selected", "opened", "closed"] }, { kind: "component", type: BkTimePicker, selector: "bk-time-picker", inputs: ["value", "label", "placeholder", "position", "pickerId", "closePicker", "timeFormat", "showSeconds"], outputs: ["timeChange", "pickerOpened", "pickerClosed"] }] });
|
|
2488
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: BkScheduledDatePicker, isStandalone: true, selector: "bk-scheduled-date-picker", inputs: { timeFormat: "timeFormat", enableSeconds: "enableSeconds" }, outputs: { scheduled: "scheduled", cleared: "cleared" }, ngImport: i0, template: "<div class=\"scheduled-date-picker-container\">\r\n <!-- Header with Tabs -->\r\n\r\n\r\n <!-- Main Content Area -->\r\n\r\n <div class=\"scheduled-content\">\r\n <!-- Left Side: Calendar -->\r\n <div class=\"calendar-section\">\r\n <h2 class=\"scheduled-title\">Scheduled Dates</h2>\r\n <div class=\"tabs\">\r\n <button\r\n class=\"tab-button\"\r\n [class.active]=\"activeTab === 'single'\"\r\n (click)=\"onTabChange('single')\">\r\n Single Date\r\n </button>\r\n <button\r\n class=\"tab-button\"\r\n [class.active]=\"activeTab === 'multiple'\"\r\n (click)=\"onTabChange('multiple')\">\r\n Multiple Dates\r\n </button>\r\n <button\r\n class=\"tab-button\"\r\n [class.active]=\"activeTab === 'range'\"\r\n (click)=\"onTabChange('range')\">\r\n Date Range\r\n </button>\r\n </div>\r\n <!-- Single Date Calendar -->\r\n <div *ngIf=\"activeTab === 'single'\" class=\"calendar-wrapper-inline\">\r\n <bk-custom-calendar\r\n [inline]=\"true\"\r\n [dualCalendar]=\"false\"\r\n [singleDatePicker]=\"true\"\r\n [showRanges]=\"false\"\r\n [enableTimepicker]=\"false\"\r\n [showCancel]=\"false\"\r\n placeholder=\"Select a date\"\r\n (selected)=\"onSingleDateSelected($event)\">\r\n </bk-custom-calendar>\r\n </div>\r\n\r\n <!-- Multiple Dates Calendar -->\r\n <div *ngIf=\"activeTab === 'multiple'\" class=\"calendar-wrapper-inline\">\r\n <bk-custom-calendar\r\n [inline]=\"true\"\r\n [dualCalendar]=\"false\"\r\n [singleDatePicker]=\"false\"\r\n [showRanges]=\"false\"\r\n [enableTimepicker]=\"false\"\r\n [multiDateSelection]=\"true\"\r\n [showCancel]=\"false\"\r\n placeholder=\"Select multiple dates\"\r\n (selected)=\"onMultipleDatesSelected($event)\">\r\n </bk-custom-calendar>\r\n </div>\r\n\r\n <!-- Date Range Calendar -->\r\n <div *ngIf=\"activeTab === 'range'\" class=\"calendar-wrapper-inline\">\r\n <bk-custom-calendar\r\n [inline]=\"true\"\r\n [dualCalendar]=\"false\"\r\n [singleDatePicker]=\"false\"\r\n [showRanges]=\"false\"\r\n [enableTimepicker]=\"false\"\r\n [showCancel]=\"false\"\r\n placeholder=\"Select date range\"\r\n (selected)=\"onRangeSelected($event)\">\r\n </bk-custom-calendar>\r\n </div>\r\n </div>\r\n\r\n <!-- Right Side: Time Configuration -->\r\n <div class=\"time-config-section\">\r\n <h3 class=\"time-config-title\">Time Configuration</h3>\r\n\r\n <!-- Single Date Time Configuration -->\r\n <div *ngIf=\"activeTab === 'single'\">\r\n <div *ngIf=\"singleDate\" class=\"time-config-item\">\r\n <div class=\"time-config-header\">\r\n <span class=\"date-label\">{{ formatDate(singleDate) }}</span>\r\n <label class=\"all-day-toggle\">\r\n <span class=\"toggle-label\">All Day</span>\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"singleAllDay\"\r\n (change)=\"onSingleAllDayChange()\">\r\n </label>\r\n </div>\r\n <div *ngIf=\"!singleAllDay\" class=\"time-inputs\">\r\n <bk-time-picker\r\n pickerId=\"single-start\"\r\n label=\"Start Time\"\r\n [value]=\"singleStartTime\"\r\n [position]=\"'left'\"\r\n [closePicker]=\"shouldClosePicker('single-start')\"\r\n (timeChange)=\"onSingleStartTimeChange($event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n <bk-time-picker\r\n pickerId=\"single-end\"\r\n label=\"End Time\"\r\n [value]=\"singleEndTime\"\r\n [position]=\"'right'\"\r\n [closePicker]=\"shouldClosePicker('single-end')\"\r\n (timeChange)=\"onSingleEndTimeChange($event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n <div *ngIf=\"!singleDate\" class=\"no-selection\">\r\n <p>No date selected. Select a date from the calendar.</p>\r\n </div>\r\n </div>\r\n\r\n <!-- Multiple Dates Time Configuration -->\r\n <div *ngIf=\"activeTab === 'multiple'\" class=\"time-config-list\">\r\n <div\r\n *ngFor=\"let dateConfig of multipleDates; let i = index\"\r\n class=\"time-config-item\">\r\n <div class=\"time-config-header\">\r\n <span class=\"date-label\">{{ formatDate(dateConfig.date) }}</span>\r\n <label class=\"all-day-toggle\">\r\n <span class=\"toggle-label\">All Day</span>\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"dateConfig.allDay\"\r\n (change)=\"onMultipleDateAllDayChange(i)\">\r\n </label>\r\n </div>\r\n <div *ngIf=\"!dateConfig.allDay\" class=\"time-inputs\">\r\n <bk-time-picker\r\n [pickerId]=\"'multiple-' + i + '-start'\"\r\n label=\"Start Time\"\r\n [value]=\"dateConfig.startTime\"\r\n [position]=\"'left'\"\r\n [closePicker]=\"shouldClosePicker('multiple-' + i + '-start')\"\r\n (timeChange)=\"onMultipleDateStartTimeChange(i, $event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n <bk-time-picker\r\n [pickerId]=\"'multiple-' + i + '-end'\"\r\n label=\"End Time\"\r\n [value]=\"dateConfig.endTime\"\r\n [position]=\"'right'\"\r\n [closePicker]=\"shouldClosePicker('multiple-' + i + '-end')\"\r\n (timeChange)=\"onMultipleDateEndTimeChange(i, $event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n <div *ngIf=\"multipleDates.length === 0\" class=\"no-selection\">\r\n <p>No dates selected. Select dates from the calendar.</p>\r\n </div>\r\n </div>\r\n\r\n <!-- Date Range Time Configuration -->\r\n <div *ngIf=\"activeTab === 'range' && rangeStartDate && rangeEndDate\" class=\"time-config-item\">\r\n <div class=\"time-config-header\">\r\n <span class=\"date-label\">{{ formatDate(rangeStartDate) }} - {{ formatDate(rangeEndDate) }}</span>\r\n <label class=\"all-day-toggle\">\r\n <span class=\"toggle-label\">All Day</span>\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"rangeAllDay\"\r\n (change)=\"onRangeAllDayChange()\">\r\n </label>\r\n </div>\r\n <div *ngIf=\"!rangeAllDay\" class=\"time-inputs\">\r\n <bk-time-picker\r\n pickerId=\"range-start\"\r\n label=\"Start Time\"\r\n [value]=\"rangeStartTime\"\r\n [position]=\"'left'\"\r\n [closePicker]=\"shouldClosePicker('range-start')\"\r\n (timeChange)=\"onRangeStartTimeChange($event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n <bk-time-picker\r\n pickerId=\"range-end\"\r\n label=\"End Time\"\r\n [value]=\"rangeEndTime\"\r\n [position]=\"'right'\"\r\n [closePicker]=\"shouldClosePicker('range-end')\"\r\n (timeChange)=\"onRangeEndTimeChange($event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n <div *ngIf=\"activeTab === 'range' && (!rangeStartDate || !rangeEndDate)\" class=\"no-selection\">\r\n <p>No date range selected. Select a date range from the calendar.</p>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Action Buttons -->\r\n <div class=\"action-buttons\">\r\n <button class=\"btn-clear\" (click)=\"clear()\">Clear</button>\r\n <button class=\"btn-apply\" (click)=\"apply()\">Apply</button>\r\n </div>\r\n</div>\r\n\r\n", styles: [".scheduled-date-picker-container{font-family:Inter,sans-serif;background:#fff;border-radius:12px;padding:0;box-shadow:0 2px 8px #0000001a;overflow:hidden;width:100%;max-width:100%;box-sizing:border-box}.scheduled-header{padding:24px 24px 16px;border-bottom:1px solid #e5e7eb;background:#fff}.scheduled-title{font-size:18px;font-weight:500;line-height:26px;color:#111827;letter-spacing:-.28px;margin:0 0 16px}.tabs{display:flex;margin-bottom:16px;border-radius:6px;padding:3px;background-color:#54578e12}.tab-button{padding:5px 11px;border:none;background:transparent;color:#6b7080;font-size:11px;font-weight:500;cursor:pointer;border:1px solid transparent;transition:all .2s;font-family:Inter,sans-serif;flex:1;border-radius:4px}.tab-button.active{color:#15191e;border-color:#42578a26;background:#fff}.scheduled-content{display:flex;gap:0;align-items:stretch}.calendar-section{flex:0 0 55%;max-width:55%;padding:12px;border-right:1px solid #e5e7eb;background:#fff;box-sizing:border-box}.calendar-wrapper-inline{width:100%}.calendar-wrapper-inline app-custom-calendar{width:100%}.time-config-section{flex:0 0 45%;max-width:45%;padding:12px;background:#fff;overflow-y:auto;max-height:600px;box-sizing:border-box}.time-config-title{font-size:16px;font-weight:600;color:#111827;margin:17px 0 14px}.time-config-item{padding:14px;border:1px solid #e5e7eb;border-radius:8px;background:#fff}.time-config-header{display:flex;justify-content:space-between;align-items:center}.date-label{font-size:12px;font-weight:500;color:#15191e;letter-spacing:-.28px}.all-day-toggle{display:flex;align-items:center;gap:5px;cursor:pointer;-webkit-user-select:none;user-select:none}.all-day-toggle input[type=checkbox]{width:28px;height:16px;appearance:none;background:#bbbdc5;border-radius:10px;position:relative;cursor:pointer;transition:background .2s;margin:0}.all-day-toggle input[type=checkbox]:checked{background:#22973f}.all-day-toggle input[type=checkbox]:before{content:\"\";position:absolute;width:12px;height:12px;border-radius:50%;background:#fff;top:1.5px;left:2.5px;transition:transform .2s;box-shadow:0 1px 3px #0003}.all-day-toggle input[type=checkbox]:checked:before{transform:translate(12px)}.toggle-label{font-size:12px;font-weight:500;color:#111827}.all-day-toggle input[type=checkbox]:checked+.toggle-label{color:#111827}.time-inputs{display:flex;gap:14px;margin-top:12px}.time-config-list{display:flex;flex-direction:column;gap:14px;max-height:350px;overflow-y:auto;padding-right:4px}.time-config-list::-webkit-scrollbar{width:6px;height:6px}.time-config-list::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}.time-config-list::-webkit-scrollbar-thumb{background:#b4b4b4;border-radius:3px}.time-config-list::-webkit-scrollbar-thumb:hover{background:#9b9b9b}.no-selection{padding:24px;text-align:center;color:#9ca3af;font-size:14px}.action-buttons{display:flex;justify-content:flex-end;gap:12px;padding:12px;border-top:1px solid #e5e7eb;background:#fff}.btn-clear,.btn-apply{padding:10px 20px;border:none;border-radius:6px;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s;font-family:Inter,sans-serif;min-width:80px}.btn-clear{background:#fff;color:#6b7280;border:1px solid #d1d5db}.btn-clear:hover{background:#f9fafb;border-color:#9ca3af}.btn-apply{background:#111827;color:#fff}.btn-apply:hover{background:#374151}@media (max-width: 1200px){.calendar-section{flex:0 0 52%;max-width:52%}.time-config-section{flex:0 0 48%;max-width:48%}}@media (max-width: 1024px){.scheduled-content{flex-direction:column}.calendar-section{flex:1 1 auto;max-width:100%;border-right:none;border-bottom:1px solid #e5e7eb}.time-config-section{flex:1 1 auto;max-width:100%;max-height:none}.time-config-list{max-height:320px}}@media (max-width: 768px){.scheduled-date-picker-container{border-radius:0}.scheduled-header{padding:16px}.calendar-section,.time-config-section{padding:12px 16px}.tabs{overflow-x:auto}.tab-button{white-space:nowrap;font-size:12px;padding:6px 10px}.time-inputs{flex-direction:column}.time-config-item{padding:12px}.action-buttons{padding:10px}}@media (max-width: 480px){.scheduled-title{font-size:16px}.time-config-title{font-size:14px}.date-label{font-size:11px}.time-config-list{max-height:260px}.btn-clear,.btn-apply{padding:8px 14px;font-size:13px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: BkCustomCalendar, selector: "bk-custom-calendar", inputs: ["enableTimepicker", "autoApply", "closeOnAutoApply", "showCancel", "linkedCalendars", "singleDatePicker", "showWeekNumbers", "showISOWeekNumbers", "customRangeDirection", "lockStartDate", "position", "drop", "dualCalendar", "showRanges", "timeFormat", "enableSeconds", "customRanges", "multiDateSelection", "maxDate", "minDate", "placeholder", "opens", "inline", "appendToBody", "isDisplayCrossIcon", "hasError", "errorMessage", "showCancelApply", "selectedValue", "displayFormat", "required"], outputs: ["selected", "opened", "closed"] }, { kind: "component", type: BkTimePicker, selector: "bk-time-picker", inputs: ["value", "label", "placeholder", "position", "pickerId", "closePicker", "timeFormat", "showSeconds"], outputs: ["timeChange", "pickerOpened", "pickerClosed"] }] });
|
|
2243
2489
|
}
|
|
2244
2490
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkScheduledDatePicker, decorators: [{
|
|
2245
2491
|
type: Component,
|
|
@@ -3651,6 +3897,9 @@ class BkSelect {
|
|
|
3651
3897
|
const key = this.colorKey();
|
|
3652
3898
|
return key && typeof item === 'object' ? item[key] : null;
|
|
3653
3899
|
}
|
|
3900
|
+
getRemainingItems() {
|
|
3901
|
+
return this.selectedOptions().slice(this.maxLabels()).map((x) => x.label);
|
|
3902
|
+
}
|
|
3654
3903
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkSelect, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3655
3904
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkSelect, isStandalone: true, selector: "bk-select", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, bindLabel: { classPropertyName: "bindLabel", publicName: "bindLabel", isSignal: true, isRequired: false, transformFunction: null }, bindValue: { classPropertyName: "bindValue", publicName: "bindValue", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, notFoundText: { classPropertyName: "notFoundText", publicName: "notFoundText", isSignal: true, isRequired: false, transformFunction: null }, loadingText: { classPropertyName: "loadingText", publicName: "loadingText", isSignal: true, isRequired: false, transformFunction: null }, clearAllText: { classPropertyName: "clearAllText", publicName: "clearAllText", isSignal: true, isRequired: false, transformFunction: null }, groupBy: { classPropertyName: "groupBy", publicName: "groupBy", isSignal: true, isRequired: false, transformFunction: null }, colorKey: { classPropertyName: "colorKey", publicName: "colorKey", isSignal: true, isRequired: false, transformFunction: null }, iconAlt: { classPropertyName: "iconAlt", publicName: "iconAlt", isSignal: false, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: false, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: false, isRequired: false, transformFunction: null }, iconSrc: { classPropertyName: "iconSrc", publicName: "iconSrc", isSignal: false, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, maxLabels: { classPropertyName: "maxLabels", publicName: "maxLabels", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, allSelect: { classPropertyName: "allSelect", publicName: "allSelect", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, closeOnSelect: { classPropertyName: "closeOnSelect", publicName: "closeOnSelect", isSignal: true, isRequired: false, transformFunction: null }, dropdownPosition: { classPropertyName: "dropdownPosition", publicName: "dropdownPosition", isSignal: true, isRequired: false, transformFunction: null }, hasError: { classPropertyName: "hasError", publicName: "hasError", isSignal: false, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: false, isRequired: false, transformFunction: null }, appendToBody: { classPropertyName: "appendToBody", publicName: "appendToBody", isSignal: true, isRequired: false, transformFunction: null }, compareWith: { classPropertyName: "compareWith", publicName: "compareWith", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { disabled: "disabledChange", open: "open", close: "close", focus: "focus", blur: "blur", search: "search", clear: "clear", change: "change", scrollToEnd: "scrollToEnd" }, host: { listeners: { "window:scroll": "onWindowEvents()", "window:resize": "onWindowEvents()", "document:click": "onClickOutside($event)" } }, providers: [
|
|
3656
3905
|
{
|
|
@@ -3658,17 +3907,17 @@ class BkSelect {
|
|
|
3658
3907
|
useExisting: forwardRef(() => BkSelect),
|
|
3659
3908
|
multi: true
|
|
3660
3909
|
}
|
|
3661
|
-
], viewQueries: [{ propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true }, { propertyName: "optionsListContainer", first: true, predicate: ["optionsListContainer"], descendants: true }, { propertyName: "controlWrapper", first: true, predicate: ["controlWrapper"], descendants: true }, { propertyName: "optionsRef", predicate: ["optionsRef"], descendants: true }], ngImport: i0, template: "<div class=\"bk-select-container\">\r\n\r\n @if(label){\r\n <label\r\n class=\"bk-select-label\"\r\n (click)=\"openFromLabel($event)\">\r\n {{ label }}\r\n @if (required) {\r\n <span class=\"bk-select-label-required\">*</span>\r\n }\r\n </label>\r\n }\r\n\r\n <div\r\n #controlWrapper\r\n class=\"bk-select-control\"\r\n [ngClass]=\"{ 'bk-has-error': hasError }\"\r\n\r\n tabindex=\"0\"\r\n (keydown)=\"onKeyDown($event)\"\r\n [class.bk-focused]=\"isOpen()\"\r\n [class.bk-disabled]=\"disabled()\"\r\n (mousedown)=\"toggleDropdown($event)\"\r\n >\r\n <!-- Icon (Always visible if set) -->\r\n @if (iconSrc) {\r\n <img [src]=\"iconSrc\" [alt]=\"iconAlt\" class=\"shrink-0\"/>\r\n }\r\n <div class=\"bk-value-container\">\r\n @if (selectedOptions().length === 0) {\r\n <div class=\"bk-placeholder\">{{ placeholder() }}</div>\r\n }\r\n @if (multiple() && selectedOptions().length > 0) {\r\n <div class=\"bk-value-chips\">\r\n @for (opt of selectedOptions().slice(0, maxLabels()); track $index) {\r\n <div class=\"bk-multi-badge-item\">\r\n <span class=\"bk-multi-badge-item-text\" [style.color]=\"resolveColor(opt)\">{{ resolveLabel(opt) }}</span>\r\n\r\n <button type=\"button\" (mousedown)=\"removeOption(opt, $event)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"none\">\r\n <path d=\"M6.625 0.625L0.625 6.625M0.625 0.625L6.625 6.625\" stroke=\"#BBBDC5\" stroke-width=\"1.25\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n }\r\n @if (selectedOptions().length > maxLabels()) {\r\n <div class=\"bk-multi-badge-item\"><span\r\n class=\"bk-multi-badge-item-text\">+{{ selectedOptions().length - maxLabels() }}</span></div>\r\n }\r\n </div>\r\n }\r\n @if (!multiple() && selectedOptions().length > 0) {\r\n <div class=\"bk-value-label-single\" [style.color]=\"resolveColor(selectedOptions()[0])\">\r\n {{ resolveLabel(selectedOptions()[0]) }}</div>\r\n }\r\n </div>\r\n <div class=\"bk-actions\">\r\n @if (clearable() && selectedOptions().length > 0 && !disabled()) {\r\n <span class=\"bk-clear-wrapper\" (mousedown)=\"handleClear($event)\" title=\"Clear\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"18\"\r\n y1=\"6\" x2=\"6\"\r\n y2=\"18\"></line><line\r\n x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line></svg>\r\n </span>\r\n }\r\n <span class=\"bk-arrow-wrapper\" [class.bk-open]=\"isOpen()\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path\r\n d=\"m6 9 6 6 6-6\"/></svg>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n @if (isOpen()) {\r\n <div\r\n #dropdownPanel\r\n class=\"bk-dropdown-panel\"\r\n [attr.data-position]=\"dropdownPosition()\"\r\n (scroll)=\"onScroll($event)\"\r\n\r\n [style.position]=\"appendToBody() ? 'fixed' : 'absolute'\"\r\n [style.top]=\"getTop()\"\r\n [style.bottom]=\"getBottom()\"\r\n [style.left]=\"appendToBody() ? dropdownStyle().left : null\"\r\n [style.width]=\"appendToBody() ? dropdownStyle().width : '100%'\"\r\n [class.bk-grouped]=\"groupBy()\"\r\n >\r\n\r\n\r\n @if (searchable()) {\r\n <div class=\"bk-dropdown-search\">\r\n <div class=\"bk-search-wrapper\">\r\n <svg class=\"text-[#BBBDC5] mr-2\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\">\r\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\r\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>\r\n </svg>\r\n <input #searchInput type=\"text\" class=\"bk-search-input\" [value]=\"searchTerm()\" [placeholder]=\"'Search...'\"\r\n (input)=\"onSearchInput($event)\" (keydown)=\"onKeyDown($event)\" (click)=\"$event.stopPropagation()\">\r\n </div>\r\n </div>\r\n }\r\n <div #optionsListContainer class=\"bk-options-list\">\r\n @if (loading()) {\r\n <div class=\"bk-option-disabled\">{{ loadingText() }}</div>\r\n } @else {\r\n @if (allSelect()){\r\n\r\n @if (multiple() && filteredItems().length > 0) {\r\n <div class=\"bk-option\" (mousedown)=\"toggleSelectAll($event)\" [class.bk-selected]=\"isAllSelected()\">\r\n <div class=\"flex-1 flex justify-between\">\r\n <span>Select All</span>\r\n @if (isAllSelected()) {\r\n <svg class=\"text-[#141414]\" width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2.5\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n }\r\n </div>\r\n </div>\r\n }\r\n }\r\n @for (group of groupedItems(); track $index) {\r\n\r\n @if (group.group) {\r\n <div class=\"bk-option-group\">\r\n {{ group.group }}\r\n </div>\r\n }\r\n\r\n @for (item of group.items; track $index) {\r\n <div #optionsRef class=\"bk-option\" [class.bk-selected]=\"isItemSelected(item)\" [class.bk-marked]=\"$index === markedIndex()\" (click)=\"handleSelection(item, $event)\">\r\n <div class=\"flex-1 flex justify-between\">\r\n <span [style.color]=\"resolveColor(item)\">{{ resolveLabel(item) }}</span>\r\n\r\n @if (isItemSelected(item)) {\r\n <svg class=\"text-[#141414]\" width=\"17\" height=\"17\" viewBox=\"0 0 24 24\"\r\n fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n }\r\n\r\n @if (filteredItems().length === 0) {\r\n <div class=\"bk-option-disabled\">{{ notFoundText() }}</div>\r\n }\r\n }\r\n </div>\r\n\r\n </div>\r\n }\r\n @if(hasError){\r\n @if (errorMessage) {\r\n <p class=\"bk-select-error\">{{ errorMessage }}</p>\r\n }\r\n }\r\n\r\n\r\n</div>\r\n", styles: [".bk-select-container{@apply relative w-full box-border flex flex-col gap-1.5;}.bk-select-control{@apply flex items-center justify-between gap-2 w-full bg-white border border-[#E3E3E7] rounded transition-all duration-200 px-3 py-2.5 cursor-pointer;}.bk-select-control.bk-focused{@apply border-[#6B7080] shadow-none z-10;}.bk-select-control.bk-disabled{@apply bg-[#F4F4F6] cursor-not-allowed opacity-60;}.bk-select-control.bk-has-error{@apply border-[#d11e14];}.bk-value-container{@apply flex flex-1 items-center flex-wrap gap-1 relative overflow-hidden h-full;}.bk-placeholder{@apply text-[#6B7080] font-normal text-sm truncate w-full pointer-events-none;}.bk-value-label-single{@apply font-normal text-sm leading-[18px] text-[#141414] truncate w-full;}.bk-multi-badge-item{@apply inline-flex items-center gap-1.5 px-1.5 py-0.5 bg-white border border-[#E3E3E7] rounded-[4px];}.bk-multi-badge-item-text{@apply text-[10px] leading-[14px] font-normal text-[#6B7080];}.bk-multi-badge-close{@apply cursor-pointer outline-none w-3 h-3;}.bk-actions{@apply flex items-center gap-0.5 flex-shrink-0;}.bk-clear-wrapper{@apply text-gray-400 hover:text-red-500 cursor-pointer;}.bk-arrow-wrapper{@apply text-gray-400 transition-transform duration-200;}.bk-arrow-wrapper.bk-open{@apply rotate-180;}.bk-dropdown-panel{@apply absolute left-0 w-full bg-white border border-[#E3E3E7] rounded-xl shadow-lg z-[99] overflow-hidden cursor-default p-2.5;}.bk-dropdown-search{@apply px-2 pt-2;}.bk-search-wrapper{@apply flex items-center border border-[#E3E3E7] rounded-md px-3 py-[7px] bg-white transition-colors focus-within:border-[#E3E3E7];}.bk-search-input{@apply w-full outline-none font-normal text-sm text-[#141414] placeholder-[#A1A3AE] bg-transparent;}.bk-options-list{@apply max-h-60 overflow-auto relative flex flex-col gap-0.5;}.bk-option{@apply flex items-center p-2.5 cursor-pointer transition-colors font-normal text-sm text-[#141414];}.bk-option:hover,.bk-option.bk-marked,.bk-option.bk-selected{@apply bg-[#F8F8F8] rounded-md;}.bk-grouped .bk-option{@apply ps-5;}.bk-option-disabled{@apply px-3 py-2 text-gray-400 cursor-default;}.bk-select-all-option{@apply sticky top-0 z-20 flex items-center px-3 py-2 cursor-pointer border-b border-[#E3E6EE] bg-gray-50 text-[#15191E];}.bk-select-all-option:hover{@apply bg-gray-100;}.bk-dropdown-panel[data-position=top]{margin-top:0;margin-bottom:4px}.bk-select-label{@apply text-sm font-medium text-[#141414] tracking-[-.28px] inline-block;}.bk-select-label-required{@apply text-[#E7000B];}.bk-options-list ::-webkit-scrollbar{width:10px}.bk-options-list ::-webkit-scrollbar-track{background:transparent;border-radius:8px;width:8px}.bk-options-list ::-webkit-scrollbar-thumb{background:#d6d7dc;border-radius:8px;transition:.3s ease-in-out}.bk-options-list ::-webkit-scrollbar-thumb:hover{background:#909090}.bk-option-group{@apply px-2.5 py-1 font-bold text-[13px] leading-5 text-[#141414];}.bk-option-group:not(:first-child){@apply mt-4;}.bk-select-error{@apply text-xs text-[#E7000B] font-normal;}.bk-select-hint{@apply text-xs text-[#868997] font-normal;}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }] });
|
|
3910
|
+
], viewQueries: [{ propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true }, { propertyName: "optionsListContainer", first: true, predicate: ["optionsListContainer"], descendants: true }, { propertyName: "controlWrapper", first: true, predicate: ["controlWrapper"], descendants: true }, { propertyName: "optionsRef", predicate: ["optionsRef"], descendants: true }], ngImport: i0, template: "<div class=\"bk-select-container\">\r\n\r\n @if(label){\r\n <label\r\n class=\"bk-select-label\"\r\n (click)=\"openFromLabel($event)\">\r\n {{ label }}\r\n @if (required) {\r\n <span class=\"bk-select-label-required\">*</span>\r\n }\r\n </label>\r\n }\r\n\r\n <div\r\n #controlWrapper\r\n class=\"bk-select-control\"\r\n [ngClass]=\"{ 'bk-has-error': hasError }\"\r\n\r\n tabindex=\"0\"\r\n (keydown)=\"onKeyDown($event)\"\r\n [class.bk-focused]=\"isOpen()\"\r\n [class.bk-disabled]=\"disabled()\"\r\n (mousedown)=\"toggleDropdown($event)\"\r\n >\r\n <!-- Icon (Always visible if set) -->\r\n @if (iconSrc) {\r\n <img [src]=\"iconSrc\" [alt]=\"iconAlt\" class=\"shrink-0\"/>\r\n }\r\n <div class=\"bk-value-container\">\r\n @if (selectedOptions().length === 0) {\r\n <div class=\"bk-placeholder\">{{ placeholder() }}</div>\r\n }\r\n @if (multiple() && selectedOptions().length > 0) {\r\n <div class=\"bk-value-chips\">\r\n @for (opt of selectedOptions().slice(0, maxLabels()); track $index) {\r\n <div class=\"bk-multi-badge-item me-0.5\">\r\n <span class=\"bk-multi-badge-item-text\" [style.color]=\"resolveColor(opt)\">{{ resolveLabel(opt) }}</span>\r\n\r\n <button type=\"button\" (mousedown)=\"removeOption(opt, $event)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"none\">\r\n <path d=\"M6.625 0.625L0.625 6.625M0.625 0.625L6.625 6.625\" stroke=\"#BBBDC5\" stroke-width=\"1.25\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n }\r\n @if (selectedOptions().length > maxLabels()) {\r\n <div class=\"bk-multi-badge-item\"><span\r\n class=\"bk-multi-badge-item-text\" bkTooltipPosition=\"top\" [bkTooltip]=\"getRemainingItems()\">+{{ selectedOptions().length - maxLabels() }}</span></div>\r\n\r\n\r\n }\r\n </div>\r\n }\r\n @if (!multiple() && selectedOptions().length > 0) {\r\n <div class=\"bk-value-label-single\" [style.color]=\"resolveColor(selectedOptions()[0])\">\r\n {{ resolveLabel(selectedOptions()[0]) }}</div>\r\n }\r\n </div>\r\n <div class=\"bk-actions\">\r\n @if (clearable() && selectedOptions().length > 0 && !disabled()) {\r\n <span class=\"bk-clear-wrapper\" (mousedown)=\"handleClear($event)\" title=\"Clear\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"18\"\r\n y1=\"6\" x2=\"6\"\r\n y2=\"18\"></line><line\r\n x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line></svg>\r\n </span>\r\n }\r\n <span class=\"bk-arrow-wrapper\" [class.bk-open]=\"isOpen()\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path\r\n d=\"m6 9 6 6 6-6\"/></svg>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n @if (isOpen()) {\r\n <div\r\n #dropdownPanel\r\n class=\"bk-dropdown-panel\"\r\n [attr.data-position]=\"dropdownPosition()\"\r\n (scroll)=\"onScroll($event)\"\r\n\r\n [style.position]=\"appendToBody() ? 'fixed' : 'absolute'\"\r\n [style.top]=\"getTop()\"\r\n [style.bottom]=\"getBottom()\"\r\n [style.left]=\"appendToBody() ? dropdownStyle().left : null\"\r\n [style.width]=\"appendToBody() ? dropdownStyle().width : '100%'\"\r\n [class.bk-grouped]=\"groupBy()\"\r\n >\r\n\r\n\r\n @if (searchable()) {\r\n <div class=\"bk-dropdown-search mb-1\">\r\n <div class=\"bk-search-wrapper\">\r\n <svg class=\"text-[#BBBDC5] mr-2\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\">\r\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\r\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>\r\n </svg>\r\n <input #searchInput type=\"text\" class=\"bk-search-input\" [value]=\"searchTerm()\" [placeholder]=\"'Search...'\"\r\n (input)=\"onSearchInput($event)\" (keydown)=\"onKeyDown($event)\" (click)=\"$event.stopPropagation()\">\r\n </div>\r\n </div>\r\n }\r\n <div #optionsListContainer class=\"bk-options-list\">\r\n @if (loading()) {\r\n <div class=\"bk-option-disabled\">{{ loadingText() }}</div>\r\n } @else {\r\n @if (allSelect()){\r\n\r\n @if (multiple() && filteredItems().length > 0) {\r\n <div class=\"bk-option\" (mousedown)=\"toggleSelectAll($event)\" [class.bk-selected]=\"isAllSelected()\">\r\n <div class=\"flex-1 flex justify-between\">\r\n <span>Select All</span>\r\n @if (isAllSelected()) {\r\n <svg class=\"text-[#141414]\" width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2.5\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n }\r\n </div>\r\n </div>\r\n }\r\n }\r\n @for (group of groupedItems(); track $index) {\r\n\r\n @if (group.group) {\r\n <div class=\"bk-option-group\">\r\n {{ group.group }}\r\n </div>\r\n }\r\n\r\n @for (item of group.items; track $index) {\r\n <div #optionsRef class=\"bk-option\" [class.bk-selected]=\"isItemSelected(item)\" [class.bk-marked]=\"$index === markedIndex()\" (click)=\"handleSelection(item, $event)\">\r\n <div class=\"flex-1 flex justify-between\">\r\n <span [style.color]=\"resolveColor(item)\">{{ resolveLabel(item) }}</span>\r\n\r\n @if (isItemSelected(item)) {\r\n <svg class=\"text-[#141414]\" width=\"17\" height=\"17\" viewBox=\"0 0 24 24\"\r\n fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n }\r\n\r\n @if (filteredItems().length === 0) {\r\n <div class=\"bk-option-disabled\">{{ notFoundText() }}</div>\r\n }\r\n }\r\n </div>\r\n\r\n </div>\r\n }\r\n @if(hasError){\r\n @if (errorMessage) {\r\n <p class=\"bk-select-error\">{{ errorMessage }}</p>\r\n }\r\n }\r\n\r\n\r\n</div>\r\n", styles: [".bk-select-container{@apply relative w-full box-border flex flex-col gap-1.5;}.bk-select-control{@apply flex items-center justify-between gap-2 w-full bg-white border border-[#E3E3E7] rounded transition-all duration-200 px-3 py-2.5 cursor-pointer;}.bk-select-control.bk-focused{@apply border-[#6B7080] shadow-none z-10;}.bk-select-control.bk-disabled{@apply bg-[#F4F4F6] cursor-not-allowed opacity-60;}.bk-select-control.bk-has-error{@apply border-[#d11e14];}.bk-value-container{@apply flex flex-1 items-center flex-wrap gap-1 relative overflow-hidden h-full;}.bk-placeholder{@apply text-[#6B7080] font-normal text-sm truncate w-full pointer-events-none;}.bk-value-label-single{@apply font-normal text-sm leading-[18px] text-[#141414] truncate w-full;}.bk-multi-badge-item{@apply inline-flex items-center gap-1.5 px-1.5 py-0.5 bg-white border border-[#E3E3E7] rounded-[4px];}.bk-multi-badge-item-text{@apply text-[10px] leading-[14px] font-normal text-[#6B7080];}.bk-multi-badge-close{@apply cursor-pointer outline-none w-3 h-3;}.bk-actions{@apply flex items-center gap-0.5 flex-shrink-0;}.bk-clear-wrapper{@apply text-gray-400 hover:text-red-500 cursor-pointer;}.bk-arrow-wrapper{@apply text-gray-400 transition-transform duration-200;}.bk-arrow-wrapper.bk-open{@apply rotate-180;}.bk-dropdown-panel{@apply absolute left-0 w-full bg-white border border-[#E3E3E7] rounded-xl shadow-lg z-[99] overflow-hidden cursor-default p-2.5;}.bk-dropdown-search{@apply px-2 pt-2;}.bk-search-wrapper{@apply flex items-center border border-[#E3E3E7] rounded-md px-3 py-[7px] bg-white transition-colors focus-within:border-[#E3E3E7];}.bk-search-input{@apply w-full outline-none font-normal text-sm text-[#141414] placeholder-[#A1A3AE] bg-transparent;}.bk-options-list{@apply max-h-60 overflow-auto relative flex flex-col gap-0.5;}.bk-option{@apply flex items-center p-2.5 cursor-pointer transition-colors font-normal text-sm text-[#141414];}.bk-option:hover,.bk-option.bk-marked,.bk-option.bk-selected{@apply bg-[#F8F8F8] rounded-md;}.bk-grouped .bk-option{@apply ps-5;}.bk-option-disabled{@apply px-3 py-2 text-gray-400 cursor-default;}.bk-select-all-option{@apply sticky top-0 z-20 flex items-center px-3 py-2 cursor-pointer border-b border-[#E3E6EE] bg-gray-50 text-[#15191E];}.bk-select-all-option:hover{@apply bg-gray-100;}.bk-dropdown-panel[data-position=top]{margin-top:0;margin-bottom:4px}.bk-select-label{@apply text-sm font-medium text-[#141414] tracking-[-.28px] inline-block;}.bk-select-label-required{@apply text-[#E7000B];}.bk-options-list ::-webkit-scrollbar{width:10px}.bk-options-list ::-webkit-scrollbar-track{background:transparent;border-radius:8px;width:8px}.bk-options-list ::-webkit-scrollbar-thumb{background:#d6d7dc;border-radius:8px;transition:.3s ease-in-out}.bk-options-list ::-webkit-scrollbar-thumb:hover{background:#909090}.bk-option-group{@apply px-2.5 py-1 font-bold text-[13px] leading-5 text-[#141414];}.bk-option-group:not(:first-child){@apply mt-4;}.bk-select-error{@apply text-xs text-[#E7000B] font-normal;}.bk-select-hint{@apply text-xs text-[#868997] font-normal;}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: BKTooltipDirective, selector: "[bkTooltip]", inputs: ["bkTooltip", "bkTooltipPosition"] }] });
|
|
3662
3911
|
}
|
|
3663
3912
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkSelect, decorators: [{
|
|
3664
3913
|
type: Component,
|
|
3665
|
-
args: [{ selector: 'bk-select', standalone: true, imports: [CommonModule, FormsModule], providers: [
|
|
3914
|
+
args: [{ selector: 'bk-select', standalone: true, imports: [CommonModule, FormsModule, BKTooltipDirective], providers: [
|
|
3666
3915
|
{
|
|
3667
3916
|
provide: NG_VALUE_ACCESSOR,
|
|
3668
3917
|
useExisting: forwardRef(() => BkSelect),
|
|
3669
3918
|
multi: true
|
|
3670
3919
|
}
|
|
3671
|
-
], template: "<div class=\"bk-select-container\">\r\n\r\n @if(label){\r\n <label\r\n class=\"bk-select-label\"\r\n (click)=\"openFromLabel($event)\">\r\n {{ label }}\r\n @if (required) {\r\n <span class=\"bk-select-label-required\">*</span>\r\n }\r\n </label>\r\n }\r\n\r\n <div\r\n #controlWrapper\r\n class=\"bk-select-control\"\r\n [ngClass]=\"{ 'bk-has-error': hasError }\"\r\n\r\n tabindex=\"0\"\r\n (keydown)=\"onKeyDown($event)\"\r\n [class.bk-focused]=\"isOpen()\"\r\n [class.bk-disabled]=\"disabled()\"\r\n (mousedown)=\"toggleDropdown($event)\"\r\n >\r\n <!-- Icon (Always visible if set) -->\r\n @if (iconSrc) {\r\n <img [src]=\"iconSrc\" [alt]=\"iconAlt\" class=\"shrink-0\"/>\r\n }\r\n <div class=\"bk-value-container\">\r\n @if (selectedOptions().length === 0) {\r\n <div class=\"bk-placeholder\">{{ placeholder() }}</div>\r\n }\r\n @if (multiple() && selectedOptions().length > 0) {\r\n <div class=\"bk-value-chips\">\r\n @for (opt of selectedOptions().slice(0, maxLabels()); track $index) {\r\n <div class=\"bk-multi-badge-item\">\r\n <span class=\"bk-multi-badge-item-text\" [style.color]=\"resolveColor(opt)\">{{ resolveLabel(opt) }}</span>\r\n\r\n <button type=\"button\" (mousedown)=\"removeOption(opt, $event)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"none\">\r\n <path d=\"M6.625 0.625L0.625 6.625M0.625 0.625L6.625 6.625\" stroke=\"#BBBDC5\" stroke-width=\"1.25\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n }\r\n @if (selectedOptions().length > maxLabels()) {\r\n <div class=\"bk-multi-badge-item\"><span\r\n class=\"bk-multi-badge-item-text\">+{{ selectedOptions().length - maxLabels() }}</span></div>\r\n }\r\n </div>\r\n }\r\n @if (!multiple() && selectedOptions().length > 0) {\r\n <div class=\"bk-value-label-single\" [style.color]=\"resolveColor(selectedOptions()[0])\">\r\n {{ resolveLabel(selectedOptions()[0]) }}</div>\r\n }\r\n </div>\r\n <div class=\"bk-actions\">\r\n @if (clearable() && selectedOptions().length > 0 && !disabled()) {\r\n <span class=\"bk-clear-wrapper\" (mousedown)=\"handleClear($event)\" title=\"Clear\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"18\"\r\n y1=\"6\" x2=\"6\"\r\n y2=\"18\"></line><line\r\n x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line></svg>\r\n </span>\r\n }\r\n <span class=\"bk-arrow-wrapper\" [class.bk-open]=\"isOpen()\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path\r\n d=\"m6 9 6 6 6-6\"/></svg>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n @if (isOpen()) {\r\n <div\r\n #dropdownPanel\r\n class=\"bk-dropdown-panel\"\r\n [attr.data-position]=\"dropdownPosition()\"\r\n (scroll)=\"onScroll($event)\"\r\n\r\n [style.position]=\"appendToBody() ? 'fixed' : 'absolute'\"\r\n [style.top]=\"getTop()\"\r\n [style.bottom]=\"getBottom()\"\r\n [style.left]=\"appendToBody() ? dropdownStyle().left : null\"\r\n [style.width]=\"appendToBody() ? dropdownStyle().width : '100%'\"\r\n [class.bk-grouped]=\"groupBy()\"\r\n >\r\n\r\n\r\n @if (searchable()) {\r\n <div class=\"bk-dropdown-search\">\r\n <div class=\"bk-search-wrapper\">\r\n <svg class=\"text-[#BBBDC5] mr-2\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\">\r\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\r\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>\r\n </svg>\r\n <input #searchInput type=\"text\" class=\"bk-search-input\" [value]=\"searchTerm()\" [placeholder]=\"'Search...'\"\r\n (input)=\"onSearchInput($event)\" (keydown)=\"onKeyDown($event)\" (click)=\"$event.stopPropagation()\">\r\n </div>\r\n </div>\r\n }\r\n <div #optionsListContainer class=\"bk-options-list\">\r\n @if (loading()) {\r\n <div class=\"bk-option-disabled\">{{ loadingText() }}</div>\r\n } @else {\r\n @if (allSelect()){\r\n\r\n @if (multiple() && filteredItems().length > 0) {\r\n <div class=\"bk-option\" (mousedown)=\"toggleSelectAll($event)\" [class.bk-selected]=\"isAllSelected()\">\r\n <div class=\"flex-1 flex justify-between\">\r\n <span>Select All</span>\r\n @if (isAllSelected()) {\r\n <svg class=\"text-[#141414]\" width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2.5\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n }\r\n </div>\r\n </div>\r\n }\r\n }\r\n @for (group of groupedItems(); track $index) {\r\n\r\n @if (group.group) {\r\n <div class=\"bk-option-group\">\r\n {{ group.group }}\r\n </div>\r\n }\r\n\r\n @for (item of group.items; track $index) {\r\n <div #optionsRef class=\"bk-option\" [class.bk-selected]=\"isItemSelected(item)\" [class.bk-marked]=\"$index === markedIndex()\" (click)=\"handleSelection(item, $event)\">\r\n <div class=\"flex-1 flex justify-between\">\r\n <span [style.color]=\"resolveColor(item)\">{{ resolveLabel(item) }}</span>\r\n\r\n @if (isItemSelected(item)) {\r\n <svg class=\"text-[#141414]\" width=\"17\" height=\"17\" viewBox=\"0 0 24 24\"\r\n fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n }\r\n\r\n @if (filteredItems().length === 0) {\r\n <div class=\"bk-option-disabled\">{{ notFoundText() }}</div>\r\n }\r\n }\r\n </div>\r\n\r\n </div>\r\n }\r\n @if(hasError){\r\n @if (errorMessage) {\r\n <p class=\"bk-select-error\">{{ errorMessage }}</p>\r\n }\r\n }\r\n\r\n\r\n</div>\r\n", styles: [".bk-select-container{@apply relative w-full box-border flex flex-col gap-1.5;}.bk-select-control{@apply flex items-center justify-between gap-2 w-full bg-white border border-[#E3E3E7] rounded transition-all duration-200 px-3 py-2.5 cursor-pointer;}.bk-select-control.bk-focused{@apply border-[#6B7080] shadow-none z-10;}.bk-select-control.bk-disabled{@apply bg-[#F4F4F6] cursor-not-allowed opacity-60;}.bk-select-control.bk-has-error{@apply border-[#d11e14];}.bk-value-container{@apply flex flex-1 items-center flex-wrap gap-1 relative overflow-hidden h-full;}.bk-placeholder{@apply text-[#6B7080] font-normal text-sm truncate w-full pointer-events-none;}.bk-value-label-single{@apply font-normal text-sm leading-[18px] text-[#141414] truncate w-full;}.bk-multi-badge-item{@apply inline-flex items-center gap-1.5 px-1.5 py-0.5 bg-white border border-[#E3E3E7] rounded-[4px];}.bk-multi-badge-item-text{@apply text-[10px] leading-[14px] font-normal text-[#6B7080];}.bk-multi-badge-close{@apply cursor-pointer outline-none w-3 h-3;}.bk-actions{@apply flex items-center gap-0.5 flex-shrink-0;}.bk-clear-wrapper{@apply text-gray-400 hover:text-red-500 cursor-pointer;}.bk-arrow-wrapper{@apply text-gray-400 transition-transform duration-200;}.bk-arrow-wrapper.bk-open{@apply rotate-180;}.bk-dropdown-panel{@apply absolute left-0 w-full bg-white border border-[#E3E3E7] rounded-xl shadow-lg z-[99] overflow-hidden cursor-default p-2.5;}.bk-dropdown-search{@apply px-2 pt-2;}.bk-search-wrapper{@apply flex items-center border border-[#E3E3E7] rounded-md px-3 py-[7px] bg-white transition-colors focus-within:border-[#E3E3E7];}.bk-search-input{@apply w-full outline-none font-normal text-sm text-[#141414] placeholder-[#A1A3AE] bg-transparent;}.bk-options-list{@apply max-h-60 overflow-auto relative flex flex-col gap-0.5;}.bk-option{@apply flex items-center p-2.5 cursor-pointer transition-colors font-normal text-sm text-[#141414];}.bk-option:hover,.bk-option.bk-marked,.bk-option.bk-selected{@apply bg-[#F8F8F8] rounded-md;}.bk-grouped .bk-option{@apply ps-5;}.bk-option-disabled{@apply px-3 py-2 text-gray-400 cursor-default;}.bk-select-all-option{@apply sticky top-0 z-20 flex items-center px-3 py-2 cursor-pointer border-b border-[#E3E6EE] bg-gray-50 text-[#15191E];}.bk-select-all-option:hover{@apply bg-gray-100;}.bk-dropdown-panel[data-position=top]{margin-top:0;margin-bottom:4px}.bk-select-label{@apply text-sm font-medium text-[#141414] tracking-[-.28px] inline-block;}.bk-select-label-required{@apply text-[#E7000B];}.bk-options-list ::-webkit-scrollbar{width:10px}.bk-options-list ::-webkit-scrollbar-track{background:transparent;border-radius:8px;width:8px}.bk-options-list ::-webkit-scrollbar-thumb{background:#d6d7dc;border-radius:8px;transition:.3s ease-in-out}.bk-options-list ::-webkit-scrollbar-thumb:hover{background:#909090}.bk-option-group{@apply px-2.5 py-1 font-bold text-[13px] leading-5 text-[#141414];}.bk-option-group:not(:first-child){@apply mt-4;}.bk-select-error{@apply text-xs text-[#E7000B] font-normal;}.bk-select-hint{@apply text-xs text-[#868997] font-normal;}\n"] }]
|
|
3920
|
+
], template: "<div class=\"bk-select-container\">\r\n\r\n @if(label){\r\n <label\r\n class=\"bk-select-label\"\r\n (click)=\"openFromLabel($event)\">\r\n {{ label }}\r\n @if (required) {\r\n <span class=\"bk-select-label-required\">*</span>\r\n }\r\n </label>\r\n }\r\n\r\n <div\r\n #controlWrapper\r\n class=\"bk-select-control\"\r\n [ngClass]=\"{ 'bk-has-error': hasError }\"\r\n\r\n tabindex=\"0\"\r\n (keydown)=\"onKeyDown($event)\"\r\n [class.bk-focused]=\"isOpen()\"\r\n [class.bk-disabled]=\"disabled()\"\r\n (mousedown)=\"toggleDropdown($event)\"\r\n >\r\n <!-- Icon (Always visible if set) -->\r\n @if (iconSrc) {\r\n <img [src]=\"iconSrc\" [alt]=\"iconAlt\" class=\"shrink-0\"/>\r\n }\r\n <div class=\"bk-value-container\">\r\n @if (selectedOptions().length === 0) {\r\n <div class=\"bk-placeholder\">{{ placeholder() }}</div>\r\n }\r\n @if (multiple() && selectedOptions().length > 0) {\r\n <div class=\"bk-value-chips\">\r\n @for (opt of selectedOptions().slice(0, maxLabels()); track $index) {\r\n <div class=\"bk-multi-badge-item me-0.5\">\r\n <span class=\"bk-multi-badge-item-text\" [style.color]=\"resolveColor(opt)\">{{ resolveLabel(opt) }}</span>\r\n\r\n <button type=\"button\" (mousedown)=\"removeOption(opt, $event)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"none\">\r\n <path d=\"M6.625 0.625L0.625 6.625M0.625 0.625L6.625 6.625\" stroke=\"#BBBDC5\" stroke-width=\"1.25\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n }\r\n @if (selectedOptions().length > maxLabels()) {\r\n <div class=\"bk-multi-badge-item\"><span\r\n class=\"bk-multi-badge-item-text\" bkTooltipPosition=\"top\" [bkTooltip]=\"getRemainingItems()\">+{{ selectedOptions().length - maxLabels() }}</span></div>\r\n\r\n\r\n }\r\n </div>\r\n }\r\n @if (!multiple() && selectedOptions().length > 0) {\r\n <div class=\"bk-value-label-single\" [style.color]=\"resolveColor(selectedOptions()[0])\">\r\n {{ resolveLabel(selectedOptions()[0]) }}</div>\r\n }\r\n </div>\r\n <div class=\"bk-actions\">\r\n @if (clearable() && selectedOptions().length > 0 && !disabled()) {\r\n <span class=\"bk-clear-wrapper\" (mousedown)=\"handleClear($event)\" title=\"Clear\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"18\"\r\n y1=\"6\" x2=\"6\"\r\n y2=\"18\"></line><line\r\n x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line></svg>\r\n </span>\r\n }\r\n <span class=\"bk-arrow-wrapper\" [class.bk-open]=\"isOpen()\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path\r\n d=\"m6 9 6 6 6-6\"/></svg>\r\n </span>\r\n </div>\r\n </div>\r\n\r\n @if (isOpen()) {\r\n <div\r\n #dropdownPanel\r\n class=\"bk-dropdown-panel\"\r\n [attr.data-position]=\"dropdownPosition()\"\r\n (scroll)=\"onScroll($event)\"\r\n\r\n [style.position]=\"appendToBody() ? 'fixed' : 'absolute'\"\r\n [style.top]=\"getTop()\"\r\n [style.bottom]=\"getBottom()\"\r\n [style.left]=\"appendToBody() ? dropdownStyle().left : null\"\r\n [style.width]=\"appendToBody() ? dropdownStyle().width : '100%'\"\r\n [class.bk-grouped]=\"groupBy()\"\r\n >\r\n\r\n\r\n @if (searchable()) {\r\n <div class=\"bk-dropdown-search mb-1\">\r\n <div class=\"bk-search-wrapper\">\r\n <svg class=\"text-[#BBBDC5] mr-2\" xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\"\r\n viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\">\r\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\r\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>\r\n </svg>\r\n <input #searchInput type=\"text\" class=\"bk-search-input\" [value]=\"searchTerm()\" [placeholder]=\"'Search...'\"\r\n (input)=\"onSearchInput($event)\" (keydown)=\"onKeyDown($event)\" (click)=\"$event.stopPropagation()\">\r\n </div>\r\n </div>\r\n }\r\n <div #optionsListContainer class=\"bk-options-list\">\r\n @if (loading()) {\r\n <div class=\"bk-option-disabled\">{{ loadingText() }}</div>\r\n } @else {\r\n @if (allSelect()){\r\n\r\n @if (multiple() && filteredItems().length > 0) {\r\n <div class=\"bk-option\" (mousedown)=\"toggleSelectAll($event)\" [class.bk-selected]=\"isAllSelected()\">\r\n <div class=\"flex-1 flex justify-between\">\r\n <span>Select All</span>\r\n @if (isAllSelected()) {\r\n <svg class=\"text-[#141414]\" width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\"\r\n stroke=\"currentColor\" stroke-width=\"2.5\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n }\r\n </div>\r\n </div>\r\n }\r\n }\r\n @for (group of groupedItems(); track $index) {\r\n\r\n @if (group.group) {\r\n <div class=\"bk-option-group\">\r\n {{ group.group }}\r\n </div>\r\n }\r\n\r\n @for (item of group.items; track $index) {\r\n <div #optionsRef class=\"bk-option\" [class.bk-selected]=\"isItemSelected(item)\" [class.bk-marked]=\"$index === markedIndex()\" (click)=\"handleSelection(item, $event)\">\r\n <div class=\"flex-1 flex justify-between\">\r\n <span [style.color]=\"resolveColor(item)\">{{ resolveLabel(item) }}</span>\r\n\r\n @if (isItemSelected(item)) {\r\n <svg class=\"text-[#141414]\" width=\"17\" height=\"17\" viewBox=\"0 0 24 24\"\r\n fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\">\r\n <polyline points=\"20 6 9 17 4 12\"/>\r\n </svg>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n }\r\n\r\n @if (filteredItems().length === 0) {\r\n <div class=\"bk-option-disabled\">{{ notFoundText() }}</div>\r\n }\r\n }\r\n </div>\r\n\r\n </div>\r\n }\r\n @if(hasError){\r\n @if (errorMessage) {\r\n <p class=\"bk-select-error\">{{ errorMessage }}</p>\r\n }\r\n }\r\n\r\n\r\n</div>\r\n", styles: [".bk-select-container{@apply relative w-full box-border flex flex-col gap-1.5;}.bk-select-control{@apply flex items-center justify-between gap-2 w-full bg-white border border-[#E3E3E7] rounded transition-all duration-200 px-3 py-2.5 cursor-pointer;}.bk-select-control.bk-focused{@apply border-[#6B7080] shadow-none z-10;}.bk-select-control.bk-disabled{@apply bg-[#F4F4F6] cursor-not-allowed opacity-60;}.bk-select-control.bk-has-error{@apply border-[#d11e14];}.bk-value-container{@apply flex flex-1 items-center flex-wrap gap-1 relative overflow-hidden h-full;}.bk-placeholder{@apply text-[#6B7080] font-normal text-sm truncate w-full pointer-events-none;}.bk-value-label-single{@apply font-normal text-sm leading-[18px] text-[#141414] truncate w-full;}.bk-multi-badge-item{@apply inline-flex items-center gap-1.5 px-1.5 py-0.5 bg-white border border-[#E3E3E7] rounded-[4px];}.bk-multi-badge-item-text{@apply text-[10px] leading-[14px] font-normal text-[#6B7080];}.bk-multi-badge-close{@apply cursor-pointer outline-none w-3 h-3;}.bk-actions{@apply flex items-center gap-0.5 flex-shrink-0;}.bk-clear-wrapper{@apply text-gray-400 hover:text-red-500 cursor-pointer;}.bk-arrow-wrapper{@apply text-gray-400 transition-transform duration-200;}.bk-arrow-wrapper.bk-open{@apply rotate-180;}.bk-dropdown-panel{@apply absolute left-0 w-full bg-white border border-[#E3E3E7] rounded-xl shadow-lg z-[99] overflow-hidden cursor-default p-2.5;}.bk-dropdown-search{@apply px-2 pt-2;}.bk-search-wrapper{@apply flex items-center border border-[#E3E3E7] rounded-md px-3 py-[7px] bg-white transition-colors focus-within:border-[#E3E3E7];}.bk-search-input{@apply w-full outline-none font-normal text-sm text-[#141414] placeholder-[#A1A3AE] bg-transparent;}.bk-options-list{@apply max-h-60 overflow-auto relative flex flex-col gap-0.5;}.bk-option{@apply flex items-center p-2.5 cursor-pointer transition-colors font-normal text-sm text-[#141414];}.bk-option:hover,.bk-option.bk-marked,.bk-option.bk-selected{@apply bg-[#F8F8F8] rounded-md;}.bk-grouped .bk-option{@apply ps-5;}.bk-option-disabled{@apply px-3 py-2 text-gray-400 cursor-default;}.bk-select-all-option{@apply sticky top-0 z-20 flex items-center px-3 py-2 cursor-pointer border-b border-[#E3E6EE] bg-gray-50 text-[#15191E];}.bk-select-all-option:hover{@apply bg-gray-100;}.bk-dropdown-panel[data-position=top]{margin-top:0;margin-bottom:4px}.bk-select-label{@apply text-sm font-medium text-[#141414] tracking-[-.28px] inline-block;}.bk-select-label-required{@apply text-[#E7000B];}.bk-options-list ::-webkit-scrollbar{width:10px}.bk-options-list ::-webkit-scrollbar-track{background:transparent;border-radius:8px;width:8px}.bk-options-list ::-webkit-scrollbar-thumb{background:#d6d7dc;border-radius:8px;transition:.3s ease-in-out}.bk-options-list ::-webkit-scrollbar-thumb:hover{background:#909090}.bk-option-group{@apply px-2.5 py-1 font-bold text-[13px] leading-5 text-[#141414];}.bk-option-group:not(:first-child){@apply mt-4;}.bk-select-error{@apply text-xs text-[#E7000B] font-normal;}.bk-select-hint{@apply text-xs text-[#868997] font-normal;}\n"] }]
|
|
3672
3921
|
}], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], bindLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "bindLabel", required: false }] }], bindValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "bindValue", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], notFoundText: [{ type: i0.Input, args: [{ isSignal: true, alias: "notFoundText", required: false }] }], loadingText: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingText", required: false }] }], clearAllText: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearAllText", required: false }] }], groupBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "groupBy", required: false }] }], colorKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorKey", required: false }] }], iconAlt: [{
|
|
3673
3922
|
type: Input
|
|
3674
3923
|
}], label: [{
|
|
@@ -5529,11 +5778,11 @@ class BkValidator {
|
|
|
5529
5778
|
ngOnInit() {
|
|
5530
5779
|
}
|
|
5531
5780
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkValidator, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5532
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkValidator, isStandalone: true, selector: "bk-validator", inputs: { control: "control", label: "label", errorMessage: "errorMessage", showError: "showError" }, ngImport: i0, template: "<span class=\"text-left font-medium text-xs leading-normal text-[#C10007] mt-0.5 h-[1px] block\">\r\n @if (control && control.invalid && (control.dirty || control.touched)) {\r\n @if (control.errors?.['required']) {\r\n <span>\r\n {{ label }} is required.\r\n </span>\r\n }\r\n @else if (control.errors?.['minlength']) {\r\n <span>\r\n {{ label }} must be at least\r\n {{ control.errors?.['minlength']?.requiredLength }} characters long.\r\n </span>\r\n }\r\n @else if (control.errors?.['maxlength']) {\r\n <span>\r\n {{ label }} cannot exceed\r\n {{ control.errors?.['maxlength']?.requiredLength }} characters.\r\n </span>\r\n }\r\n @else if (control.errors?.['pattern']) {\r\n <span>\r\n {{ label }} contains invalid characters.\r\n </span>\r\n } @else if (control.errors?.['min']) {\r\n <span>\r\n {{ label }} must be at least {{ control.errors?.['min'].min }}.\r\n </span>\r\n } @else if (control.errors?.['max']) {\r\n <span>\r\n {{ label }} cannot be greater than {{ control.errors?.['max'].max }}.\r\n </span>\r\n }\r\n\r\n }
|
|
5781
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkValidator, isStandalone: true, selector: "bk-validator", inputs: { control: "control", label: "label", errorMessage: "errorMessage", showError: "showError" }, ngImport: i0, template: "<span class=\"text-left font-medium text-xs leading-normal text-[#C10007] mt-0.5 h-[1px] block\">\r\n @if (showError) {\r\n <span>\r\n {{ errorMessage }}\r\n </span>\r\n }\r\n @else if (control && control.invalid && (control.dirty || control.touched)) {\r\n @if (control.errors?.['required']) {\r\n <span>\r\n {{ label }} is required.\r\n </span>\r\n }\r\n @else if (control.errors?.['minlength']) {\r\n <span>\r\n {{ label }} must be at least\r\n {{ control.errors?.['minlength']?.requiredLength }} characters long.\r\n </span>\r\n }\r\n @else if (control.errors?.['maxlength']) {\r\n <span>\r\n {{ label }} cannot exceed\r\n {{ control.errors?.['maxlength']?.requiredLength }} characters.\r\n </span>\r\n }\r\n @else if (control.errors?.['pattern']) {\r\n <span>\r\n {{ label }} contains invalid characters.\r\n </span>\r\n } @else if (control.errors?.['min']) {\r\n <span>\r\n {{ label }} must be at least {{ control.errors?.['min'].min }}.\r\n </span>\r\n } @else if (control.errors?.['max']) {\r\n <span>\r\n {{ label }} cannot be greater than {{ control.errors?.['max'].max }}.\r\n </span>\r\n }\r\n\r\n }\r\n</span>\r\n" });
|
|
5533
5782
|
}
|
|
5534
5783
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkValidator, decorators: [{
|
|
5535
5784
|
type: Component,
|
|
5536
|
-
args: [{ selector: 'bk-validator', standalone: true, imports: [], template: "<span class=\"text-left font-medium text-xs leading-normal text-[#C10007] mt-0.5 h-[1px] block\">\r\n @if (control && control.invalid && (control.dirty || control.touched)) {\r\n @if (control.errors?.['required']) {\r\n <span>\r\n {{ label }} is required.\r\n </span>\r\n }\r\n @else if (control.errors?.['minlength']) {\r\n <span>\r\n {{ label }} must be at least\r\n {{ control.errors?.['minlength']?.requiredLength }} characters long.\r\n </span>\r\n }\r\n @else if (control.errors?.['maxlength']) {\r\n <span>\r\n {{ label }} cannot exceed\r\n {{ control.errors?.['maxlength']?.requiredLength }} characters.\r\n </span>\r\n }\r\n @else if (control.errors?.['pattern']) {\r\n <span>\r\n {{ label }} contains invalid characters.\r\n </span>\r\n } @else if (control.errors?.['min']) {\r\n <span>\r\n {{ label }} must be at least {{ control.errors?.['min'].min }}.\r\n </span>\r\n } @else if (control.errors?.['max']) {\r\n <span>\r\n {{ label }} cannot be greater than {{ control.errors?.['max'].max }}.\r\n </span>\r\n }\r\n\r\n }
|
|
5785
|
+
args: [{ selector: 'bk-validator', standalone: true, imports: [], template: "<span class=\"text-left font-medium text-xs leading-normal text-[#C10007] mt-0.5 h-[1px] block\">\r\n @if (showError) {\r\n <span>\r\n {{ errorMessage }}\r\n </span>\r\n }\r\n @else if (control && control.invalid && (control.dirty || control.touched)) {\r\n @if (control.errors?.['required']) {\r\n <span>\r\n {{ label }} is required.\r\n </span>\r\n }\r\n @else if (control.errors?.['minlength']) {\r\n <span>\r\n {{ label }} must be at least\r\n {{ control.errors?.['minlength']?.requiredLength }} characters long.\r\n </span>\r\n }\r\n @else if (control.errors?.['maxlength']) {\r\n <span>\r\n {{ label }} cannot exceed\r\n {{ control.errors?.['maxlength']?.requiredLength }} characters.\r\n </span>\r\n }\r\n @else if (control.errors?.['pattern']) {\r\n <span>\r\n {{ label }} contains invalid characters.\r\n </span>\r\n } @else if (control.errors?.['min']) {\r\n <span>\r\n {{ label }} must be at least {{ control.errors?.['min'].min }}.\r\n </span>\r\n } @else if (control.errors?.['max']) {\r\n <span>\r\n {{ label }} cannot be greater than {{ control.errors?.['max'].max }}.\r\n </span>\r\n }\r\n\r\n }\r\n</span>\r\n" }]
|
|
5537
5786
|
}], ctorParameters: () => [], propDecorators: { control: [{
|
|
5538
5787
|
type: Input
|
|
5539
5788
|
}], label: [{
|
|
@@ -5544,7 +5793,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
5544
5793
|
type: Input
|
|
5545
5794
|
}] } });
|
|
5546
5795
|
|
|
5547
|
-
class
|
|
5796
|
+
class BkAvatarProfile {
|
|
5548
5797
|
// ---------- Display inputs ----------
|
|
5549
5798
|
src = null;
|
|
5550
5799
|
alt = 'Avatar';
|
|
@@ -5610,6 +5859,13 @@ class AvatarProfile {
|
|
|
5610
5859
|
this.disabled = isDisabled;
|
|
5611
5860
|
this.editable = !isDisabled;
|
|
5612
5861
|
}
|
|
5862
|
+
// ---------- Validator Implementation ----------
|
|
5863
|
+
validate(control) {
|
|
5864
|
+
if (this.required && !control.value) {
|
|
5865
|
+
return { required: true };
|
|
5866
|
+
}
|
|
5867
|
+
return null;
|
|
5868
|
+
}
|
|
5613
5869
|
// ---------- Lifecycle ----------
|
|
5614
5870
|
ngOnChanges(changes) {
|
|
5615
5871
|
if (this.name) {
|
|
@@ -5743,21 +5999,31 @@ class AvatarProfile {
|
|
|
5743
5999
|
}
|
|
5744
6000
|
return (parts[0][0] + parts.at(-1)[0]).toUpperCase();
|
|
5745
6001
|
}
|
|
5746
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type:
|
|
5747
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type:
|
|
6002
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkAvatarProfile, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
6003
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkAvatarProfile, isStandalone: true, selector: "bk-avatar-profile", inputs: { src: "src", alt: "alt", name: "name", size: "size", fallback: "fallback", editable: "editable", accept: "accept", maxFileSizeKB: "maxFileSizeKB", uploadLabel: "uploadLabel", hint: "hint", loading: "loading", removable: "removable", label: "label", required: "required", hasError: "hasError", errorMessage: "errorMessage", disabled: "disabled" }, outputs: { fileSelected: "fileSelected", removed: "removed", fileError: "fileError" }, providers: [
|
|
5748
6004
|
{
|
|
5749
6005
|
provide: NG_VALUE_ACCESSOR,
|
|
5750
|
-
useExisting: forwardRef(() =>
|
|
6006
|
+
useExisting: forwardRef(() => BkAvatarProfile),
|
|
6007
|
+
multi: true
|
|
6008
|
+
},
|
|
6009
|
+
{
|
|
6010
|
+
provide: NG_VALIDATORS,
|
|
6011
|
+
useExisting: forwardRef(() => BkAvatarProfile),
|
|
5751
6012
|
multi: true
|
|
5752
6013
|
}
|
|
5753
6014
|
], usesOnChanges: true, ngImport: i0, template: "<div class=\"avatar-profile-container\" [ngClass]=\"sizeClasses\">\r\n @if (label) {\r\n <label class=\"avatar-profile-label\">\r\n {{ label }}\r\n @if (required) {\r\n <span class=\"avatar-profile-label-required\">*</span>\r\n }\r\n </label>\r\n }\r\n\r\n <div class=\"flex gap-4 justify-end\">\r\n <div\r\n [ngClass]=\"containerClasses\"\r\n [bkTooltip]=\"name\"\r\n [bkTooltipPosition]=\"'top'\"\r\n >\r\n\r\n <!-- Loading overlay -->\r\n @if (loading) {\r\n <div class=\"absolute inset-0 flex items-center justify-center z-10 rounded-full bg-white/60\">\r\n <div class=\"w-5 h-5 border-2 border-[#141414] border-t-transparent rounded-full animate-spin\"></div>\r\n </div>\r\n }\r\n\r\n @if (corrupted) {\r\n <!-- Corrupted file indicator -->\r\n <svg width=\"64px\" height=\"64px\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M19.3517 7.61665L15.3929 4.05375C14.2651 3.03868 13.7012 2.53114 13.0092 2.26562L13 5.00011C13 7.35713 13 8.53564 13.7322 9.26787C14.4645 10.0001 15.643 10.0001 18 10.0001H21.5801C21.2175 9.29588 20.5684 8.71164 19.3517 7.61665Z\" fill=\"#DC3545\"/>\r\n <path d=\"M14 22H10C6.22876 22 4.34315 22 3.17157 20.8284C2.72548 20.3823 2.44924 19.8327 2.27818 19.1149C2.15904 18.6149 2.09948 18.3649 2.21429 18.0728C2.32911 17.7806 2.58217 17.6119 3.08829 17.2745L3.71429 16.8571C4.49285 16.3381 5.50715 16.3381 6.28571 16.8571C7.3238 17.5492 8.6762 17.5492 9.71429 16.8571C10.4929 16.3381 11.5071 16.3381 12.2857 16.8571C13.3238 17.5492 14.6762 17.5492 15.7143 16.8571C16.4929 16.3381 17.5071 16.3381 18.2857 16.8571C19.3238 17.5492 20.6762 17.5492 21.7143 16.8571C21.8241 16.7839 21.9705 16.8681 21.965 17C21.8873 18.8723 21.6366 20.0203 20.8284 20.8284C19.6569 22 17.7712 22 14 22Z\" fill=\"#DC3545\"/>\r\n <path d=\"M2 10C2 6.22876 2 4.34315 3.17157 3.17157C4.34315 2 6.23869 2 10.0298 2C10.6358 2 11.1214 2 11.53 2.01666C11.5166 2.09659 11.5095 2.17813 11.5092 2.26057L11.5 5.09497C11.4999 6.19207 11.4998 7.16164 11.6049 7.94316C11.7188 8.79028 11.9803 9.63726 12.6716 10.3285C13.3628 11.0198 14.2098 11.2813 15.0569 11.3952C15.8385 11.5003 16.808 11.5002 17.9051 11.5001L18 11.5001H21.9934V12.3273C21.9973 12.5399 21.8912 12.7392 21.7143 12.8571C20.6762 13.5492 19.3238 13.5492 18.2857 12.8571C17.5071 12.3381 16.4929 12.3381 15.7143 12.8571C14.6762 13.5492 13.3238 13.5492 12.2857 12.8571C11.5071 12.3381 10.4929 12.3381 9.71429 12.8571C8.6762 13.5492 7.3238 13.5492 6.28571 12.8571C5.50715 12.3381 4.49285 12.3381 3.71429 12.8571L3.5547 12.9635C2.87033 13.4198 2.52814 13.6479 2.26407 13.5066C2 13.3653 2 12.954 2 12.1315V10Z\" fill=\"#DC3545\"/>\r\n </svg>\r\n }\r\n\r\n @else if (displaySrc && !imageLoadFailed) {\r\n <img\r\n [src]=\"displaySrc\"\r\n [alt]=\"alt\"\r\n class=\"avatar-img\"\r\n (error)=\"onImageError()\"\r\n />\r\n }\r\n\r\n @else if (fallback === 'camera') {\r\n <svg class=\"placeholder-icon\" width=\"23\" height=\"24\" viewBox=\"0 0 23 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M18.3843 4.66667C17.6726 4.66667 17.0193 4.25833 16.6926 3.62833L15.8526 1.93667C15.316 0.875 13.916 0 12.726 0H10.0543C8.85264 0 7.45264 0.875 6.91598 1.93667L6.07598 3.62833C5.74931 4.25833 5.09598 4.66667 4.38431 4.66667C1.85264 4.66667 -0.154023 6.80167 0.00931005 9.32167L0.615977 18.9583C0.755977 21.3617 2.05098 23.3333 5.27098 23.3333H17.4976C20.7176 23.3333 22.001 21.3617 22.1526 18.9583L22.7593 9.32167C22.9226 6.80167 20.916 4.66667 18.3843 4.66667ZM9.63431 6.125H13.1343C13.6126 6.125 14.0093 6.52167 14.0093 7C14.0093 7.47833 13.6126 7.875 13.1343 7.875H9.63431C9.15598 7.875 8.75931 7.47833 8.75931 7C8.75931 6.52167 9.15598 6.125 9.63431 6.125ZM11.3843 18.8067C9.21431 18.8067 7.44098 17.045 7.44098 14.8633C7.44098 12.6817 9.20264 10.92 11.3843 10.92C13.566 10.92 15.3276 12.6817 15.3276 14.8633C15.3276 17.045 13.5543 18.8067 11.3843 18.8067Z\" fill=\"#6B7080\"/>\r\n </svg>\r\n }\r\n\r\n @else if (showInitials) {\r\n <span class=\"avatar-text\">\r\n {{ initials }}\r\n </span>\r\n }\r\n\r\n @else {\r\n <svg class=\"placeholder-icon\" viewBox=\"0 0 32 32\" fill=\"none\" aria-hidden=\"true\" xmlns=\"http://www.w3.org/2000/svg\" > <g clip-path=\"url(#clip0)\"> <path d=\"M16 16c3.682 0 6.667-2.985 6.667-6.667S19.682 2.667 16 2.667 9.333 5.651 9.333 9.333 12.318 16 16 16Z\" stroke=\"#363C51\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /> <path d=\"M27.453 29.333C27.453 24.173 22.32 20 16 20S4.547 24.173 4.547 29.333\" stroke=\"#363C51\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /> </g> <defs> <clipPath id=\"clip0\"> <rect width=\"32\" height=\"32\" fill=\"white\" /> </clipPath> </defs> </svg>\r\n }\r\n\r\n <!-- Remove badge -->\r\n @if (showRemoveButton) {\r\n <button\r\n type=\"button\"\r\n class=\"remove-badge\"\r\n (click)=\"onRemove()\"\r\n aria-label=\"Remove avatar\"\r\n >\r\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M1 1L9 9M9 1L1 9\" stroke=\"#6B7080\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\r\n </svg>\r\n </button>\r\n }\r\n\r\n </div>\r\n <div class=\"flex flex-col gap-2 justify-end items-start\">\r\n @if (editable) {\r\n <label class=\"upload-button cursor-pointer\">\r\n {{ uploadLabel }}\r\n <input\r\n type=\"file\"\r\n class=\"hidden\"\r\n [accept]=\"accept\"\r\n [disabled]=\"disabled\"\r\n (change)=\"onFileSelected($event)\"\r\n />\r\n </label>\r\n }\r\n @if (!hasError && hint) {\r\n <p class=\"profile-size\">{{ hint }}</p>\r\n }\r\n @if (hasError && errorMessage) {\r\n <p class=\"avatar-profile-error\">{{ errorMessage }}</p>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".avatar-profile-container{@apply flex flex-col gap-1.5;}.avatar-profile-label{@apply text-sm font-medium text-[#141414];}.avatar-profile-label-required{@apply text-[#E7000B] ml-0.5;}.avatar-profile-error{@apply text-xs text-[#E7000B] font-normal;}.avatar-profile{@apply relative inline-flex items-center justify-center rounded-full flex-shrink-0 select-none shadow-lg transition-all duration-200 border-[3px] border-white bg-[#F9FAFA];}.avatar-profile .avatar-img{@apply w-full h-full object-cover rounded-full;}.upload-button{@apply font-medium text-[#6B7080] border border-[#E3E3E7] rounded shadow-sm;}.sm .upload-button{@apply text-[12px] leading-[18px] px-2 py-3;}.md .upload-button{@apply text-[14px] leading-[20px] px-[10px] py-2.5;}.lg .upload-button{@apply text-[16px] leading-[24px] px-[18px] py-2.5;}.xl .upload-button{@apply text-[16px] leading-[24px] px-5 py-3;}.profile-size{@apply font-medium text-[#6B7080];}.sm .profile-size{@apply text-[10px] leading-[14px];}.md .profile-size{@apply text-[12px] leading-[18px];}.lg .profile-size{@apply text-[14px] leading-[20px];}.xl .profile-size{@apply text-[16px] leading-[24px];}.avatar-profile.sm .avatar-text{@apply font-medium text-[30px] leading-[38px];}.avatar-profile.md .avatar-text{@apply font-medium text-[36px] leading-[44px];}.avatar-profile.lg .avatar-text{@apply font-medium text-[45px] leading-[55px];}.avatar-profile.xl .avatar-text{@apply font-medium text-[60px] leading-[72px];}.avatar-profile{@apply font-medium text-[#6B7080];}.avatar-profile.sm{@apply size-[72px] text-sm;}.avatar-profile.md{@apply size-[96px] text-base;}.avatar-profile.lg{@apply size-[120px] text-[18px] leading-[26px];}.avatar-profile.xl{@apply size-[160px] text-xl;}.avatar-profile.sm .placeholder-icon{@apply size-[28px];}.avatar-profile.md .placeholder-icon{@apply size-[42px];}.avatar-profile.lg .placeholder-icon{@apply size-[52px];}.avatar-profile.xl .placeholder-icon{@apply size-[65px];}.avatar-profile.corrupted{@apply border-[3px] border-[#E7000B];}.avatar-profile .corrupted-icon{@apply text-[#E7000B];}.avatar-profile.sm .corrupted-icon{@apply size-[28px];}.avatar-profile.md .corrupted-icon{@apply size-[42px];}.avatar-profile.lg .corrupted-icon{@apply size-[52px];}.avatar-profile.xl .corrupted-icon{@apply size-[65px];}.remove-badge{@apply absolute top-0 right-0 w-5 h-5 bg-white rounded-full shadow-md flex items-center justify-center cursor-pointer hover:bg-gray-50 transition z-20 border-0 p-0;}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: BKTooltipDirective, selector: "[bkTooltip]", inputs: ["bkTooltip", "bkTooltipPosition"] }] });
|
|
5754
6015
|
}
|
|
5755
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type:
|
|
6016
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkAvatarProfile, decorators: [{
|
|
5756
6017
|
type: Component,
|
|
5757
6018
|
args: [{ selector: 'bk-avatar-profile', imports: [NgClass, CommonModule, BKTooltipDirective], providers: [
|
|
5758
6019
|
{
|
|
5759
6020
|
provide: NG_VALUE_ACCESSOR,
|
|
5760
|
-
useExisting: forwardRef(() =>
|
|
6021
|
+
useExisting: forwardRef(() => BkAvatarProfile),
|
|
6022
|
+
multi: true
|
|
6023
|
+
},
|
|
6024
|
+
{
|
|
6025
|
+
provide: NG_VALIDATORS,
|
|
6026
|
+
useExisting: forwardRef(() => BkAvatarProfile),
|
|
5761
6027
|
multi: true
|
|
5762
6028
|
}
|
|
5763
6029
|
], template: "<div class=\"avatar-profile-container\" [ngClass]=\"sizeClasses\">\r\n @if (label) {\r\n <label class=\"avatar-profile-label\">\r\n {{ label }}\r\n @if (required) {\r\n <span class=\"avatar-profile-label-required\">*</span>\r\n }\r\n </label>\r\n }\r\n\r\n <div class=\"flex gap-4 justify-end\">\r\n <div\r\n [ngClass]=\"containerClasses\"\r\n [bkTooltip]=\"name\"\r\n [bkTooltipPosition]=\"'top'\"\r\n >\r\n\r\n <!-- Loading overlay -->\r\n @if (loading) {\r\n <div class=\"absolute inset-0 flex items-center justify-center z-10 rounded-full bg-white/60\">\r\n <div class=\"w-5 h-5 border-2 border-[#141414] border-t-transparent rounded-full animate-spin\"></div>\r\n </div>\r\n }\r\n\r\n @if (corrupted) {\r\n <!-- Corrupted file indicator -->\r\n <svg width=\"64px\" height=\"64px\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M19.3517 7.61665L15.3929 4.05375C14.2651 3.03868 13.7012 2.53114 13.0092 2.26562L13 5.00011C13 7.35713 13 8.53564 13.7322 9.26787C14.4645 10.0001 15.643 10.0001 18 10.0001H21.5801C21.2175 9.29588 20.5684 8.71164 19.3517 7.61665Z\" fill=\"#DC3545\"/>\r\n <path d=\"M14 22H10C6.22876 22 4.34315 22 3.17157 20.8284C2.72548 20.3823 2.44924 19.8327 2.27818 19.1149C2.15904 18.6149 2.09948 18.3649 2.21429 18.0728C2.32911 17.7806 2.58217 17.6119 3.08829 17.2745L3.71429 16.8571C4.49285 16.3381 5.50715 16.3381 6.28571 16.8571C7.3238 17.5492 8.6762 17.5492 9.71429 16.8571C10.4929 16.3381 11.5071 16.3381 12.2857 16.8571C13.3238 17.5492 14.6762 17.5492 15.7143 16.8571C16.4929 16.3381 17.5071 16.3381 18.2857 16.8571C19.3238 17.5492 20.6762 17.5492 21.7143 16.8571C21.8241 16.7839 21.9705 16.8681 21.965 17C21.8873 18.8723 21.6366 20.0203 20.8284 20.8284C19.6569 22 17.7712 22 14 22Z\" fill=\"#DC3545\"/>\r\n <path d=\"M2 10C2 6.22876 2 4.34315 3.17157 3.17157C4.34315 2 6.23869 2 10.0298 2C10.6358 2 11.1214 2 11.53 2.01666C11.5166 2.09659 11.5095 2.17813 11.5092 2.26057L11.5 5.09497C11.4999 6.19207 11.4998 7.16164 11.6049 7.94316C11.7188 8.79028 11.9803 9.63726 12.6716 10.3285C13.3628 11.0198 14.2098 11.2813 15.0569 11.3952C15.8385 11.5003 16.808 11.5002 17.9051 11.5001L18 11.5001H21.9934V12.3273C21.9973 12.5399 21.8912 12.7392 21.7143 12.8571C20.6762 13.5492 19.3238 13.5492 18.2857 12.8571C17.5071 12.3381 16.4929 12.3381 15.7143 12.8571C14.6762 13.5492 13.3238 13.5492 12.2857 12.8571C11.5071 12.3381 10.4929 12.3381 9.71429 12.8571C8.6762 13.5492 7.3238 13.5492 6.28571 12.8571C5.50715 12.3381 4.49285 12.3381 3.71429 12.8571L3.5547 12.9635C2.87033 13.4198 2.52814 13.6479 2.26407 13.5066C2 13.3653 2 12.954 2 12.1315V10Z\" fill=\"#DC3545\"/>\r\n </svg>\r\n }\r\n\r\n @else if (displaySrc && !imageLoadFailed) {\r\n <img\r\n [src]=\"displaySrc\"\r\n [alt]=\"alt\"\r\n class=\"avatar-img\"\r\n (error)=\"onImageError()\"\r\n />\r\n }\r\n\r\n @else if (fallback === 'camera') {\r\n <svg class=\"placeholder-icon\" width=\"23\" height=\"24\" viewBox=\"0 0 23 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M18.3843 4.66667C17.6726 4.66667 17.0193 4.25833 16.6926 3.62833L15.8526 1.93667C15.316 0.875 13.916 0 12.726 0H10.0543C8.85264 0 7.45264 0.875 6.91598 1.93667L6.07598 3.62833C5.74931 4.25833 5.09598 4.66667 4.38431 4.66667C1.85264 4.66667 -0.154023 6.80167 0.00931005 9.32167L0.615977 18.9583C0.755977 21.3617 2.05098 23.3333 5.27098 23.3333H17.4976C20.7176 23.3333 22.001 21.3617 22.1526 18.9583L22.7593 9.32167C22.9226 6.80167 20.916 4.66667 18.3843 4.66667ZM9.63431 6.125H13.1343C13.6126 6.125 14.0093 6.52167 14.0093 7C14.0093 7.47833 13.6126 7.875 13.1343 7.875H9.63431C9.15598 7.875 8.75931 7.47833 8.75931 7C8.75931 6.52167 9.15598 6.125 9.63431 6.125ZM11.3843 18.8067C9.21431 18.8067 7.44098 17.045 7.44098 14.8633C7.44098 12.6817 9.20264 10.92 11.3843 10.92C13.566 10.92 15.3276 12.6817 15.3276 14.8633C15.3276 17.045 13.5543 18.8067 11.3843 18.8067Z\" fill=\"#6B7080\"/>\r\n </svg>\r\n }\r\n\r\n @else if (showInitials) {\r\n <span class=\"avatar-text\">\r\n {{ initials }}\r\n </span>\r\n }\r\n\r\n @else {\r\n <svg class=\"placeholder-icon\" viewBox=\"0 0 32 32\" fill=\"none\" aria-hidden=\"true\" xmlns=\"http://www.w3.org/2000/svg\" > <g clip-path=\"url(#clip0)\"> <path d=\"M16 16c3.682 0 6.667-2.985 6.667-6.667S19.682 2.667 16 2.667 9.333 5.651 9.333 9.333 12.318 16 16 16Z\" stroke=\"#363C51\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /> <path d=\"M27.453 29.333C27.453 24.173 22.32 20 16 20S4.547 24.173 4.547 29.333\" stroke=\"#363C51\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" /> </g> <defs> <clipPath id=\"clip0\"> <rect width=\"32\" height=\"32\" fill=\"white\" /> </clipPath> </defs> </svg>\r\n }\r\n\r\n <!-- Remove badge -->\r\n @if (showRemoveButton) {\r\n <button\r\n type=\"button\"\r\n class=\"remove-badge\"\r\n (click)=\"onRemove()\"\r\n aria-label=\"Remove avatar\"\r\n >\r\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M1 1L9 9M9 1L1 9\" stroke=\"#6B7080\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\r\n </svg>\r\n </button>\r\n }\r\n\r\n </div>\r\n <div class=\"flex flex-col gap-2 justify-end items-start\">\r\n @if (editable) {\r\n <label class=\"upload-button cursor-pointer\">\r\n {{ uploadLabel }}\r\n <input\r\n type=\"file\"\r\n class=\"hidden\"\r\n [accept]=\"accept\"\r\n [disabled]=\"disabled\"\r\n (change)=\"onFileSelected($event)\"\r\n />\r\n </label>\r\n }\r\n @if (!hasError && hint) {\r\n <p class=\"profile-size\">{{ hint }}</p>\r\n }\r\n @if (hasError && errorMessage) {\r\n <p class=\"avatar-profile-error\">{{ errorMessage }}</p>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".avatar-profile-container{@apply flex flex-col gap-1.5;}.avatar-profile-label{@apply text-sm font-medium text-[#141414];}.avatar-profile-label-required{@apply text-[#E7000B] ml-0.5;}.avatar-profile-error{@apply text-xs text-[#E7000B] font-normal;}.avatar-profile{@apply relative inline-flex items-center justify-center rounded-full flex-shrink-0 select-none shadow-lg transition-all duration-200 border-[3px] border-white bg-[#F9FAFA];}.avatar-profile .avatar-img{@apply w-full h-full object-cover rounded-full;}.upload-button{@apply font-medium text-[#6B7080] border border-[#E3E3E7] rounded shadow-sm;}.sm .upload-button{@apply text-[12px] leading-[18px] px-2 py-3;}.md .upload-button{@apply text-[14px] leading-[20px] px-[10px] py-2.5;}.lg .upload-button{@apply text-[16px] leading-[24px] px-[18px] py-2.5;}.xl .upload-button{@apply text-[16px] leading-[24px] px-5 py-3;}.profile-size{@apply font-medium text-[#6B7080];}.sm .profile-size{@apply text-[10px] leading-[14px];}.md .profile-size{@apply text-[12px] leading-[18px];}.lg .profile-size{@apply text-[14px] leading-[20px];}.xl .profile-size{@apply text-[16px] leading-[24px];}.avatar-profile.sm .avatar-text{@apply font-medium text-[30px] leading-[38px];}.avatar-profile.md .avatar-text{@apply font-medium text-[36px] leading-[44px];}.avatar-profile.lg .avatar-text{@apply font-medium text-[45px] leading-[55px];}.avatar-profile.xl .avatar-text{@apply font-medium text-[60px] leading-[72px];}.avatar-profile{@apply font-medium text-[#6B7080];}.avatar-profile.sm{@apply size-[72px] text-sm;}.avatar-profile.md{@apply size-[96px] text-base;}.avatar-profile.lg{@apply size-[120px] text-[18px] leading-[26px];}.avatar-profile.xl{@apply size-[160px] text-xl;}.avatar-profile.sm .placeholder-icon{@apply size-[28px];}.avatar-profile.md .placeholder-icon{@apply size-[42px];}.avatar-profile.lg .placeholder-icon{@apply size-[52px];}.avatar-profile.xl .placeholder-icon{@apply size-[65px];}.avatar-profile.corrupted{@apply border-[3px] border-[#E7000B];}.avatar-profile .corrupted-icon{@apply text-[#E7000B];}.avatar-profile.sm .corrupted-icon{@apply size-[28px];}.avatar-profile.md .corrupted-icon{@apply size-[42px];}.avatar-profile.lg .corrupted-icon{@apply size-[52px];}.avatar-profile.xl .corrupted-icon{@apply size-[65px];}.remove-badge{@apply absolute top-0 right-0 w-5 h-5 bg-white rounded-full shadow-md flex items-center justify-center cursor-pointer hover:bg-gray-50 transition z-20 border-0 p-0;}\n"] }]
|
|
@@ -6248,6 +6514,161 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
6248
6514
|
args: [{ selector: 'bk-toastr', standalone: true, imports: [CommonModule], encapsulation: ViewEncapsulation.None, template: "<!-- Toast Container \u2013 fixed overlay -->\r\n<div class=\"toast-container\" [attr.data-position]=\"position$ | async\">\r\n\r\n @for (toast of (toasts$ | async) ?? []; track toast.id) {\r\n <div\r\n class=\"toast-item\"\r\n [attr.data-severity]=\"toast.severity\"\r\n [class.toast-enter]=\"!toast.leaving\"\r\n [class.toast-leave]=\"toast.leaving\">\r\n\r\n <!-- \u2500\u2500 Icon \u2500\u2500 -->\r\n @if (toast.icon) {\r\n <svg class=\"toast-icon shrink-0\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\"\r\n fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <g [attr.clip-path]=\"'url(#clip_' + toast.id + ')'\">\r\n <path\r\n d=\"M10.0001 13.3334V10M10.0001 6.66671H10.0084M18.3334 10C18.3334 5.39767 14.6025 1.66671 10.0001 1.66671C5.39771 1.66671 1.66675 5.39767 1.66675 10C1.66675 14.6024 5.39771 18.3334 10.0001 18.3334C14.6025 18.3334 18.3334 14.6024 18.3334 10Z\"\r\n stroke-width=\"1.5\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </g>\r\n <defs>\r\n <clipPath [attr.id]=\"'clip_' + toast.id\">\r\n <rect width=\"20\" height=\"20\" fill=\"white\" />\r\n </clipPath>\r\n </defs>\r\n </svg>\r\n }\r\n\r\n <!-- \u2500\u2500 Content \u2500\u2500 -->\r\n <div class=\"flex-1 min-w-0\">\r\n <p class=\"toast-summary\">{{ toast.summary }}</p>\r\n @if (toast.detail) {\r\n <p class=\"toast-detail\">{{ toast.detail }}</p>\r\n }\r\n </div>\r\n\r\n <!-- \u2500\u2500 Action button \u2500\u2500 -->\r\n @if (toast.actionLabel) {\r\n <button type=\"button\" class=\"toast-action\" (click)=\"onAction($event, toast)\">\r\n {{ toast.actionLabel }}\r\n </button>\r\n }\r\n\r\n <!-- \u2500\u2500 Close button \u2500\u2500 -->\r\n <button type=\"button\" class=\"toast-close\" (click)=\"onClose($event, toast.id)\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\">\r\n <path\r\n d=\"M10.625 0.625L0.625 10.625M0.625 0.625L10.625 10.625\"\r\n stroke-width=\"1.25\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </button>\r\n\r\n </div>\r\n }\r\n\r\n</div>\r\n", styles: [".toast-container{@apply fixed flex flex-col gap-3 max-w-[100vw-2rem];z-index:2147483647!important;pointer-events:none}.toast-container[data-position=top-right]{@apply top-4 right-4;}.toast-container[data-position=top-left]{@apply top-4 left-4;}.toast-container[data-position=top-center]{@apply top-4 left-1/2 -translate-x-1/2;}.toast-container[data-position=bottom-right]{@apply bottom-4 right-4;}.toast-container[data-position=bottom-left]{@apply bottom-4 left-4;}.toast-container[data-position=bottom-center]{@apply bottom-4 left-1/2 -translate-x-1/2;}.toast-item{@apply flex items-center justify-start gap-3 py-2 px-4 rounded-lg border;box-shadow:0 4px 12px #00000014,0 1px 3px #0000000f;pointer-events:auto}.toast-item[data-severity=info]{@apply bg-[#E5F3FF] border-[#E5F3FF];}.toast-item[data-severity=info] .toast-icon path{stroke:#1434cb}.toast-item[data-severity=info] .toast-summary{@apply text-[#0D227F];}.toast-item[data-severity=info] .toast-action{@apply bg-[#1434CB] text-white border border-[#1434CB];}.toast-item[data-severity=info] .toast-close path{stroke:#2563eb}.toast-item[data-severity=default]{@apply bg-white border-gray-200;}.toast-item[data-severity=default] .toast-icon path{stroke:#6b7080}.toast-item[data-severity=default] .toast-summary{@apply text-[#363C51];}.toast-item[data-severity=default] .toast-action{@apply bg-[#A1A3AE] text-white;}.toast-item[data-severity=default] .toast-close path{stroke:#6b7080}.toast-item[data-severity=error]{@apply bg-[#FFF1F1] border-[#FFF1F1];}.toast-item[data-severity=error] .toast-icon path{stroke:#cb1432}.toast-item[data-severity=error] .toast-summary{@apply text-[#B41E32];}.toast-item[data-severity=error] .toast-action{@apply bg-[#CB1432] text-white;}.toast-item[data-severity=error] .toast-close path{stroke:#cb1432}.toast-item[data-severity=warn]{@apply bg-[#FFEED7] border-[#FFEED7];}.toast-item[data-severity=warn] .toast-icon path{stroke:#f97c00}.toast-item[data-severity=warn] .toast-summary{@apply text-[#A04C02];}.toast-item[data-severity=warn] .toast-action{@apply bg-[#CC6401] text-white;}.toast-item[data-severity=warn] .toast-close path{stroke:#f97c00}.toast-item[data-severity=success]{@apply bg-[#F1FCF3] border-[#F1FCF3];}.toast-item[data-severity=success] .toast-icon path{stroke:#22973f}.toast-item[data-severity=success] .toast-summary{@apply text-[#1E7735];}.toast-item[data-severity=success] .toast-action{@apply bg-[#22973F] text-white;}.toast-item[data-severity=success] .toast-action:hover{@apply bg-green-800;}.toast-item[data-severity=success] .toast-close path{stroke:#22973f}.toast-summary{@apply text-sm font-medium;}.toast-action{@apply shrink-0 py-1 px-2 text-xs font-medium leading-[18px] rounded-lg cursor-pointer border-none transition-colors;pointer-events:auto}.toast-close{@apply shrink-0 p-1 rounded cursor-pointer border-none bg-transparent transition-opacity;pointer-events:auto;position:relative;z-index:1}.toast-close:hover{@apply opacity-60;}.toast-close svg{display:block;pointer-events:none}.toast-close *{cursor:pointer}.toast-enter{animation:toastIn .3s ease-out forwards}.toast-leave{animation:toastOut .3s ease-in forwards}@keyframes toastIn{0%{opacity:0;transform:translateY(-10px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes toastOut{0%{opacity:1;transform:translateY(0) scale(1)}to{opacity:0;transform:translateY(-10px) scale(.96)}}\n"] }]
|
|
6249
6515
|
}] });
|
|
6250
6516
|
|
|
6517
|
+
class BkUiAvatar {
|
|
6518
|
+
cdr;
|
|
6519
|
+
constructor(cdr) {
|
|
6520
|
+
this.cdr = cdr;
|
|
6521
|
+
}
|
|
6522
|
+
// ---------- Display Inputs ----------
|
|
6523
|
+
src = null;
|
|
6524
|
+
alt = 'Avatar';
|
|
6525
|
+
name = '';
|
|
6526
|
+
size = 'md';
|
|
6527
|
+
variant = 'gray';
|
|
6528
|
+
fallback = 'auto';
|
|
6529
|
+
dot = 'none';
|
|
6530
|
+
dotPosition = 'bottom-right';
|
|
6531
|
+
// ---------- Outputs ----------
|
|
6532
|
+
/** Emits when the provided image URL fails to load */
|
|
6533
|
+
imageLoadError = new EventEmitter();
|
|
6534
|
+
// ---------- Internal State ----------
|
|
6535
|
+
initials = '';
|
|
6536
|
+
imageLoadFailed = false;
|
|
6537
|
+
// ---------- CVA Callbacks ----------
|
|
6538
|
+
onChange = (_value) => { };
|
|
6539
|
+
onTouched = () => { };
|
|
6540
|
+
/**
|
|
6541
|
+
* Called by the forms system when the model value changes (ngModel / formControl).
|
|
6542
|
+
* Sets the src directly and tells OnPush to re-check the template.
|
|
6543
|
+
*/
|
|
6544
|
+
writeValue(value) {
|
|
6545
|
+
this.src = value || null;
|
|
6546
|
+
this.imageLoadFailed = false;
|
|
6547
|
+
// OnPush won't detect this change on its own because writeValue
|
|
6548
|
+
// is called programmatically by the forms system — not through an
|
|
6549
|
+
// @Input binding. markForCheck tells Angular: "this component's
|
|
6550
|
+
// template might have changed, check it on the next CD cycle."
|
|
6551
|
+
this.cdr.markForCheck();
|
|
6552
|
+
}
|
|
6553
|
+
registerOnChange(fn) {
|
|
6554
|
+
this.onChange = fn;
|
|
6555
|
+
}
|
|
6556
|
+
registerOnTouched(fn) {
|
|
6557
|
+
this.onTouched = fn;
|
|
6558
|
+
}
|
|
6559
|
+
setDisabledState(_isDisabled) {
|
|
6560
|
+
// Display-only component — disabled doesn't change visual behaviour,
|
|
6561
|
+
// but we still honour the CVA contract.
|
|
6562
|
+
this.cdr.markForCheck();
|
|
6563
|
+
}
|
|
6564
|
+
// ---------- Lifecycle ----------
|
|
6565
|
+
ngOnChanges(changes) {
|
|
6566
|
+
if (changes['name']) {
|
|
6567
|
+
this.initials = this.getInitials(this.name);
|
|
6568
|
+
}
|
|
6569
|
+
// Reset error state whenever a new src arrives via @Input
|
|
6570
|
+
if (changes['src']) {
|
|
6571
|
+
this.imageLoadFailed = false;
|
|
6572
|
+
}
|
|
6573
|
+
}
|
|
6574
|
+
onImageError() {
|
|
6575
|
+
this.imageLoadFailed = true;
|
|
6576
|
+
this.imageLoadError.emit();
|
|
6577
|
+
}
|
|
6578
|
+
// ---------- Derived UI ----------
|
|
6579
|
+
get showImage() {
|
|
6580
|
+
return !!(this.src) && !this.imageLoadFailed;
|
|
6581
|
+
}
|
|
6582
|
+
get showInitials() {
|
|
6583
|
+
if (this.showImage)
|
|
6584
|
+
return false;
|
|
6585
|
+
if (!this.name)
|
|
6586
|
+
return false;
|
|
6587
|
+
if (this.fallback === 'icon')
|
|
6588
|
+
return false;
|
|
6589
|
+
return true; // 'auto' and 'initials' both show initials when name is present
|
|
6590
|
+
}
|
|
6591
|
+
get showIcon() {
|
|
6592
|
+
return !this.showImage && !this.showInitials;
|
|
6593
|
+
}
|
|
6594
|
+
get containerClasses() {
|
|
6595
|
+
return [
|
|
6596
|
+
'avatar',
|
|
6597
|
+
this.size,
|
|
6598
|
+
VARIANT_MAP[this.variant]
|
|
6599
|
+
].join(' ');
|
|
6600
|
+
}
|
|
6601
|
+
get dotClasses() {
|
|
6602
|
+
return [
|
|
6603
|
+
'avatar-dot',
|
|
6604
|
+
this.size,
|
|
6605
|
+
DOT_COLOR_MAP[this.dot],
|
|
6606
|
+
DOT_POSITION_MAP[this.dotPosition]
|
|
6607
|
+
].join(' ');
|
|
6608
|
+
}
|
|
6609
|
+
// ---------- Utils ----------
|
|
6610
|
+
getInitials(name) {
|
|
6611
|
+
if (!name?.trim())
|
|
6612
|
+
return '';
|
|
6613
|
+
const parts = name.trim().split(/\s+/);
|
|
6614
|
+
if (parts.length === 1) {
|
|
6615
|
+
return parts[0].slice(0, 2).toUpperCase();
|
|
6616
|
+
}
|
|
6617
|
+
return (parts[0][0] + parts.at(-1)[0]).toUpperCase();
|
|
6618
|
+
}
|
|
6619
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkUiAvatar, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
6620
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkUiAvatar, isStandalone: true, selector: "bk-ui-avatar", inputs: { src: "src", alt: "alt", name: "name", size: "size", variant: "variant", fallback: "fallback", dot: "dot", dotPosition: "dotPosition" }, outputs: { imageLoadError: "imageLoadError" }, providers: [
|
|
6621
|
+
{
|
|
6622
|
+
provide: NG_VALUE_ACCESSOR,
|
|
6623
|
+
useExisting: forwardRef(() => BkUiAvatar),
|
|
6624
|
+
multi: true
|
|
6625
|
+
}
|
|
6626
|
+
], usesOnChanges: true, ngImport: i0, template: "<div\n [ngClass]=\"containerClasses\"\n [bkTooltip]=\"name\"\n [bkTooltipPosition]=\"'top'\"\n>\n\n @if (showImage) {\n <img\n [src]=\"src\"\n [alt]=\"alt\"\n class=\"avatar-img\"\n (error)=\"onImageError()\"\n />\n }\n\n @else if (showInitials) {\n <span class=\"avatar-text\">\n {{ initials }}\n </span>\n }\n\n @else {\n <svg\n class=\"placeholder-icon\"\n viewBox=\"0 0 32 32\"\n fill=\"none\"\n aria-hidden=\"true\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M16 16c3.682 0 6.667-2.985 6.667-6.667S19.682 2.667 16 2.667 9.333 5.651 9.333 9.333 12.318 16 16 16Z\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M27.453 29.333C27.453 24.173 22.32 20 16 20S4.547 24.173 4.547 29.333\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n\n @if (dot !== 'none') {\n <span [ngClass]=\"dotClasses\"></span>\n }\n\n</div>\n", styles: [".avatar{@apply relative inline-flex items-center justify-center rounded-full flex-shrink-0 select-none transition-all duration-200;}.avatar-img{@apply w-full h-full object-cover rounded-full;}.avatar-text{@apply font-medium;}.xsm{@apply size-6 text-[10px] leading-[14px];}.sm{@apply size-8 text-sm;}.md{@apply size-10 text-base;}.lg{@apply size-12 text-[18px] leading-[26px];}.xl{@apply size-14 text-xl;}.xxl{@apply size-16 text-xl;}.xsm .placeholder-icon{@apply size-4;}.sm .placeholder-icon{@apply size-5;}.md .placeholder-icon{@apply size-6;}.lg .placeholder-icon{@apply size-7;}.xl .placeholder-icon,.xxl .placeholder-icon{@apply size-8;}.avatar-dot{@apply absolute rounded-full block box-content border-[1.5px] border-white;}.xsm .avatar-dot{@apply size-1;}.sm .avatar-dot{@apply size-1.5;}.md .avatar-dot{@apply size-2.5;}.lg .avatar-dot{@apply size-3;}.xl .avatar-dot{@apply size-[14px];}.xxl .avatar-dot{@apply size-4;}.active{@apply bg-[#22973F];}.inactive{@apply bg-gray-300;}.notification{@apply bg-[#2E90FA];}.none{@apply hidden;}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: BKTooltipDirective, selector: "[bkTooltip]", inputs: ["bkTooltip", "bkTooltipPosition"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
6627
|
+
}
|
|
6628
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkUiAvatar, decorators: [{
|
|
6629
|
+
type: Component,
|
|
6630
|
+
args: [{ selector: 'bk-ui-avatar', standalone: true, imports: [CommonModule, BKTooltipDirective], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
6631
|
+
{
|
|
6632
|
+
provide: NG_VALUE_ACCESSOR,
|
|
6633
|
+
useExisting: forwardRef(() => BkUiAvatar),
|
|
6634
|
+
multi: true
|
|
6635
|
+
}
|
|
6636
|
+
], template: "<div\n [ngClass]=\"containerClasses\"\n [bkTooltip]=\"name\"\n [bkTooltipPosition]=\"'top'\"\n>\n\n @if (showImage) {\n <img\n [src]=\"src\"\n [alt]=\"alt\"\n class=\"avatar-img\"\n (error)=\"onImageError()\"\n />\n }\n\n @else if (showInitials) {\n <span class=\"avatar-text\">\n {{ initials }}\n </span>\n }\n\n @else {\n <svg\n class=\"placeholder-icon\"\n viewBox=\"0 0 32 32\"\n fill=\"none\"\n aria-hidden=\"true\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M16 16c3.682 0 6.667-2.985 6.667-6.667S19.682 2.667 16 2.667 9.333 5.651 9.333 9.333 12.318 16 16 16Z\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n <path\n d=\"M27.453 29.333C27.453 24.173 22.32 20 16 20S4.547 24.173 4.547 29.333\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n }\n\n @if (dot !== 'none') {\n <span [ngClass]=\"dotClasses\"></span>\n }\n\n</div>\n", styles: [".avatar{@apply relative inline-flex items-center justify-center rounded-full flex-shrink-0 select-none transition-all duration-200;}.avatar-img{@apply w-full h-full object-cover rounded-full;}.avatar-text{@apply font-medium;}.xsm{@apply size-6 text-[10px] leading-[14px];}.sm{@apply size-8 text-sm;}.md{@apply size-10 text-base;}.lg{@apply size-12 text-[18px] leading-[26px];}.xl{@apply size-14 text-xl;}.xxl{@apply size-16 text-xl;}.xsm .placeholder-icon{@apply size-4;}.sm .placeholder-icon{@apply size-5;}.md .placeholder-icon{@apply size-6;}.lg .placeholder-icon{@apply size-7;}.xl .placeholder-icon,.xxl .placeholder-icon{@apply size-8;}.avatar-dot{@apply absolute rounded-full block box-content border-[1.5px] border-white;}.xsm .avatar-dot{@apply size-1;}.sm .avatar-dot{@apply size-1.5;}.md .avatar-dot{@apply size-2.5;}.lg .avatar-dot{@apply size-3;}.xl .avatar-dot{@apply size-[14px];}.xxl .avatar-dot{@apply size-4;}.active{@apply bg-[#22973F];}.inactive{@apply bg-gray-300;}.notification{@apply bg-[#2E90FA];}.none{@apply hidden;}\n"] }]
|
|
6637
|
+
}], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { src: [{
|
|
6638
|
+
type: Input
|
|
6639
|
+
}], alt: [{
|
|
6640
|
+
type: Input
|
|
6641
|
+
}], name: [{
|
|
6642
|
+
type: Input
|
|
6643
|
+
}], size: [{
|
|
6644
|
+
type: Input
|
|
6645
|
+
}], variant: [{
|
|
6646
|
+
type: Input
|
|
6647
|
+
}], fallback: [{
|
|
6648
|
+
type: Input
|
|
6649
|
+
}], dot: [{
|
|
6650
|
+
type: Input
|
|
6651
|
+
}], dotPosition: [{
|
|
6652
|
+
type: Input
|
|
6653
|
+
}], imageLoadError: [{
|
|
6654
|
+
type: Output
|
|
6655
|
+
}] } });
|
|
6656
|
+
// ---------- Constants ----------
|
|
6657
|
+
const VARIANT_MAP = {
|
|
6658
|
+
gray: 'bg-white border border-[#EFEFF1] text-[#363C51]',
|
|
6659
|
+
colored: 'bg-[#F63D68] border border-white text-white'
|
|
6660
|
+
};
|
|
6661
|
+
const DOT_COLOR_MAP = {
|
|
6662
|
+
active: 'active',
|
|
6663
|
+
inactive: 'inactive',
|
|
6664
|
+
notification: 'notification',
|
|
6665
|
+
none: 'hidden'
|
|
6666
|
+
};
|
|
6667
|
+
const DOT_POSITION_MAP = {
|
|
6668
|
+
'bottom-right': 'bottom-0 right-0',
|
|
6669
|
+
'top-left': 'top-0.5 -left-0.5'
|
|
6670
|
+
};
|
|
6671
|
+
|
|
6251
6672
|
/*
|
|
6252
6673
|
* Public API Surface of brickclay-lib
|
|
6253
6674
|
*/
|
|
@@ -6257,5 +6678,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
6257
6678
|
* Generated bundle index. Do not edit.
|
|
6258
6679
|
*/
|
|
6259
6680
|
|
|
6260
|
-
export {
|
|
6681
|
+
export { BKTooltipDirective, BK_DEFAULT_DIALOG_CONFIG, BK_DIALOG_DATA, BK_DIALOG_GLOBAL_CONFIG, BkAvatarProfile, BkBadge, BkButton, BkButtonGroup, BkCheckbox, BkCustomCalendar, BkDialogActions, BkDialogClose, BkDialogContent, BkDialogModule, BkDialogRef, BkDialogService, BkDialogTitle, BkGrid, BkHierarchicalSelect, BkIconButton, BkInput, BkInputChips, BkPill, BkRadioButton, BkScheduledDatePicker, BkSelect, BkSpinner, BkTabs, BkTextarea, BkTimePicker, BkToastr, BkToastrService, BkToggle, BkUiAvatar, BkValidator, BrickclayIcons, BrickclayLib, CalendarManagerService, CalendarModule, CalendarSelection, getDialogBackdropAnimation, getDialogPanelAnimation };
|
|
6261
6682
|
//# sourceMappingURL=brickclay-org-ui.mjs.map
|