nexheal-lib 0.0.55 → 0.0.57
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/nexheal-lib.mjs +312 -28
- package/fesm2022/nexheal-lib.mjs.map +1 -1
- package/index.d.ts +66 -7
- package/package.json +1 -1
package/fesm2022/nexheal-lib.mjs
CHANGED
|
@@ -452,6 +452,8 @@ class CalendarControl {
|
|
|
452
452
|
dateSelected = new EventEmitter();
|
|
453
453
|
/** Emitted in `selectionMode="week"` with the selected week's start/end (or null when cleared). */
|
|
454
454
|
weekSelected = new EventEmitter();
|
|
455
|
+
/** Emitted in `selectionMode="range"` with the selected start/end (or null when cleared). */
|
|
456
|
+
rangeSelected = new EventEmitter();
|
|
455
457
|
_defaultDate;
|
|
456
458
|
get defaultDate() {
|
|
457
459
|
return this._defaultDate;
|
|
@@ -503,6 +505,11 @@ class CalendarControl {
|
|
|
503
505
|
selectedWeekEnd = null;
|
|
504
506
|
hoverWeekStart = null;
|
|
505
507
|
hoverWeekEnd = null;
|
|
508
|
+
rangeStart = null;
|
|
509
|
+
rangeEnd = null;
|
|
510
|
+
hoverDate = null;
|
|
511
|
+
committedRangeStart = null;
|
|
512
|
+
committedRangeEnd = null;
|
|
506
513
|
today = new Date();
|
|
507
514
|
todayYear = this.today.getFullYear();
|
|
508
515
|
todayMonth = this.today.getMonth();
|
|
@@ -543,6 +550,7 @@ class CalendarControl {
|
|
|
543
550
|
this.selectedDate = null;
|
|
544
551
|
this.selectedWeekStart = null;
|
|
545
552
|
this.selectedWeekEnd = null;
|
|
553
|
+
this.applyDateRange(null, null, false);
|
|
546
554
|
this.inputControl.setValue("", { emitEvent: false });
|
|
547
555
|
return;
|
|
548
556
|
}
|
|
@@ -567,6 +575,20 @@ class CalendarControl {
|
|
|
567
575
|
this.inputControl.setValue(this.formatWeek(start, end), { emitEvent: false });
|
|
568
576
|
return;
|
|
569
577
|
}
|
|
578
|
+
if (this.selectionMode === "range") {
|
|
579
|
+
const parsedRange = this.parseIncomingRange(value);
|
|
580
|
+
if (!parsedRange) {
|
|
581
|
+
this.applyDateRange(null, null, false);
|
|
582
|
+
this.selectedDate = null;
|
|
583
|
+
this.inputControl.setValue("", { emitEvent: false });
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
586
|
+
this.applyDateRange(parsedRange.start, parsedRange.end, false);
|
|
587
|
+
this.selectedDate = parsedRange.start;
|
|
588
|
+
this.displayMonth = parsedRange.start.getMonth();
|
|
589
|
+
this.displayYear = parsedRange.start.getFullYear();
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
570
592
|
if (this.timeOnly) {
|
|
571
593
|
let hours, mins;
|
|
572
594
|
if (typeof value === "string") {
|
|
@@ -739,6 +761,10 @@ class CalendarControl {
|
|
|
739
761
|
this.blurEvent.emit();
|
|
740
762
|
return;
|
|
741
763
|
}
|
|
764
|
+
if (this.selectionMode === "range") {
|
|
765
|
+
this.onRangeBlur();
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
742
768
|
const raw = (this.inputControl.value || "");
|
|
743
769
|
let currentFormatted = "";
|
|
744
770
|
if (this.selectedDate) {
|
|
@@ -880,7 +906,10 @@ class CalendarControl {
|
|
|
880
906
|
this.toggleCalendar();
|
|
881
907
|
break;
|
|
882
908
|
case "Escape":
|
|
883
|
-
this.
|
|
909
|
+
if (this.selectionMode === "range")
|
|
910
|
+
this.closeCalendar();
|
|
911
|
+
else
|
|
912
|
+
this.isOpen = false;
|
|
884
913
|
break;
|
|
885
914
|
case " ":
|
|
886
915
|
case "Spacebar":
|
|
@@ -888,7 +917,10 @@ class CalendarControl {
|
|
|
888
917
|
this.toggleCalendar();
|
|
889
918
|
break;
|
|
890
919
|
case "Tab":
|
|
891
|
-
this.
|
|
920
|
+
if (this.selectionMode === "range")
|
|
921
|
+
this.closeCalendar();
|
|
922
|
+
else
|
|
923
|
+
this.isOpen = false;
|
|
892
924
|
break;
|
|
893
925
|
}
|
|
894
926
|
}
|
|
@@ -912,6 +944,10 @@ class CalendarControl {
|
|
|
912
944
|
this.isOpen = false;
|
|
913
945
|
return;
|
|
914
946
|
}
|
|
947
|
+
if (this.selectionMode === "range") {
|
|
948
|
+
this.selectRangeDay(cell);
|
|
949
|
+
return;
|
|
950
|
+
}
|
|
915
951
|
const picked = this.showTime
|
|
916
952
|
? new Date(base.getFullYear(), base.getMonth(), base.getDate(), this.selectedHour, this.selectedMinute)
|
|
917
953
|
: new Date(base.getFullYear(), base.getMonth(), base.getDate());
|
|
@@ -944,12 +980,7 @@ class CalendarControl {
|
|
|
944
980
|
day: date.getDate(),
|
|
945
981
|
otherMonth: date.getMonth() !== this.displayMonth,
|
|
946
982
|
disabled: this.isDateDisabled(date),
|
|
947
|
-
selected: this.
|
|
948
|
-
? this.isWithin(date, this.selectedWeekStart, this.selectedWeekEnd)
|
|
949
|
-
: !!this.selectedDate &&
|
|
950
|
-
this.selectedDate.getFullYear() === date.getFullYear() &&
|
|
951
|
-
this.selectedDate.getMonth() === date.getMonth() &&
|
|
952
|
-
this.selectedDate.getDate() === date.getDate(),
|
|
983
|
+
selected: this.isCellSelected(date),
|
|
953
984
|
today: this.todayYear === date.getFullYear() &&
|
|
954
985
|
this.todayMonth === date.getMonth() &&
|
|
955
986
|
this.todayDate === date.getDate(),
|
|
@@ -1037,18 +1068,223 @@ class CalendarControl {
|
|
|
1037
1068
|
return this.isWithin(date, this.hoverWeekStart, this.hoverWeekEnd);
|
|
1038
1069
|
}
|
|
1039
1070
|
onDayHover(cell) {
|
|
1040
|
-
if (this.selectionMode
|
|
1071
|
+
if (this.selectionMode === "week") {
|
|
1072
|
+
const { start, end } = this.getWeekRange(cell.date);
|
|
1073
|
+
this.hoverWeekStart = start;
|
|
1074
|
+
this.hoverWeekEnd = end;
|
|
1041
1075
|
return;
|
|
1042
|
-
|
|
1043
|
-
this.
|
|
1044
|
-
|
|
1076
|
+
}
|
|
1077
|
+
if (this.selectionMode === "range") {
|
|
1078
|
+
if (!this.rangeStart || this.rangeEnd)
|
|
1079
|
+
return;
|
|
1080
|
+
this.hoverDate = cell.date;
|
|
1081
|
+
}
|
|
1045
1082
|
}
|
|
1046
1083
|
onDayLeave() {
|
|
1047
1084
|
this.hoverWeekStart = null;
|
|
1048
1085
|
this.hoverWeekEnd = null;
|
|
1086
|
+
this.hoverDate = null;
|
|
1049
1087
|
}
|
|
1050
1088
|
/** Stable identity for day cells so they aren't re-created every change-detection. */
|
|
1051
1089
|
trackByDate = (_, cell) => cell.date.getTime();
|
|
1090
|
+
isCellSelected(date) {
|
|
1091
|
+
if (this.selectionMode === "week") {
|
|
1092
|
+
return this.isWithin(date, this.selectedWeekStart, this.selectedWeekEnd);
|
|
1093
|
+
}
|
|
1094
|
+
if (this.selectionMode === "range") {
|
|
1095
|
+
return this.isRangeStart(date) || this.isRangeEnd(date);
|
|
1096
|
+
}
|
|
1097
|
+
return (!!this.selectedDate &&
|
|
1098
|
+
this.selectedDate.getFullYear() === date.getFullYear() &&
|
|
1099
|
+
this.selectedDate.getMonth() === date.getMonth() &&
|
|
1100
|
+
this.selectedDate.getDate() === date.getDate());
|
|
1101
|
+
}
|
|
1102
|
+
isRangeStart(date) {
|
|
1103
|
+
if (this.selectionMode !== "range" || !this.rangeStart)
|
|
1104
|
+
return false;
|
|
1105
|
+
return this.isSameDay(date, this.rangeStart);
|
|
1106
|
+
}
|
|
1107
|
+
isRangeEnd(date) {
|
|
1108
|
+
if (this.selectionMode !== "range")
|
|
1109
|
+
return false;
|
|
1110
|
+
if (this.rangeEnd)
|
|
1111
|
+
return this.isSameDay(date, this.rangeEnd);
|
|
1112
|
+
return !!this.rangeStart && !!this.hoverDate && this.isSameDay(date, this.hoverDate);
|
|
1113
|
+
}
|
|
1114
|
+
isInSelectedRange(date) {
|
|
1115
|
+
if (this.selectionMode !== "range" || !this.rangeStart || !this.rangeEnd)
|
|
1116
|
+
return false;
|
|
1117
|
+
return this.isWithinDayRange(date, this.rangeStart, this.rangeEnd);
|
|
1118
|
+
}
|
|
1119
|
+
isInHoverRange(date) {
|
|
1120
|
+
if (this.selectionMode !== "range" || !this.rangeStart || this.rangeEnd || !this.hoverDate)
|
|
1121
|
+
return false;
|
|
1122
|
+
const ordered = this.orderDateRange(this.rangeStart, this.hoverDate);
|
|
1123
|
+
return this.isWithinDayRange(date, ordered.start, ordered.end);
|
|
1124
|
+
}
|
|
1125
|
+
selectRangeDay(cell) {
|
|
1126
|
+
const picked = this.startOfDay(cell.date);
|
|
1127
|
+
if (!this.rangeStart || this.rangeEnd) {
|
|
1128
|
+
this.rangeStart = picked;
|
|
1129
|
+
this.rangeEnd = null;
|
|
1130
|
+
this.hoverDate = null;
|
|
1131
|
+
this.selectedDate = picked;
|
|
1132
|
+
this.displayMonth = picked.getMonth();
|
|
1133
|
+
this.displayYear = picked.getFullYear();
|
|
1134
|
+
this.inputControl.setValue(this.formatInProgressRange(picked), { emitEvent: false });
|
|
1135
|
+
return;
|
|
1136
|
+
}
|
|
1137
|
+
const ordered = this.orderDateRange(this.rangeStart, picked);
|
|
1138
|
+
this.applyDateRange(ordered.start, ordered.end, true);
|
|
1139
|
+
this.selectedDate = ordered.start;
|
|
1140
|
+
this.displayMonth = ordered.start.getMonth();
|
|
1141
|
+
this.displayYear = ordered.start.getFullYear();
|
|
1142
|
+
this.onTouchedFn();
|
|
1143
|
+
this.rangeSelected.emit({ start: ordered.start, end: ordered.end });
|
|
1144
|
+
this.dateSelected.emit(ordered.start);
|
|
1145
|
+
this.closeCalendar();
|
|
1146
|
+
}
|
|
1147
|
+
onRangeBlur() {
|
|
1148
|
+
const raw = (this.inputControl.value || "").trim();
|
|
1149
|
+
const current = this.formatCommittedRangeInput();
|
|
1150
|
+
if (raw === current) {
|
|
1151
|
+
this.blurEvent.emit();
|
|
1152
|
+
return;
|
|
1153
|
+
}
|
|
1154
|
+
if (!raw) {
|
|
1155
|
+
this.applyDateRange(null, null, true);
|
|
1156
|
+
this.selectedDate = null;
|
|
1157
|
+
this.rangeSelected.emit(null);
|
|
1158
|
+
this.dateSelected.emit(null);
|
|
1159
|
+
this.blurEvent.emit();
|
|
1160
|
+
return;
|
|
1161
|
+
}
|
|
1162
|
+
const parsed = this.parseIncomingRange(raw);
|
|
1163
|
+
if (parsed) {
|
|
1164
|
+
this.applyDateRange(parsed.start, parsed.end, true);
|
|
1165
|
+
this.selectedDate = parsed.start;
|
|
1166
|
+
this.displayMonth = parsed.start.getMonth();
|
|
1167
|
+
this.displayYear = parsed.start.getFullYear();
|
|
1168
|
+
this.rangeSelected.emit({ start: parsed.start, end: parsed.end });
|
|
1169
|
+
this.dateSelected.emit(parsed.start);
|
|
1170
|
+
this.blurEvent.emit();
|
|
1171
|
+
return;
|
|
1172
|
+
}
|
|
1173
|
+
const startOnly = this.parseDate(raw.replace(/\s*-\s*$/, "").trim());
|
|
1174
|
+
if (startOnly && !this.rangeEnd) {
|
|
1175
|
+
this.rangeStart = this.startOfDay(startOnly);
|
|
1176
|
+
this.selectedDate = this.rangeStart;
|
|
1177
|
+
this.inputControl.setValue(this.formatInProgressRange(this.rangeStart), { emitEvent: false });
|
|
1178
|
+
this.blurEvent.emit();
|
|
1179
|
+
return;
|
|
1180
|
+
}
|
|
1181
|
+
this.inputControl.setValue(current, { emitEvent: false });
|
|
1182
|
+
this.rangeStart = this.committedRangeStart;
|
|
1183
|
+
this.rangeEnd = this.committedRangeEnd;
|
|
1184
|
+
this.selectedDate = this.rangeStart;
|
|
1185
|
+
this.blurEvent.emit();
|
|
1186
|
+
}
|
|
1187
|
+
applyDateRange(start, end, emit) {
|
|
1188
|
+
this.rangeStart = start;
|
|
1189
|
+
this.rangeEnd = end;
|
|
1190
|
+
this.hoverDate = null;
|
|
1191
|
+
this.committedRangeStart = start;
|
|
1192
|
+
this.committedRangeEnd = end;
|
|
1193
|
+
const out = start && end ? this.formatWeek(start, end) : "";
|
|
1194
|
+
this.inputControl.setValue(out, { emitEvent: false });
|
|
1195
|
+
if (emit) {
|
|
1196
|
+
this.onChangeFn(out || null);
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
formatInProgressRange(start) {
|
|
1200
|
+
return `${this.datePipe.transform(start, this.dateFormat)} - `;
|
|
1201
|
+
}
|
|
1202
|
+
formatCommittedRangeInput() {
|
|
1203
|
+
if (this.committedRangeStart && this.committedRangeEnd) {
|
|
1204
|
+
return this.formatWeek(this.committedRangeStart, this.committedRangeEnd);
|
|
1205
|
+
}
|
|
1206
|
+
if (this.rangeStart && !this.rangeEnd) {
|
|
1207
|
+
return this.formatInProgressRange(this.rangeStart);
|
|
1208
|
+
}
|
|
1209
|
+
return "";
|
|
1210
|
+
}
|
|
1211
|
+
parseIncomingRange(value) {
|
|
1212
|
+
if (Array.isArray(value) && value.length >= 2) {
|
|
1213
|
+
const start = this.parseDate(value[0]);
|
|
1214
|
+
const end = this.parseDate(value[1]);
|
|
1215
|
+
if (start && end)
|
|
1216
|
+
return this.orderDateRange(start, end);
|
|
1217
|
+
return null;
|
|
1218
|
+
}
|
|
1219
|
+
if (value && typeof value === "object" && !(value instanceof Date) && value.start && value.end) {
|
|
1220
|
+
const start = this.parseDate(value.start);
|
|
1221
|
+
const end = this.parseDate(value.end);
|
|
1222
|
+
if (start && end)
|
|
1223
|
+
return this.orderDateRange(start, end);
|
|
1224
|
+
return null;
|
|
1225
|
+
}
|
|
1226
|
+
if (typeof value === "string") {
|
|
1227
|
+
const parts = value.split(" - ").map((part) => part.trim()).filter(Boolean);
|
|
1228
|
+
if (parts.length === 2) {
|
|
1229
|
+
const start = this.parseDate(parts[0]);
|
|
1230
|
+
const end = this.parseDate(parts[1]);
|
|
1231
|
+
if (start && end)
|
|
1232
|
+
return this.orderDateRange(start, end);
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
return null;
|
|
1236
|
+
}
|
|
1237
|
+
orderDateRange(a, b) {
|
|
1238
|
+
const start = this.startOfDay(a);
|
|
1239
|
+
const end = this.startOfDay(b);
|
|
1240
|
+
if (this.toDayKey(end) < this.toDayKey(start)) {
|
|
1241
|
+
return { start: end, end: start };
|
|
1242
|
+
}
|
|
1243
|
+
return { start, end };
|
|
1244
|
+
}
|
|
1245
|
+
startOfDay(d) {
|
|
1246
|
+
return new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
1247
|
+
}
|
|
1248
|
+
toDayKey(d) {
|
|
1249
|
+
return d.getFullYear() * 10000 + d.getMonth() * 100 + d.getDate();
|
|
1250
|
+
}
|
|
1251
|
+
isSameDay(a, b) {
|
|
1252
|
+
return this.toDayKey(a) === this.toDayKey(b);
|
|
1253
|
+
}
|
|
1254
|
+
isWithinDayRange(date, start, end) {
|
|
1255
|
+
const key = this.toDayKey(date);
|
|
1256
|
+
return key >= this.toDayKey(start) && key <= this.toDayKey(end);
|
|
1257
|
+
}
|
|
1258
|
+
rangeCoversMonth(year, monthIndex) {
|
|
1259
|
+
if (!this.rangeStart)
|
|
1260
|
+
return false;
|
|
1261
|
+
const start = this.rangeStart;
|
|
1262
|
+
const end = this.rangeEnd || this.rangeStart;
|
|
1263
|
+
const monthStart = new Date(year, monthIndex, 1);
|
|
1264
|
+
const monthEnd = new Date(year, monthIndex + 1, 0);
|
|
1265
|
+
return this.toDayKey(start) <= this.toDayKey(monthEnd) && this.toDayKey(end) >= this.toDayKey(monthStart);
|
|
1266
|
+
}
|
|
1267
|
+
rangeCoversYear(year) {
|
|
1268
|
+
if (!this.rangeStart)
|
|
1269
|
+
return false;
|
|
1270
|
+
const startYear = this.rangeStart.getFullYear();
|
|
1271
|
+
const endYear = (this.rangeEnd || this.rangeStart).getFullYear();
|
|
1272
|
+
return year >= startYear && year <= endYear;
|
|
1273
|
+
}
|
|
1274
|
+
restoreIncompleteRange() {
|
|
1275
|
+
if (this.selectionMode !== "range")
|
|
1276
|
+
return;
|
|
1277
|
+
if (!this.rangeStart || this.rangeEnd)
|
|
1278
|
+
return;
|
|
1279
|
+
this.rangeStart = this.committedRangeStart;
|
|
1280
|
+
this.rangeEnd = this.committedRangeEnd;
|
|
1281
|
+
this.hoverDate = null;
|
|
1282
|
+
this.selectedDate = this.rangeStart;
|
|
1283
|
+
const out = this.committedRangeStart && this.committedRangeEnd
|
|
1284
|
+
? this.formatWeek(this.committedRangeStart, this.committedRangeEnd)
|
|
1285
|
+
: "";
|
|
1286
|
+
this.inputControl.setValue(out, { emitEvent: false });
|
|
1287
|
+
}
|
|
1052
1288
|
// month
|
|
1053
1289
|
goToMonthView() {
|
|
1054
1290
|
this.currentView = "month";
|
|
@@ -1089,6 +1325,9 @@ class CalendarControl {
|
|
|
1089
1325
|
return this.months[this.displayMonth];
|
|
1090
1326
|
}
|
|
1091
1327
|
isMonthSelected(monthIndex) {
|
|
1328
|
+
if (this.selectionMode === "range") {
|
|
1329
|
+
return this.rangeCoversMonth(this.displayYear, monthIndex);
|
|
1330
|
+
}
|
|
1092
1331
|
return (!!this.selectedDate &&
|
|
1093
1332
|
this.selectedDate.getFullYear() === this.displayYear &&
|
|
1094
1333
|
this.selectedDate.getMonth() === monthIndex);
|
|
@@ -1097,6 +1336,9 @@ class CalendarControl {
|
|
|
1097
1336
|
return this.todayYear === this.displayYear && this.todayMonth === monthIndex;
|
|
1098
1337
|
}
|
|
1099
1338
|
isYearSelected(year) {
|
|
1339
|
+
if (this.selectionMode === "range") {
|
|
1340
|
+
return this.rangeCoversYear(year);
|
|
1341
|
+
}
|
|
1100
1342
|
return !!this.selectedDate && this.selectedDate.getFullYear() === year;
|
|
1101
1343
|
}
|
|
1102
1344
|
isYearCurrent(year) {
|
|
@@ -1398,6 +1640,9 @@ class CalendarControl {
|
|
|
1398
1640
|
}
|
|
1399
1641
|
}
|
|
1400
1642
|
else {
|
|
1643
|
+
if (this.selectionMode === "range") {
|
|
1644
|
+
this.restoreIncompleteRange();
|
|
1645
|
+
}
|
|
1401
1646
|
this.destroyPopper();
|
|
1402
1647
|
}
|
|
1403
1648
|
}
|
|
@@ -1408,10 +1653,18 @@ class CalendarControl {
|
|
|
1408
1653
|
}
|
|
1409
1654
|
clickOutside(event) {
|
|
1410
1655
|
if (!this.rootElement.nativeElement.contains(event.target) && this.isOpen) {
|
|
1411
|
-
this.
|
|
1656
|
+
if (this.selectionMode === "range") {
|
|
1657
|
+
this.closeCalendar();
|
|
1658
|
+
}
|
|
1659
|
+
else {
|
|
1660
|
+
this.isOpen = false;
|
|
1661
|
+
}
|
|
1412
1662
|
}
|
|
1413
1663
|
}
|
|
1414
1664
|
closeCalendar() {
|
|
1665
|
+
if (this.selectionMode === "range") {
|
|
1666
|
+
this.restoreIncompleteRange();
|
|
1667
|
+
}
|
|
1415
1668
|
this.destroyPopper();
|
|
1416
1669
|
this.isOpen = false;
|
|
1417
1670
|
if (CalendarControl._currentlyOpen === this) {
|
|
@@ -1424,6 +1677,7 @@ class CalendarControl {
|
|
|
1424
1677
|
this.selectedDate = null;
|
|
1425
1678
|
this.selectedWeekStart = null;
|
|
1426
1679
|
this.selectedWeekEnd = null;
|
|
1680
|
+
this.applyDateRange(null, null, false);
|
|
1427
1681
|
if (this._minDate) {
|
|
1428
1682
|
const parsed = new Date(this._minDate);
|
|
1429
1683
|
if (!isNaN(parsed.getTime())) {
|
|
@@ -1448,16 +1702,18 @@ class CalendarControl {
|
|
|
1448
1702
|
this.dateSelected.emit(null);
|
|
1449
1703
|
if (this.selectionMode === "week")
|
|
1450
1704
|
this.weekSelected.emit(null);
|
|
1705
|
+
if (this.selectionMode === "range")
|
|
1706
|
+
this.rangeSelected.emit(null);
|
|
1451
1707
|
}
|
|
1452
1708
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: CalendarControl, deps: [{ token: i1.DatePipe }], target: i0.ɵɵFactoryTarget.Component });
|
|
1453
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: CalendarControl, isStandalone: true, selector: "calendar-control", inputs: { title: "title", required: "required", customClass: "customClass", clearVal: "clearVal", deFocus: "deFocus", error: "error", errorMessage: "errorMessage", hourFormat: "hourFormat", selectionMode: "selectionMode", timeOnly: "timeOnly", dateFormat: "dateFormat", placeholder: "placeholder", viewMode: "viewMode", inputLoader: "inputLoader", disabled: "disabled", readonly: "readonly", submitted: "submitted", closeVal: ["close-val", "closeVal"], showTime: "showTime", defaultDate: "defaultDate", minDate: "minDate", maxDate: "maxDate" }, outputs: { selectionCleared: "selectionCleared", blurEvent: "blurEvent", dateSelected: "dateSelected", weekSelected: "weekSelected" }, host: { listeners: { "document:click": "clickOutside($event)" } }, providers: [
|
|
1709
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: CalendarControl, isStandalone: true, selector: "calendar-control", inputs: { title: "title", required: "required", customClass: "customClass", clearVal: "clearVal", deFocus: "deFocus", error: "error", errorMessage: "errorMessage", hourFormat: "hourFormat", selectionMode: "selectionMode", timeOnly: "timeOnly", dateFormat: "dateFormat", placeholder: "placeholder", viewMode: "viewMode", inputLoader: "inputLoader", disabled: "disabled", readonly: "readonly", submitted: "submitted", closeVal: ["close-val", "closeVal"], showTime: "showTime", defaultDate: "defaultDate", minDate: "minDate", maxDate: "maxDate" }, outputs: { selectionCleared: "selectionCleared", blurEvent: "blurEvent", dateSelected: "dateSelected", weekSelected: "weekSelected", rangeSelected: "rangeSelected" }, host: { listeners: { "document:click": "clickOutside($event)" } }, providers: [
|
|
1454
1710
|
DatePipe,
|
|
1455
1711
|
{
|
|
1456
1712
|
provide: NG_VALUE_ACCESSOR,
|
|
1457
1713
|
useExisting: forwardRef(() => CalendarControl),
|
|
1458
1714
|
multi: true,
|
|
1459
1715
|
},
|
|
1460
|
-
], viewQueries: [{ propertyName: "rootElement", first: true, predicate: ["root"], descendants: true, static: true }, { propertyName: "inputEl", first: true, predicate: ["inputEl"], descendants: true, static: true }, { propertyName: "datePickerEl", first: true, predicate: ["datePicker"], descendants: true }], ngImport: i0, template: "<div class=\"form-group calendar\" [ngClass]=\"customClass\" [class.readonly]=\"readonly\" [class.disabled]=\"disabled\" #root\r\n (click)=\"openCalendar()\">\r\n <label class=\"inp-label\" [ngClass]=\"{'required' : required}\" *ngIf=\"title\">{{ title }}</label>\r\n <input type=\"text\" #inputEl [placeholder]=\"placeholder\" [formControl]=\"inputControl\" class=\"form-control\"\r\n [ngClass]=\"{ 'is-invalid': error }\" (blur)=\"onBlur()\" (focus)=\"onFocus()\" [readonly]=\"readonly\"\r\n (click)=\"openCalendar(); $event.stopPropagation()\" (keydown)=\"onInputKeydown($event)\" />\r\n\r\n <span class=\"focus-border\" *ngIf=\"deFocus\"></span>\r\n @if(!inputLoader) {\r\n <span class=\"calendar-icon\">\r\n <i class=\"he\" [ngClass]=\"!timeOnly ? 'he-calendar-blank' : 'he-clock'\"></i>\r\n </span>\r\n }\r\n\r\n @if(!inputLoader &&(selectedDate && !disabled && !readonly) && clearVal) {\r\n <label class=\"clear\" (click)=\"clearDate($event)\">\r\n <i class=\"he he-close\"></i>\r\n </label>\r\n }\r\n\r\n @if(inputLoader) {\r\n <label class=\"loader input-loader\"></label>\r\n }\r\n @if(error) {\r\n <div class=\"val-msg\">{{ errorMessage }}</div>\r\n }\r\n\r\n <div class=\"datepicker-group\" #datePicker *ngIf=\"isOpen\" (mousedown)=\"$event.preventDefault()\"\r\n (click)=\"$event.stopPropagation()\">\r\n\r\n <!-- time picker -->\r\n <ng-container *ngIf=\"timeOnly\">\r\n <div class=\"time-picker\">\r\n <div class=\"time-select\">\r\n <button (click)=\"incrementHour()\" [disabled]=\"!isIncrementHourValid()\"><i\r\n class=\"he he-chevron-up\"></i></button>\r\n <ng-container *ngIf=\"hourFormat === '12'; else show24\">\r\n <div class=\"time-value\">\r\n {{ ((selectedHour % 12) || 12) | number:'2.0' }}\r\n </div>\r\n </ng-container>\r\n <ng-template #show24>\r\n <div class=\"time-value\">\r\n {{ selectedHour | number:'2.0' }}\r\n </div>\r\n </ng-template>\r\n\r\n <button (click)=\"decrementHour()\" [disabled]=\"!isDecrementHourValid()\"><i\r\n class=\"he he-chevron-down\"></i></button>\r\n </div>\r\n <span class=\"time-separator\">:</span>\r\n <div class=\"time-select\">\r\n <button (click)=\"incrementMinute()\" [disabled]=\"!isIncrementMinuteValid()\"><i\r\n class=\"he he-chevron-up\"></i></button>\r\n <div class=\"time-value\">{{ selectedMinute | number:'2.0' }}</div>\r\n <button (click)=\"decrementMinute()\" [disabled]=\"!isDecrementMinuteValid()\"><i\r\n class=\"he he-chevron-down\"></i></button>\r\n </div>\r\n <div class=\"ampm-toggle\" *ngIf=\"hourFormat === '12'\">\r\n <button type=\"button\" [class.active]=\"meridian === 'AM'\" (click)=\"setMeridian('AM')\">AM</button>\r\n <button type=\"button\" [class.active]=\"meridian === 'PM'\" (click)=\"setMeridian('PM')\">PM</button>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- day view -->\r\n <ng-container *ngIf=\"!timeOnly && currentView === 'day'\">\r\n <div class=\"header\">\r\n <button class=\"calendar-arrow\" (click)=\"prevMonth()\"><i class=\"he he-chevron-left\"></i></button>\r\n <div class=\"title\" (click)=\"goToMonthView()\">\r\n <div>{{ displayMonthName }}</div>\r\n <div>{{ displayYear }}</div>\r\n </div>\r\n <button class=\"calendar-arrow\" (click)=\"nextMonth()\"><i class=\"he he-chevron-right\"></i></button>\r\n </div>\r\n <div class=\"week-header\">\r\n <div>Sun</div>\r\n <div>Mon</div>\r\n <div>Tue</div>\r\n <div>Wed</div>\r\n <div>Thu</div>\r\n <div>Fri</div>\r\n <div>Sat</div>\r\n </div>\r\n <div class=\"days-grid\" [class.week-mode]=\"selectionMode === 'week'\">\r\n <div class=\"day-cell\" *ngFor=\"let cell of daysInMonth; trackBy: trackByDate\" (click)=\"selectDay(cell)\"\r\n (mouseenter)=\"onDayHover(cell)\" (mouseleave)=\"onDayLeave()\"\r\n [class.other-month]=\"cell.otherMonth\"\r\n [class.disabled]=\"cell.disabled\"\r\n [class.selected]=\"cell.selected\"\r\n [class.week-hover]=\"isInHoverWeek(cell.date)\"\r\n [class.today]=\"cell.today\">\r\n {{ cell.day }}\r\n </div>\r\n </div>\r\n <ng-container *ngIf=\"showTime\">\r\n <div class=\"time-picker\">\r\n <div class=\"time-select\">\r\n <button type=\"button\" (click)=\"incrementHour()\" [disabled]=\"!isIncrementHourValid()\">\r\n <i class=\"he he-chevron-up\"></i>\r\n </button>\r\n <ng-container *ngIf=\"hourFormat === '12'; else show24\">\r\n <div class=\"time-value\">\r\n {{\r\n selectedHour % 12 === 0\r\n ? 12\r\n : selectedHour % 12\r\n | number:'2.0' }}\r\n </div>\r\n </ng-container>\r\n <ng-template #show24>\r\n <div class=\"time-value\">{{ selectedHour | number:'2.0' }}</div>\r\n </ng-template>\r\n <button type=\"button\" (click)=\"decrementHour()\" [disabled]=\"!isDecrementHourValid()\">\r\n <i class=\"he he-chevron-down\"></i>\r\n </button>\r\n </div>\r\n <span class=\"time-separator\">:</span>\r\n <div class=\"time-select\">\r\n <button type=\"button\" (click)=\"incrementMinute()\" [disabled]=\"!isIncrementMinuteValid()\">\r\n <i class=\"he he-chevron-up\"></i>\r\n </button>\r\n <div class=\"time-value\">\r\n {{ selectedMinute < 10 ? '0' +selectedMinute : selectedMinute }} </div>\r\n <button type=\"button\" (click)=\"decrementMinute()\" [disabled]=\"!isDecrementMinuteValid()\">\r\n <i class=\"he he-chevron-down\"></i>\r\n </button>\r\n </div>\r\n <div class=\"ampm-toggle\" *ngIf=\"hourFormat === '12'\">\r\n <button type=\"button\" [class.active]=\"meridian === 'AM'\" (click)=\"setMeridian('AM')\">AM</button>\r\n <button type=\"button\" [class.active]=\"meridian === 'PM'\" (click)=\"setMeridian('PM')\">PM</button>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- month view -->\r\n <ng-container *ngIf=\"!timeOnly && currentView === 'month'\">\r\n <div class=\"header\" *ngIf=\"viewMode !== 'month'\">\r\n <button class=\"calendar-arrow\" (click)=\"displayYear = displayYear - 1\"><i\r\n class=\"he he-chevron-left\"></i></button>\r\n <div class=\"title\" (click)=\"goToYearRangeView()\">{{ displayYear }}</div>\r\n <button class=\"calendar-arrow\" (click)=\"displayYear = displayYear + 1\"><i\r\n class=\"he he-chevron-right\"></i></button>\r\n </div>\r\n <div class=\"month-grid\">\r\n <div class=\"month-cell\" *ngFor=\"let m of months; index as i\" (click)=\"selectMonth(i)\"\r\n [class.selected]=\"isMonthSelected(i)\" [class.today]=\"isMonthCurrent(i)\">{{ m }}\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- year range view -->\r\n <ng-container *ngIf=\"!timeOnly && currentView === 'yearRange'\">\r\n <div class=\"header\">\r\n <button class=\"calendar-arrow\" (click)=\"prevYearRange()\"><i class=\"he he-chevron-left\"></i></button>\r\n <div class=\"title\">{{ yearRange[0] }} ~ {{ yearRange[yearRangeSize-1] }}</div>\r\n <button class=\"calendar-arrow\" (click)=\"nextYearRange()\"><i class=\"he he-chevron-right\"></i></button>\r\n </div>\r\n <div class=\"year-grid\">\r\n <div class=\"year-cell\" *ngFor=\"let y of yearRange\" (click)=\"selectYear(y)\"\r\n [class.selected]=\"isYearSelected(y)\" [class.today]=\"isYearCurrent(y)\">{{ y }}</div>\r\n </div>\r\n </ng-container>\r\n\r\n </div>\r\n</div>", styles: [".form-group.calendar{position:relative}.form-group.calendar .datepicker-group{left:0;width:100%;z-index:1000;padding:.5rem;color:#495057;min-width:240px;max-width:260px;border-radius:3px;background:#fff;box-shadow:0 2px 4px -1px #0003,0 4px 5px #00000024,0 1px 10px #0000001f}.form-group.calendar .datepicker-group .header{display:flex;font-weight:600;padding:5px;align-items:center;justify-content:space-between;border-bottom:1px solid #dee2e6}.form-group.calendar .datepicker-group .header .title{gap:8px;display:flex;font-size:15px;cursor:pointer;font-weight:600}.form-group.calendar .datepicker-group .header .calendar-arrow{width:28px;height:28px;border:none;line-height:1;cursor:pointer;background:none}.form-group.calendar .datepicker-group .header .calendar-arrow i{font-size:14px}.form-group.calendar .datepicker-group .header .calendar-arrow:hover{background:#f0f0f0}.form-group.calendar .datepicker-group .week-header{display:grid;padding:8px 0;font-size:13px;font-weight:700;text-align:center;grid-template-columns:repeat(7,1fr)}.form-group.calendar .datepicker-group .days-grid,.form-group.calendar .datepicker-group .month-grid,.form-group.calendar .datepicker-group .year-grid{gap:3px;padding:5px;display:grid;grid-template-columns:repeat(7,1fr)}.form-group.calendar .datepicker-group .days-grid .day-cell,.form-group.calendar .datepicker-group .days-grid .month-cell,.form-group.calendar .datepicker-group .days-grid .year-cell,.form-group.calendar .datepicker-group .month-grid .day-cell,.form-group.calendar .datepicker-group .month-grid .month-cell,.form-group.calendar .datepicker-group .month-grid .year-cell,.form-group.calendar .datepicker-group .year-grid .day-cell,.form-group.calendar .datepicker-group .year-grid .month-cell,.form-group.calendar .datepicker-group .year-grid .year-cell{display:flex;font-size:14px;cursor:pointer;align-items:center;justify-content:center}.form-group.calendar .datepicker-group .days-grid .day-cell.today,.form-group.calendar .datepicker-group .days-grid .month-cell.today,.form-group.calendar .datepicker-group .days-grid .year-cell.today,.form-group.calendar .datepicker-group .month-grid .day-cell.today,.form-group.calendar .datepicker-group .month-grid .month-cell.today,.form-group.calendar .datepicker-group .month-grid .year-cell.today,.form-group.calendar .datepicker-group .year-grid .day-cell.today,.form-group.calendar .datepicker-group .year-grid .month-cell.today,.form-group.calendar .datepicker-group .year-grid .year-cell.today{color:#37c0b3;font-weight:700;border:1px solid #37c0b3}.form-group.calendar .datepicker-group .days-grid .day-cell.selected,.form-group.calendar .datepicker-group .days-grid .day-cell:hover,.form-group.calendar .datepicker-group .days-grid .month-cell.selected,.form-group.calendar .datepicker-group .days-grid .month-cell:hover,.form-group.calendar .datepicker-group .days-grid .year-cell.selected,.form-group.calendar .datepicker-group .days-grid .year-cell:hover,.form-group.calendar .datepicker-group .month-grid .day-cell.selected,.form-group.calendar .datepicker-group .month-grid .day-cell:hover,.form-group.calendar .datepicker-group .month-grid .month-cell.selected,.form-group.calendar .datepicker-group .month-grid .month-cell:hover,.form-group.calendar .datepicker-group .month-grid .year-cell.selected,.form-group.calendar .datepicker-group .month-grid .year-cell:hover,.form-group.calendar .datepicker-group .year-grid .day-cell.selected,.form-group.calendar .datepicker-group .year-grid .day-cell:hover,.form-group.calendar .datepicker-group .year-grid .month-cell.selected,.form-group.calendar .datepicker-group .year-grid .month-cell:hover,.form-group.calendar .datepicker-group .year-grid .year-cell.selected,.form-group.calendar .datepicker-group .year-grid .year-cell:hover{color:#fff;background:#37c0b3}.form-group.calendar .datepicker-group .days-grid .day-cell.disabled,.form-group.calendar .datepicker-group .days-grid .month-cell.disabled,.form-group.calendar .datepicker-group .days-grid .year-cell.disabled,.form-group.calendar .datepicker-group .month-grid .day-cell.disabled,.form-group.calendar .datepicker-group .month-grid .month-cell.disabled,.form-group.calendar .datepicker-group .month-grid .year-cell.disabled,.form-group.calendar .datepicker-group .year-grid .day-cell.disabled,.form-group.calendar .datepicker-group .year-grid .month-cell.disabled,.form-group.calendar .datepicker-group .year-grid .year-cell.disabled{color:#e0e0e0;background:none;-webkit-user-select:none;user-select:none;cursor:not-allowed}.form-group.calendar .datepicker-group .days-grid .day-cell.disabled.today,.form-group.calendar .datepicker-group .days-grid .month-cell.disabled.today,.form-group.calendar .datepicker-group .days-grid .year-cell.disabled.today,.form-group.calendar .datepicker-group .month-grid .day-cell.disabled.today,.form-group.calendar .datepicker-group .month-grid .month-cell.disabled.today,.form-group.calendar .datepicker-group .month-grid .year-cell.disabled.today,.form-group.calendar .datepicker-group .year-grid .day-cell.disabled.today,.form-group.calendar .datepicker-group .year-grid .month-cell.disabled.today,.form-group.calendar .datepicker-group .year-grid .year-cell.disabled.today{color:#37c0b3}.form-group.calendar .datepicker-group .days-grid .day-cell.disabled.today:hover,.form-group.calendar .datepicker-group .days-grid .month-cell.disabled.today:hover,.form-group.calendar .datepicker-group .days-grid .year-cell.disabled.today:hover,.form-group.calendar .datepicker-group .month-grid .day-cell.disabled.today:hover,.form-group.calendar .datepicker-group .month-grid .month-cell.disabled.today:hover,.form-group.calendar .datepicker-group .month-grid .year-cell.disabled.today:hover,.form-group.calendar .datepicker-group .year-grid .day-cell.disabled.today:hover,.form-group.calendar .datepicker-group .year-grid .month-cell.disabled.today:hover,.form-group.calendar .datepicker-group .year-grid .year-cell.disabled.today:hover{color:#fff;background:#37c0b3}.form-group.calendar .datepicker-group .days-grid .day-cell.disabled:hover,.form-group.calendar .datepicker-group .days-grid .month-cell.disabled:hover,.form-group.calendar .datepicker-group .days-grid .year-cell.disabled:hover,.form-group.calendar .datepicker-group .month-grid .day-cell.disabled:hover,.form-group.calendar .datepicker-group .month-grid .month-cell.disabled:hover,.form-group.calendar .datepicker-group .month-grid .year-cell.disabled:hover,.form-group.calendar .datepicker-group .year-grid .day-cell.disabled:hover,.form-group.calendar .datepicker-group .year-grid .month-cell.disabled:hover,.form-group.calendar .datepicker-group .year-grid .year-cell.disabled:hover{color:#e0e0e0;background:transparent}.form-group.calendar .datepicker-group .days-grid .day-cell,.form-group.calendar .datepicker-group .month-grid .day-cell,.form-group.calendar .datepicker-group .year-grid .day-cell{padding:5px 2px;border-radius:50%}.form-group.calendar .datepicker-group .days-grid .day-cell.other-month:not(.selected):not(:hover),.form-group.calendar .datepicker-group .month-grid .day-cell.other-month:not(.selected):not(:hover),.form-group.calendar .datepicker-group .year-grid .day-cell.other-month:not(.selected):not(:hover){color:#c5c5c5}.form-group.calendar .datepicker-group .days-grid .month-cell,.form-group.calendar .datepicker-group .days-grid .year-cell,.form-group.calendar .datepicker-group .month-grid .month-cell,.form-group.calendar .datepicker-group .month-grid .year-cell,.form-group.calendar .datepicker-group .year-grid .month-cell,.form-group.calendar .datepicker-group .year-grid .year-cell{padding:8px 2px;border-radius:3px}.form-group.calendar .datepicker-group .days-grid.week-mode .day-cell{border-radius:4px}.form-group.calendar .datepicker-group .days-grid.week-mode .day-cell.week-hover:not(.selected){color:#0d6f7d;background:#e6f5f3}.form-group.calendar .datepicker-group .month-grid{grid-template-columns:repeat(3,1fr)}.form-group.calendar .datepicker-group .year-grid{grid-template-columns:repeat(4,1fr)}.form-group.calendar .datepicker-group .time-picker{display:flex;-webkit-user-select:none;user-select:none;align-items:center;justify-content:center}.form-group.calendar .datepicker-group .time-picker .ampm-toggle{gap:6px;display:flex;margin-left:1rem;flex-direction:column;justify-content:center}.form-group.calendar .datepicker-group .time-picker .ampm-toggle button{cursor:pointer;padding:3px 8px;font-size:.75rem;background:#fff;border:1px solid #cccccc}.form-group.calendar .datepicker-group .time-picker .ampm-toggle button.active{color:#fff;border-color:#37c0b3;background-color:#37c0b3}.form-group.calendar .datepicker-group .time-picker .time-select{display:flex;margin:0 .75rem;align-items:center;flex-direction:column}.form-group.calendar .datepicker-group .time-picker .time-select button{border:none;cursor:pointer;padding:4px 8px;background:transparent}.form-group.calendar .datepicker-group .time-picker .time-select button i{font-size:1rem}.form-group.calendar .datepicker-group .time-picker .time-select button:hover{background:#f0f0f0}.form-group.calendar .datepicker-group .time-picker .time-select .time-value{width:2rem;font-size:1rem;text-align:center;margin:2px 3px 4px}.form-group.calendar .datepicker-group .time-picker .time-separator{line-height:1;font-size:1rem}.form-group.calendar .clear{right:35px}.form-group.calendar.group-sm .clear{top:7px;right:35px}\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: ReactiveFormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FormsModule }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }] });
|
|
1716
|
+
], viewQueries: [{ propertyName: "rootElement", first: true, predicate: ["root"], descendants: true, static: true }, { propertyName: "inputEl", first: true, predicate: ["inputEl"], descendants: true, static: true }, { propertyName: "datePickerEl", first: true, predicate: ["datePicker"], descendants: true }], ngImport: i0, template: "<div class=\"form-group calendar\" [ngClass]=\"customClass\" [class.readonly]=\"readonly\" [class.disabled]=\"disabled\" #root\r\n (click)=\"openCalendar()\">\r\n <label class=\"inp-label\" [ngClass]=\"{'required' : required}\" *ngIf=\"title\">{{ title }}</label>\r\n <input type=\"text\" #inputEl [placeholder]=\"placeholder\" [formControl]=\"inputControl\" class=\"form-control\"\r\n [ngClass]=\"{ 'is-invalid': error }\" (blur)=\"onBlur()\" (focus)=\"onFocus()\" [readonly]=\"readonly\"\r\n (click)=\"openCalendar(); $event.stopPropagation()\" (keydown)=\"onInputKeydown($event)\" />\r\n\r\n <span class=\"focus-border\" *ngIf=\"deFocus\"></span>\r\n @if(!inputLoader) {\r\n <span class=\"calendar-icon\">\r\n <i class=\"he\" [ngClass]=\"!timeOnly ? 'he-calendar-blank' : 'he-clock'\"></i>\r\n </span>\r\n }\r\n\r\n @if(!inputLoader &&(selectedDate && !disabled && !readonly) && clearVal) {\r\n <label class=\"clear\" (click)=\"clearDate($event)\">\r\n <i class=\"he he-close\"></i>\r\n </label>\r\n }\r\n\r\n @if(inputLoader) {\r\n <label class=\"loader input-loader\"></label>\r\n }\r\n @if(error) {\r\n <div class=\"val-msg\">{{ errorMessage }}</div>\r\n }\r\n\r\n <div class=\"datepicker-group\" #datePicker *ngIf=\"isOpen\" (mousedown)=\"$event.preventDefault()\"\r\n (click)=\"$event.stopPropagation()\">\r\n\r\n <!-- time picker -->\r\n <ng-container *ngIf=\"timeOnly\">\r\n <div class=\"time-picker\">\r\n <div class=\"time-select\">\r\n <button (click)=\"incrementHour()\" [disabled]=\"!isIncrementHourValid()\"><i\r\n class=\"he he-chevron-up\"></i></button>\r\n <ng-container *ngIf=\"hourFormat === '12'; else show24\">\r\n <div class=\"time-value\">\r\n {{ ((selectedHour % 12) || 12) | number:'2.0' }}\r\n </div>\r\n </ng-container>\r\n <ng-template #show24>\r\n <div class=\"time-value\">\r\n {{ selectedHour | number:'2.0' }}\r\n </div>\r\n </ng-template>\r\n\r\n <button (click)=\"decrementHour()\" [disabled]=\"!isDecrementHourValid()\"><i\r\n class=\"he he-chevron-down\"></i></button>\r\n </div>\r\n <span class=\"time-separator\">:</span>\r\n <div class=\"time-select\">\r\n <button (click)=\"incrementMinute()\" [disabled]=\"!isIncrementMinuteValid()\"><i\r\n class=\"he he-chevron-up\"></i></button>\r\n <div class=\"time-value\">{{ selectedMinute | number:'2.0' }}</div>\r\n <button (click)=\"decrementMinute()\" [disabled]=\"!isDecrementMinuteValid()\"><i\r\n class=\"he he-chevron-down\"></i></button>\r\n </div>\r\n <div class=\"ampm-toggle\" *ngIf=\"hourFormat === '12'\">\r\n <button type=\"button\" [class.active]=\"meridian === 'AM'\" (click)=\"setMeridian('AM')\">AM</button>\r\n <button type=\"button\" [class.active]=\"meridian === 'PM'\" (click)=\"setMeridian('PM')\">PM</button>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- day view -->\r\n <ng-container *ngIf=\"!timeOnly && currentView === 'day'\">\r\n <div class=\"header\">\r\n <button class=\"calendar-arrow\" (click)=\"prevMonth()\"><i class=\"he he-chevron-left\"></i></button>\r\n <div class=\"title\" (click)=\"goToMonthView()\">\r\n <div>{{ displayMonthName }}</div>\r\n <div>{{ displayYear }}</div>\r\n </div>\r\n <button class=\"calendar-arrow\" (click)=\"nextMonth()\"><i class=\"he he-chevron-right\"></i></button>\r\n </div>\r\n <div class=\"week-header\">\r\n <div>Sun</div>\r\n <div>Mon</div>\r\n <div>Tue</div>\r\n <div>Wed</div>\r\n <div>Thu</div>\r\n <div>Fri</div>\r\n <div>Sat</div>\r\n </div>\r\n <div class=\"days-grid\" [class.week-mode]=\"selectionMode === 'week'\"\r\n [class.range-mode]=\"selectionMode === 'range'\" (mouseleave)=\"onDayLeave()\">\r\n <div class=\"day-cell\" *ngFor=\"let cell of daysInMonth; trackBy: trackByDate\" (click)=\"selectDay(cell)\"\r\n (mouseenter)=\"onDayHover(cell)\" (mouseleave)=\"onDayLeave()\"\r\n [class.other-month]=\"cell.otherMonth\"\r\n [class.disabled]=\"cell.disabled\"\r\n [class.selected]=\"cell.selected\"\r\n [class.week-hover]=\"isInHoverWeek(cell.date)\"\r\n [class.range-start]=\"isRangeStart(cell.date)\"\r\n [class.range-end]=\"isRangeEnd(cell.date)\"\r\n [class.in-range]=\"isInSelectedRange(cell.date)\"\r\n [class.range-hover]=\"isInHoverRange(cell.date)\"\r\n [class.today]=\"cell.today\">\r\n {{ cell.day }}\r\n </div>\r\n </div>\r\n <ng-container *ngIf=\"showTime\">\r\n <div class=\"time-picker\">\r\n <div class=\"time-select\">\r\n <button type=\"button\" (click)=\"incrementHour()\" [disabled]=\"!isIncrementHourValid()\">\r\n <i class=\"he he-chevron-up\"></i>\r\n </button>\r\n <ng-container *ngIf=\"hourFormat === '12'; else show24\">\r\n <div class=\"time-value\">\r\n {{\r\n selectedHour % 12 === 0\r\n ? 12\r\n : selectedHour % 12\r\n | number:'2.0' }}\r\n </div>\r\n </ng-container>\r\n <ng-template #show24>\r\n <div class=\"time-value\">{{ selectedHour | number:'2.0' }}</div>\r\n </ng-template>\r\n <button type=\"button\" (click)=\"decrementHour()\" [disabled]=\"!isDecrementHourValid()\">\r\n <i class=\"he he-chevron-down\"></i>\r\n </button>\r\n </div>\r\n <span class=\"time-separator\">:</span>\r\n <div class=\"time-select\">\r\n <button type=\"button\" (click)=\"incrementMinute()\" [disabled]=\"!isIncrementMinuteValid()\">\r\n <i class=\"he he-chevron-up\"></i>\r\n </button>\r\n <div class=\"time-value\">\r\n {{ selectedMinute < 10 ? '0' +selectedMinute : selectedMinute }} </div>\r\n <button type=\"button\" (click)=\"decrementMinute()\" [disabled]=\"!isDecrementMinuteValid()\">\r\n <i class=\"he he-chevron-down\"></i>\r\n </button>\r\n </div>\r\n <div class=\"ampm-toggle\" *ngIf=\"hourFormat === '12'\">\r\n <button type=\"button\" [class.active]=\"meridian === 'AM'\" (click)=\"setMeridian('AM')\">AM</button>\r\n <button type=\"button\" [class.active]=\"meridian === 'PM'\" (click)=\"setMeridian('PM')\">PM</button>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- month view -->\r\n <ng-container *ngIf=\"!timeOnly && currentView === 'month'\">\r\n <div class=\"header\" *ngIf=\"viewMode !== 'month'\">\r\n <button class=\"calendar-arrow\" (click)=\"displayYear = displayYear - 1\"><i\r\n class=\"he he-chevron-left\"></i></button>\r\n <div class=\"title\" (click)=\"goToYearRangeView()\">{{ displayYear }}</div>\r\n <button class=\"calendar-arrow\" (click)=\"displayYear = displayYear + 1\"><i\r\n class=\"he he-chevron-right\"></i></button>\r\n </div>\r\n <div class=\"month-grid\">\r\n <div class=\"month-cell\" *ngFor=\"let m of months; index as i\" (click)=\"selectMonth(i)\"\r\n [class.selected]=\"isMonthSelected(i)\" [class.today]=\"isMonthCurrent(i)\">{{ m }}\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- year range view -->\r\n <ng-container *ngIf=\"!timeOnly && currentView === 'yearRange'\">\r\n <div class=\"header\">\r\n <button class=\"calendar-arrow\" (click)=\"prevYearRange()\"><i class=\"he he-chevron-left\"></i></button>\r\n <div class=\"title\">{{ yearRange[0] }} ~ {{ yearRange[yearRangeSize-1] }}</div>\r\n <button class=\"calendar-arrow\" (click)=\"nextYearRange()\"><i class=\"he he-chevron-right\"></i></button>\r\n </div>\r\n <div class=\"year-grid\">\r\n <div class=\"year-cell\" *ngFor=\"let y of yearRange\" (click)=\"selectYear(y)\"\r\n [class.selected]=\"isYearSelected(y)\" [class.today]=\"isYearCurrent(y)\">{{ y }}</div>\r\n </div>\r\n </ng-container>\r\n\r\n </div>\r\n</div>", styles: [".form-group.calendar{position:relative}.form-group.calendar .datepicker-group{left:0;width:100%;z-index:1000;padding:.5rem;color:#495057;min-width:240px;max-width:260px;border-radius:3px;background:#fff;box-shadow:0 2px 4px -1px #0003,0 4px 5px #00000024,0 1px 10px #0000001f}.form-group.calendar .datepicker-group .header{display:flex;font-weight:600;padding:5px;align-items:center;justify-content:space-between;border-bottom:1px solid #dee2e6}.form-group.calendar .datepicker-group .header .title{gap:8px;display:flex;font-size:15px;cursor:pointer;font-weight:600}.form-group.calendar .datepicker-group .header .calendar-arrow{width:28px;height:28px;border:none;line-height:1;cursor:pointer;background:none}.form-group.calendar .datepicker-group .header .calendar-arrow i{font-size:14px}.form-group.calendar .datepicker-group .header .calendar-arrow:hover{background:#f0f0f0}.form-group.calendar .datepicker-group .week-header{display:grid;padding:8px 0;font-size:13px;font-weight:700;text-align:center;grid-template-columns:repeat(7,1fr)}.form-group.calendar .datepicker-group .days-grid,.form-group.calendar .datepicker-group .month-grid,.form-group.calendar .datepicker-group .year-grid{gap:3px;padding:5px;display:grid;grid-template-columns:repeat(7,1fr)}.form-group.calendar .datepicker-group .days-grid .day-cell,.form-group.calendar .datepicker-group .days-grid .month-cell,.form-group.calendar .datepicker-group .days-grid .year-cell,.form-group.calendar .datepicker-group .month-grid .day-cell,.form-group.calendar .datepicker-group .month-grid .month-cell,.form-group.calendar .datepicker-group .month-grid .year-cell,.form-group.calendar .datepicker-group .year-grid .day-cell,.form-group.calendar .datepicker-group .year-grid .month-cell,.form-group.calendar .datepicker-group .year-grid .year-cell{display:flex;font-size:14px;cursor:pointer;align-items:center;justify-content:center}.form-group.calendar .datepicker-group .days-grid .day-cell.today,.form-group.calendar .datepicker-group .days-grid .month-cell.today,.form-group.calendar .datepicker-group .days-grid .year-cell.today,.form-group.calendar .datepicker-group .month-grid .day-cell.today,.form-group.calendar .datepicker-group .month-grid .month-cell.today,.form-group.calendar .datepicker-group .month-grid .year-cell.today,.form-group.calendar .datepicker-group .year-grid .day-cell.today,.form-group.calendar .datepicker-group .year-grid .month-cell.today,.form-group.calendar .datepicker-group .year-grid .year-cell.today{color:#37c0b3;font-weight:700;border:1px solid #37c0b3}.form-group.calendar .datepicker-group .days-grid .day-cell.selected,.form-group.calendar .datepicker-group .days-grid .day-cell:hover,.form-group.calendar .datepicker-group .days-grid .month-cell.selected,.form-group.calendar .datepicker-group .days-grid .month-cell:hover,.form-group.calendar .datepicker-group .days-grid .year-cell.selected,.form-group.calendar .datepicker-group .days-grid .year-cell:hover,.form-group.calendar .datepicker-group .month-grid .day-cell.selected,.form-group.calendar .datepicker-group .month-grid .day-cell:hover,.form-group.calendar .datepicker-group .month-grid .month-cell.selected,.form-group.calendar .datepicker-group .month-grid .month-cell:hover,.form-group.calendar .datepicker-group .month-grid .year-cell.selected,.form-group.calendar .datepicker-group .month-grid .year-cell:hover,.form-group.calendar .datepicker-group .year-grid .day-cell.selected,.form-group.calendar .datepicker-group .year-grid .day-cell:hover,.form-group.calendar .datepicker-group .year-grid .month-cell.selected,.form-group.calendar .datepicker-group .year-grid .month-cell:hover,.form-group.calendar .datepicker-group .year-grid .year-cell.selected,.form-group.calendar .datepicker-group .year-grid .year-cell:hover{color:#fff;background:#37c0b3}.form-group.calendar .datepicker-group .days-grid .day-cell.disabled,.form-group.calendar .datepicker-group .days-grid .month-cell.disabled,.form-group.calendar .datepicker-group .days-grid .year-cell.disabled,.form-group.calendar .datepicker-group .month-grid .day-cell.disabled,.form-group.calendar .datepicker-group .month-grid .month-cell.disabled,.form-group.calendar .datepicker-group .month-grid .year-cell.disabled,.form-group.calendar .datepicker-group .year-grid .day-cell.disabled,.form-group.calendar .datepicker-group .year-grid .month-cell.disabled,.form-group.calendar .datepicker-group .year-grid .year-cell.disabled{color:#e0e0e0;background:none;-webkit-user-select:none;user-select:none;cursor:not-allowed}.form-group.calendar .datepicker-group .days-grid .day-cell.disabled.today,.form-group.calendar .datepicker-group .days-grid .month-cell.disabled.today,.form-group.calendar .datepicker-group .days-grid .year-cell.disabled.today,.form-group.calendar .datepicker-group .month-grid .day-cell.disabled.today,.form-group.calendar .datepicker-group .month-grid .month-cell.disabled.today,.form-group.calendar .datepicker-group .month-grid .year-cell.disabled.today,.form-group.calendar .datepicker-group .year-grid .day-cell.disabled.today,.form-group.calendar .datepicker-group .year-grid .month-cell.disabled.today,.form-group.calendar .datepicker-group .year-grid .year-cell.disabled.today{color:#37c0b3}.form-group.calendar .datepicker-group .days-grid .day-cell.disabled.today:hover,.form-group.calendar .datepicker-group .days-grid .month-cell.disabled.today:hover,.form-group.calendar .datepicker-group .days-grid .year-cell.disabled.today:hover,.form-group.calendar .datepicker-group .month-grid .day-cell.disabled.today:hover,.form-group.calendar .datepicker-group .month-grid .month-cell.disabled.today:hover,.form-group.calendar .datepicker-group .month-grid .year-cell.disabled.today:hover,.form-group.calendar .datepicker-group .year-grid .day-cell.disabled.today:hover,.form-group.calendar .datepicker-group .year-grid .month-cell.disabled.today:hover,.form-group.calendar .datepicker-group .year-grid .year-cell.disabled.today:hover{color:#fff;background:#37c0b3}.form-group.calendar .datepicker-group .days-grid .day-cell.disabled:hover,.form-group.calendar .datepicker-group .days-grid .month-cell.disabled:hover,.form-group.calendar .datepicker-group .days-grid .year-cell.disabled:hover,.form-group.calendar .datepicker-group .month-grid .day-cell.disabled:hover,.form-group.calendar .datepicker-group .month-grid .month-cell.disabled:hover,.form-group.calendar .datepicker-group .month-grid .year-cell.disabled:hover,.form-group.calendar .datepicker-group .year-grid .day-cell.disabled:hover,.form-group.calendar .datepicker-group .year-grid .month-cell.disabled:hover,.form-group.calendar .datepicker-group .year-grid .year-cell.disabled:hover{color:#e0e0e0;background:transparent}.form-group.calendar .datepicker-group .days-grid .day-cell,.form-group.calendar .datepicker-group .month-grid .day-cell,.form-group.calendar .datepicker-group .year-grid .day-cell{padding:5px 2px;border-radius:50%}.form-group.calendar .datepicker-group .days-grid .day-cell.other-month:not(.selected):not(:hover),.form-group.calendar .datepicker-group .month-grid .day-cell.other-month:not(.selected):not(:hover),.form-group.calendar .datepicker-group .year-grid .day-cell.other-month:not(.selected):not(:hover){color:#c5c5c5}.form-group.calendar .datepicker-group .days-grid .month-cell,.form-group.calendar .datepicker-group .days-grid .year-cell,.form-group.calendar .datepicker-group .month-grid .month-cell,.form-group.calendar .datepicker-group .month-grid .year-cell,.form-group.calendar .datepicker-group .year-grid .month-cell,.form-group.calendar .datepicker-group .year-grid .year-cell{padding:8px 2px;border-radius:3px}.form-group.calendar .datepicker-group .days-grid.week-mode .day-cell{border-radius:4px}.form-group.calendar .datepicker-group .days-grid.week-mode .day-cell.week-hover:not(.selected){color:#0d6f7d;background:#e6f5f3}.form-group.calendar .datepicker-group .days-grid.range-mode .day-cell{border-radius:4px}.form-group.calendar .datepicker-group .days-grid.range-mode .day-cell.in-range:not(.range-start):not(.range-end),.form-group.calendar .datepicker-group .days-grid.range-mode .day-cell.range-hover:not(.range-start):not(.range-end){color:#0d6f7d;background:#e6f5f3;border-radius:0}.form-group.calendar .datepicker-group .days-grid.range-mode .day-cell.other-month.in-range:not(.range-start):not(.range-end),.form-group.calendar .datepicker-group .days-grid.range-mode .day-cell.other-month.range-hover:not(.range-start):not(.range-end){color:#0d6f7d}.form-group.calendar .datepicker-group .days-grid.range-mode .day-cell.range-start,.form-group.calendar .datepicker-group .days-grid.range-mode .day-cell.range-end,.form-group.calendar .datepicker-group .days-grid.range-mode .day-cell.selected{color:#fff;background:#37c0b3}.form-group.calendar .datepicker-group .days-grid.range-mode .day-cell.range-start:not(.range-end){border-radius:4px 0 0 4px}.form-group.calendar .datepicker-group .days-grid.range-mode .day-cell.range-end:not(.range-start){border-radius:0 4px 4px 0}.form-group.calendar .datepicker-group .days-grid.range-mode .day-cell:hover:not(.disabled):not(.range-start):not(.range-end){color:#0d6f7d;background:#e6f5f3}.form-group.calendar .datepicker-group .month-grid{grid-template-columns:repeat(3,1fr)}.form-group.calendar .datepicker-group .year-grid{grid-template-columns:repeat(4,1fr)}.form-group.calendar .datepicker-group .time-picker{display:flex;-webkit-user-select:none;user-select:none;align-items:center;justify-content:center}.form-group.calendar .datepicker-group .time-picker .ampm-toggle{gap:6px;display:flex;margin-left:1rem;flex-direction:column;justify-content:center}.form-group.calendar .datepicker-group .time-picker .ampm-toggle button{cursor:pointer;padding:3px 8px;font-size:.75rem;background:#fff;border:1px solid #cccccc}.form-group.calendar .datepicker-group .time-picker .ampm-toggle button.active{color:#fff;border-color:#37c0b3;background-color:#37c0b3}.form-group.calendar .datepicker-group .time-picker .time-select{display:flex;margin:0 .75rem;align-items:center;flex-direction:column}.form-group.calendar .datepicker-group .time-picker .time-select button{border:none;cursor:pointer;padding:4px 8px;background:transparent}.form-group.calendar .datepicker-group .time-picker .time-select button i{font-size:1rem}.form-group.calendar .datepicker-group .time-picker .time-select button:hover{background:#f0f0f0}.form-group.calendar .datepicker-group .time-picker .time-select .time-value{width:2rem;font-size:1rem;text-align:center;margin:2px 3px 4px}.form-group.calendar .datepicker-group .time-picker .time-separator{line-height:1;font-size:1rem}.form-group.calendar .clear{right:35px}.form-group.calendar.group-sm .clear{top:7px;right:35px}\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: ReactiveFormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FormsModule }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }] });
|
|
1461
1717
|
}
|
|
1462
1718
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: CalendarControl, decorators: [{
|
|
1463
1719
|
type: Component,
|
|
@@ -1472,7 +1728,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
1472
1728
|
useExisting: forwardRef(() => CalendarControl),
|
|
1473
1729
|
multi: true,
|
|
1474
1730
|
},
|
|
1475
|
-
], template: "<div class=\"form-group calendar\" [ngClass]=\"customClass\" [class.readonly]=\"readonly\" [class.disabled]=\"disabled\" #root\r\n (click)=\"openCalendar()\">\r\n <label class=\"inp-label\" [ngClass]=\"{'required' : required}\" *ngIf=\"title\">{{ title }}</label>\r\n <input type=\"text\" #inputEl [placeholder]=\"placeholder\" [formControl]=\"inputControl\" class=\"form-control\"\r\n [ngClass]=\"{ 'is-invalid': error }\" (blur)=\"onBlur()\" (focus)=\"onFocus()\" [readonly]=\"readonly\"\r\n (click)=\"openCalendar(); $event.stopPropagation()\" (keydown)=\"onInputKeydown($event)\" />\r\n\r\n <span class=\"focus-border\" *ngIf=\"deFocus\"></span>\r\n @if(!inputLoader) {\r\n <span class=\"calendar-icon\">\r\n <i class=\"he\" [ngClass]=\"!timeOnly ? 'he-calendar-blank' : 'he-clock'\"></i>\r\n </span>\r\n }\r\n\r\n @if(!inputLoader &&(selectedDate && !disabled && !readonly) && clearVal) {\r\n <label class=\"clear\" (click)=\"clearDate($event)\">\r\n <i class=\"he he-close\"></i>\r\n </label>\r\n }\r\n\r\n @if(inputLoader) {\r\n <label class=\"loader input-loader\"></label>\r\n }\r\n @if(error) {\r\n <div class=\"val-msg\">{{ errorMessage }}</div>\r\n }\r\n\r\n <div class=\"datepicker-group\" #datePicker *ngIf=\"isOpen\" (mousedown)=\"$event.preventDefault()\"\r\n (click)=\"$event.stopPropagation()\">\r\n\r\n <!-- time picker -->\r\n <ng-container *ngIf=\"timeOnly\">\r\n <div class=\"time-picker\">\r\n <div class=\"time-select\">\r\n <button (click)=\"incrementHour()\" [disabled]=\"!isIncrementHourValid()\"><i\r\n class=\"he he-chevron-up\"></i></button>\r\n <ng-container *ngIf=\"hourFormat === '12'; else show24\">\r\n <div class=\"time-value\">\r\n {{ ((selectedHour % 12) || 12) | number:'2.0' }}\r\n </div>\r\n </ng-container>\r\n <ng-template #show24>\r\n <div class=\"time-value\">\r\n {{ selectedHour | number:'2.0' }}\r\n </div>\r\n </ng-template>\r\n\r\n <button (click)=\"decrementHour()\" [disabled]=\"!isDecrementHourValid()\"><i\r\n class=\"he he-chevron-down\"></i></button>\r\n </div>\r\n <span class=\"time-separator\">:</span>\r\n <div class=\"time-select\">\r\n <button (click)=\"incrementMinute()\" [disabled]=\"!isIncrementMinuteValid()\"><i\r\n class=\"he he-chevron-up\"></i></button>\r\n <div class=\"time-value\">{{ selectedMinute | number:'2.0' }}</div>\r\n <button (click)=\"decrementMinute()\" [disabled]=\"!isDecrementMinuteValid()\"><i\r\n class=\"he he-chevron-down\"></i></button>\r\n </div>\r\n <div class=\"ampm-toggle\" *ngIf=\"hourFormat === '12'\">\r\n <button type=\"button\" [class.active]=\"meridian === 'AM'\" (click)=\"setMeridian('AM')\">AM</button>\r\n <button type=\"button\" [class.active]=\"meridian === 'PM'\" (click)=\"setMeridian('PM')\">PM</button>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- day view -->\r\n <ng-container *ngIf=\"!timeOnly && currentView === 'day'\">\r\n <div class=\"header\">\r\n <button class=\"calendar-arrow\" (click)=\"prevMonth()\"><i class=\"he he-chevron-left\"></i></button>\r\n <div class=\"title\" (click)=\"goToMonthView()\">\r\n <div>{{ displayMonthName }}</div>\r\n <div>{{ displayYear }}</div>\r\n </div>\r\n <button class=\"calendar-arrow\" (click)=\"nextMonth()\"><i class=\"he he-chevron-right\"></i></button>\r\n </div>\r\n <div class=\"week-header\">\r\n <div>Sun</div>\r\n <div>Mon</div>\r\n <div>Tue</div>\r\n <div>Wed</div>\r\n <div>Thu</div>\r\n <div>Fri</div>\r\n <div>Sat</div>\r\n </div>\r\n <div class=\"days-grid\" [class.week-mode]=\"selectionMode === 'week'\">\r\n <div class=\"day-cell\" *ngFor=\"let cell of daysInMonth; trackBy: trackByDate\" (click)=\"selectDay(cell)\"\r\n (mouseenter)=\"onDayHover(cell)\" (mouseleave)=\"onDayLeave()\"\r\n [class.other-month]=\"cell.otherMonth\"\r\n [class.disabled]=\"cell.disabled\"\r\n [class.selected]=\"cell.selected\"\r\n [class.week-hover]=\"isInHoverWeek(cell.date)\"\r\n [class.today]=\"cell.today\">\r\n {{ cell.day }}\r\n </div>\r\n </div>\r\n <ng-container *ngIf=\"showTime\">\r\n <div class=\"time-picker\">\r\n <div class=\"time-select\">\r\n <button type=\"button\" (click)=\"incrementHour()\" [disabled]=\"!isIncrementHourValid()\">\r\n <i class=\"he he-chevron-up\"></i>\r\n </button>\r\n <ng-container *ngIf=\"hourFormat === '12'; else show24\">\r\n <div class=\"time-value\">\r\n {{\r\n selectedHour % 12 === 0\r\n ? 12\r\n : selectedHour % 12\r\n | number:'2.0' }}\r\n </div>\r\n </ng-container>\r\n <ng-template #show24>\r\n <div class=\"time-value\">{{ selectedHour | number:'2.0' }}</div>\r\n </ng-template>\r\n <button type=\"button\" (click)=\"decrementHour()\" [disabled]=\"!isDecrementHourValid()\">\r\n <i class=\"he he-chevron-down\"></i>\r\n </button>\r\n </div>\r\n <span class=\"time-separator\">:</span>\r\n <div class=\"time-select\">\r\n <button type=\"button\" (click)=\"incrementMinute()\" [disabled]=\"!isIncrementMinuteValid()\">\r\n <i class=\"he he-chevron-up\"></i>\r\n </button>\r\n <div class=\"time-value\">\r\n {{ selectedMinute < 10 ? '0' +selectedMinute : selectedMinute }} </div>\r\n <button type=\"button\" (click)=\"decrementMinute()\" [disabled]=\"!isDecrementMinuteValid()\">\r\n <i class=\"he he-chevron-down\"></i>\r\n </button>\r\n </div>\r\n <div class=\"ampm-toggle\" *ngIf=\"hourFormat === '12'\">\r\n <button type=\"button\" [class.active]=\"meridian === 'AM'\" (click)=\"setMeridian('AM')\">AM</button>\r\n <button type=\"button\" [class.active]=\"meridian === 'PM'\" (click)=\"setMeridian('PM')\">PM</button>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- month view -->\r\n <ng-container *ngIf=\"!timeOnly && currentView === 'month'\">\r\n <div class=\"header\" *ngIf=\"viewMode !== 'month'\">\r\n <button class=\"calendar-arrow\" (click)=\"displayYear = displayYear - 1\"><i\r\n class=\"he he-chevron-left\"></i></button>\r\n <div class=\"title\" (click)=\"goToYearRangeView()\">{{ displayYear }}</div>\r\n <button class=\"calendar-arrow\" (click)=\"displayYear = displayYear + 1\"><i\r\n class=\"he he-chevron-right\"></i></button>\r\n </div>\r\n <div class=\"month-grid\">\r\n <div class=\"month-cell\" *ngFor=\"let m of months; index as i\" (click)=\"selectMonth(i)\"\r\n [class.selected]=\"isMonthSelected(i)\" [class.today]=\"isMonthCurrent(i)\">{{ m }}\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- year range view -->\r\n <ng-container *ngIf=\"!timeOnly && currentView === 'yearRange'\">\r\n <div class=\"header\">\r\n <button class=\"calendar-arrow\" (click)=\"prevYearRange()\"><i class=\"he he-chevron-left\"></i></button>\r\n <div class=\"title\">{{ yearRange[0] }} ~ {{ yearRange[yearRangeSize-1] }}</div>\r\n <button class=\"calendar-arrow\" (click)=\"nextYearRange()\"><i class=\"he he-chevron-right\"></i></button>\r\n </div>\r\n <div class=\"year-grid\">\r\n <div class=\"year-cell\" *ngFor=\"let y of yearRange\" (click)=\"selectYear(y)\"\r\n [class.selected]=\"isYearSelected(y)\" [class.today]=\"isYearCurrent(y)\">{{ y }}</div>\r\n </div>\r\n </ng-container>\r\n\r\n </div>\r\n</div>", styles: [".form-group.calendar{position:relative}.form-group.calendar .datepicker-group{left:0;width:100%;z-index:1000;padding:.5rem;color:#495057;min-width:240px;max-width:260px;border-radius:3px;background:#fff;box-shadow:0 2px 4px -1px #0003,0 4px 5px #00000024,0 1px 10px #0000001f}.form-group.calendar .datepicker-group .header{display:flex;font-weight:600;padding:5px;align-items:center;justify-content:space-between;border-bottom:1px solid #dee2e6}.form-group.calendar .datepicker-group .header .title{gap:8px;display:flex;font-size:15px;cursor:pointer;font-weight:600}.form-group.calendar .datepicker-group .header .calendar-arrow{width:28px;height:28px;border:none;line-height:1;cursor:pointer;background:none}.form-group.calendar .datepicker-group .header .calendar-arrow i{font-size:14px}.form-group.calendar .datepicker-group .header .calendar-arrow:hover{background:#f0f0f0}.form-group.calendar .datepicker-group .week-header{display:grid;padding:8px 0;font-size:13px;font-weight:700;text-align:center;grid-template-columns:repeat(7,1fr)}.form-group.calendar .datepicker-group .days-grid,.form-group.calendar .datepicker-group .month-grid,.form-group.calendar .datepicker-group .year-grid{gap:3px;padding:5px;display:grid;grid-template-columns:repeat(7,1fr)}.form-group.calendar .datepicker-group .days-grid .day-cell,.form-group.calendar .datepicker-group .days-grid .month-cell,.form-group.calendar .datepicker-group .days-grid .year-cell,.form-group.calendar .datepicker-group .month-grid .day-cell,.form-group.calendar .datepicker-group .month-grid .month-cell,.form-group.calendar .datepicker-group .month-grid .year-cell,.form-group.calendar .datepicker-group .year-grid .day-cell,.form-group.calendar .datepicker-group .year-grid .month-cell,.form-group.calendar .datepicker-group .year-grid .year-cell{display:flex;font-size:14px;cursor:pointer;align-items:center;justify-content:center}.form-group.calendar .datepicker-group .days-grid .day-cell.today,.form-group.calendar .datepicker-group .days-grid .month-cell.today,.form-group.calendar .datepicker-group .days-grid .year-cell.today,.form-group.calendar .datepicker-group .month-grid .day-cell.today,.form-group.calendar .datepicker-group .month-grid .month-cell.today,.form-group.calendar .datepicker-group .month-grid .year-cell.today,.form-group.calendar .datepicker-group .year-grid .day-cell.today,.form-group.calendar .datepicker-group .year-grid .month-cell.today,.form-group.calendar .datepicker-group .year-grid .year-cell.today{color:#37c0b3;font-weight:700;border:1px solid #37c0b3}.form-group.calendar .datepicker-group .days-grid .day-cell.selected,.form-group.calendar .datepicker-group .days-grid .day-cell:hover,.form-group.calendar .datepicker-group .days-grid .month-cell.selected,.form-group.calendar .datepicker-group .days-grid .month-cell:hover,.form-group.calendar .datepicker-group .days-grid .year-cell.selected,.form-group.calendar .datepicker-group .days-grid .year-cell:hover,.form-group.calendar .datepicker-group .month-grid .day-cell.selected,.form-group.calendar .datepicker-group .month-grid .day-cell:hover,.form-group.calendar .datepicker-group .month-grid .month-cell.selected,.form-group.calendar .datepicker-group .month-grid .month-cell:hover,.form-group.calendar .datepicker-group .month-grid .year-cell.selected,.form-group.calendar .datepicker-group .month-grid .year-cell:hover,.form-group.calendar .datepicker-group .year-grid .day-cell.selected,.form-group.calendar .datepicker-group .year-grid .day-cell:hover,.form-group.calendar .datepicker-group .year-grid .month-cell.selected,.form-group.calendar .datepicker-group .year-grid .month-cell:hover,.form-group.calendar .datepicker-group .year-grid .year-cell.selected,.form-group.calendar .datepicker-group .year-grid .year-cell:hover{color:#fff;background:#37c0b3}.form-group.calendar .datepicker-group .days-grid .day-cell.disabled,.form-group.calendar .datepicker-group .days-grid .month-cell.disabled,.form-group.calendar .datepicker-group .days-grid .year-cell.disabled,.form-group.calendar .datepicker-group .month-grid .day-cell.disabled,.form-group.calendar .datepicker-group .month-grid .month-cell.disabled,.form-group.calendar .datepicker-group .month-grid .year-cell.disabled,.form-group.calendar .datepicker-group .year-grid .day-cell.disabled,.form-group.calendar .datepicker-group .year-grid .month-cell.disabled,.form-group.calendar .datepicker-group .year-grid .year-cell.disabled{color:#e0e0e0;background:none;-webkit-user-select:none;user-select:none;cursor:not-allowed}.form-group.calendar .datepicker-group .days-grid .day-cell.disabled.today,.form-group.calendar .datepicker-group .days-grid .month-cell.disabled.today,.form-group.calendar .datepicker-group .days-grid .year-cell.disabled.today,.form-group.calendar .datepicker-group .month-grid .day-cell.disabled.today,.form-group.calendar .datepicker-group .month-grid .month-cell.disabled.today,.form-group.calendar .datepicker-group .month-grid .year-cell.disabled.today,.form-group.calendar .datepicker-group .year-grid .day-cell.disabled.today,.form-group.calendar .datepicker-group .year-grid .month-cell.disabled.today,.form-group.calendar .datepicker-group .year-grid .year-cell.disabled.today{color:#37c0b3}.form-group.calendar .datepicker-group .days-grid .day-cell.disabled.today:hover,.form-group.calendar .datepicker-group .days-grid .month-cell.disabled.today:hover,.form-group.calendar .datepicker-group .days-grid .year-cell.disabled.today:hover,.form-group.calendar .datepicker-group .month-grid .day-cell.disabled.today:hover,.form-group.calendar .datepicker-group .month-grid .month-cell.disabled.today:hover,.form-group.calendar .datepicker-group .month-grid .year-cell.disabled.today:hover,.form-group.calendar .datepicker-group .year-grid .day-cell.disabled.today:hover,.form-group.calendar .datepicker-group .year-grid .month-cell.disabled.today:hover,.form-group.calendar .datepicker-group .year-grid .year-cell.disabled.today:hover{color:#fff;background:#37c0b3}.form-group.calendar .datepicker-group .days-grid .day-cell.disabled:hover,.form-group.calendar .datepicker-group .days-grid .month-cell.disabled:hover,.form-group.calendar .datepicker-group .days-grid .year-cell.disabled:hover,.form-group.calendar .datepicker-group .month-grid .day-cell.disabled:hover,.form-group.calendar .datepicker-group .month-grid .month-cell.disabled:hover,.form-group.calendar .datepicker-group .month-grid .year-cell.disabled:hover,.form-group.calendar .datepicker-group .year-grid .day-cell.disabled:hover,.form-group.calendar .datepicker-group .year-grid .month-cell.disabled:hover,.form-group.calendar .datepicker-group .year-grid .year-cell.disabled:hover{color:#e0e0e0;background:transparent}.form-group.calendar .datepicker-group .days-grid .day-cell,.form-group.calendar .datepicker-group .month-grid .day-cell,.form-group.calendar .datepicker-group .year-grid .day-cell{padding:5px 2px;border-radius:50%}.form-group.calendar .datepicker-group .days-grid .day-cell.other-month:not(.selected):not(:hover),.form-group.calendar .datepicker-group .month-grid .day-cell.other-month:not(.selected):not(:hover),.form-group.calendar .datepicker-group .year-grid .day-cell.other-month:not(.selected):not(:hover){color:#c5c5c5}.form-group.calendar .datepicker-group .days-grid .month-cell,.form-group.calendar .datepicker-group .days-grid .year-cell,.form-group.calendar .datepicker-group .month-grid .month-cell,.form-group.calendar .datepicker-group .month-grid .year-cell,.form-group.calendar .datepicker-group .year-grid .month-cell,.form-group.calendar .datepicker-group .year-grid .year-cell{padding:8px 2px;border-radius:3px}.form-group.calendar .datepicker-group .days-grid.week-mode .day-cell{border-radius:4px}.form-group.calendar .datepicker-group .days-grid.week-mode .day-cell.week-hover:not(.selected){color:#0d6f7d;background:#e6f5f3}.form-group.calendar .datepicker-group .month-grid{grid-template-columns:repeat(3,1fr)}.form-group.calendar .datepicker-group .year-grid{grid-template-columns:repeat(4,1fr)}.form-group.calendar .datepicker-group .time-picker{display:flex;-webkit-user-select:none;user-select:none;align-items:center;justify-content:center}.form-group.calendar .datepicker-group .time-picker .ampm-toggle{gap:6px;display:flex;margin-left:1rem;flex-direction:column;justify-content:center}.form-group.calendar .datepicker-group .time-picker .ampm-toggle button{cursor:pointer;padding:3px 8px;font-size:.75rem;background:#fff;border:1px solid #cccccc}.form-group.calendar .datepicker-group .time-picker .ampm-toggle button.active{color:#fff;border-color:#37c0b3;background-color:#37c0b3}.form-group.calendar .datepicker-group .time-picker .time-select{display:flex;margin:0 .75rem;align-items:center;flex-direction:column}.form-group.calendar .datepicker-group .time-picker .time-select button{border:none;cursor:pointer;padding:4px 8px;background:transparent}.form-group.calendar .datepicker-group .time-picker .time-select button i{font-size:1rem}.form-group.calendar .datepicker-group .time-picker .time-select button:hover{background:#f0f0f0}.form-group.calendar .datepicker-group .time-picker .time-select .time-value{width:2rem;font-size:1rem;text-align:center;margin:2px 3px 4px}.form-group.calendar .datepicker-group .time-picker .time-separator{line-height:1;font-size:1rem}.form-group.calendar .clear{right:35px}.form-group.calendar.group-sm .clear{top:7px;right:35px}\n"] }]
|
|
1731
|
+
], template: "<div class=\"form-group calendar\" [ngClass]=\"customClass\" [class.readonly]=\"readonly\" [class.disabled]=\"disabled\" #root\r\n (click)=\"openCalendar()\">\r\n <label class=\"inp-label\" [ngClass]=\"{'required' : required}\" *ngIf=\"title\">{{ title }}</label>\r\n <input type=\"text\" #inputEl [placeholder]=\"placeholder\" [formControl]=\"inputControl\" class=\"form-control\"\r\n [ngClass]=\"{ 'is-invalid': error }\" (blur)=\"onBlur()\" (focus)=\"onFocus()\" [readonly]=\"readonly\"\r\n (click)=\"openCalendar(); $event.stopPropagation()\" (keydown)=\"onInputKeydown($event)\" />\r\n\r\n <span class=\"focus-border\" *ngIf=\"deFocus\"></span>\r\n @if(!inputLoader) {\r\n <span class=\"calendar-icon\">\r\n <i class=\"he\" [ngClass]=\"!timeOnly ? 'he-calendar-blank' : 'he-clock'\"></i>\r\n </span>\r\n }\r\n\r\n @if(!inputLoader &&(selectedDate && !disabled && !readonly) && clearVal) {\r\n <label class=\"clear\" (click)=\"clearDate($event)\">\r\n <i class=\"he he-close\"></i>\r\n </label>\r\n }\r\n\r\n @if(inputLoader) {\r\n <label class=\"loader input-loader\"></label>\r\n }\r\n @if(error) {\r\n <div class=\"val-msg\">{{ errorMessage }}</div>\r\n }\r\n\r\n <div class=\"datepicker-group\" #datePicker *ngIf=\"isOpen\" (mousedown)=\"$event.preventDefault()\"\r\n (click)=\"$event.stopPropagation()\">\r\n\r\n <!-- time picker -->\r\n <ng-container *ngIf=\"timeOnly\">\r\n <div class=\"time-picker\">\r\n <div class=\"time-select\">\r\n <button (click)=\"incrementHour()\" [disabled]=\"!isIncrementHourValid()\"><i\r\n class=\"he he-chevron-up\"></i></button>\r\n <ng-container *ngIf=\"hourFormat === '12'; else show24\">\r\n <div class=\"time-value\">\r\n {{ ((selectedHour % 12) || 12) | number:'2.0' }}\r\n </div>\r\n </ng-container>\r\n <ng-template #show24>\r\n <div class=\"time-value\">\r\n {{ selectedHour | number:'2.0' }}\r\n </div>\r\n </ng-template>\r\n\r\n <button (click)=\"decrementHour()\" [disabled]=\"!isDecrementHourValid()\"><i\r\n class=\"he he-chevron-down\"></i></button>\r\n </div>\r\n <span class=\"time-separator\">:</span>\r\n <div class=\"time-select\">\r\n <button (click)=\"incrementMinute()\" [disabled]=\"!isIncrementMinuteValid()\"><i\r\n class=\"he he-chevron-up\"></i></button>\r\n <div class=\"time-value\">{{ selectedMinute | number:'2.0' }}</div>\r\n <button (click)=\"decrementMinute()\" [disabled]=\"!isDecrementMinuteValid()\"><i\r\n class=\"he he-chevron-down\"></i></button>\r\n </div>\r\n <div class=\"ampm-toggle\" *ngIf=\"hourFormat === '12'\">\r\n <button type=\"button\" [class.active]=\"meridian === 'AM'\" (click)=\"setMeridian('AM')\">AM</button>\r\n <button type=\"button\" [class.active]=\"meridian === 'PM'\" (click)=\"setMeridian('PM')\">PM</button>\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- day view -->\r\n <ng-container *ngIf=\"!timeOnly && currentView === 'day'\">\r\n <div class=\"header\">\r\n <button class=\"calendar-arrow\" (click)=\"prevMonth()\"><i class=\"he he-chevron-left\"></i></button>\r\n <div class=\"title\" (click)=\"goToMonthView()\">\r\n <div>{{ displayMonthName }}</div>\r\n <div>{{ displayYear }}</div>\r\n </div>\r\n <button class=\"calendar-arrow\" (click)=\"nextMonth()\"><i class=\"he he-chevron-right\"></i></button>\r\n </div>\r\n <div class=\"week-header\">\r\n <div>Sun</div>\r\n <div>Mon</div>\r\n <div>Tue</div>\r\n <div>Wed</div>\r\n <div>Thu</div>\r\n <div>Fri</div>\r\n <div>Sat</div>\r\n </div>\r\n <div class=\"days-grid\" [class.week-mode]=\"selectionMode === 'week'\"\r\n [class.range-mode]=\"selectionMode === 'range'\" (mouseleave)=\"onDayLeave()\">\r\n <div class=\"day-cell\" *ngFor=\"let cell of daysInMonth; trackBy: trackByDate\" (click)=\"selectDay(cell)\"\r\n (mouseenter)=\"onDayHover(cell)\" (mouseleave)=\"onDayLeave()\"\r\n [class.other-month]=\"cell.otherMonth\"\r\n [class.disabled]=\"cell.disabled\"\r\n [class.selected]=\"cell.selected\"\r\n [class.week-hover]=\"isInHoverWeek(cell.date)\"\r\n [class.range-start]=\"isRangeStart(cell.date)\"\r\n [class.range-end]=\"isRangeEnd(cell.date)\"\r\n [class.in-range]=\"isInSelectedRange(cell.date)\"\r\n [class.range-hover]=\"isInHoverRange(cell.date)\"\r\n [class.today]=\"cell.today\">\r\n {{ cell.day }}\r\n </div>\r\n </div>\r\n <ng-container *ngIf=\"showTime\">\r\n <div class=\"time-picker\">\r\n <div class=\"time-select\">\r\n <button type=\"button\" (click)=\"incrementHour()\" [disabled]=\"!isIncrementHourValid()\">\r\n <i class=\"he he-chevron-up\"></i>\r\n </button>\r\n <ng-container *ngIf=\"hourFormat === '12'; else show24\">\r\n <div class=\"time-value\">\r\n {{\r\n selectedHour % 12 === 0\r\n ? 12\r\n : selectedHour % 12\r\n | number:'2.0' }}\r\n </div>\r\n </ng-container>\r\n <ng-template #show24>\r\n <div class=\"time-value\">{{ selectedHour | number:'2.0' }}</div>\r\n </ng-template>\r\n <button type=\"button\" (click)=\"decrementHour()\" [disabled]=\"!isDecrementHourValid()\">\r\n <i class=\"he he-chevron-down\"></i>\r\n </button>\r\n </div>\r\n <span class=\"time-separator\">:</span>\r\n <div class=\"time-select\">\r\n <button type=\"button\" (click)=\"incrementMinute()\" [disabled]=\"!isIncrementMinuteValid()\">\r\n <i class=\"he he-chevron-up\"></i>\r\n </button>\r\n <div class=\"time-value\">\r\n {{ selectedMinute < 10 ? '0' +selectedMinute : selectedMinute }} </div>\r\n <button type=\"button\" (click)=\"decrementMinute()\" [disabled]=\"!isDecrementMinuteValid()\">\r\n <i class=\"he he-chevron-down\"></i>\r\n </button>\r\n </div>\r\n <div class=\"ampm-toggle\" *ngIf=\"hourFormat === '12'\">\r\n <button type=\"button\" [class.active]=\"meridian === 'AM'\" (click)=\"setMeridian('AM')\">AM</button>\r\n <button type=\"button\" [class.active]=\"meridian === 'PM'\" (click)=\"setMeridian('PM')\">PM</button>\r\n </div>\r\n </div>\r\n </ng-container>\r\n </ng-container>\r\n\r\n <!-- month view -->\r\n <ng-container *ngIf=\"!timeOnly && currentView === 'month'\">\r\n <div class=\"header\" *ngIf=\"viewMode !== 'month'\">\r\n <button class=\"calendar-arrow\" (click)=\"displayYear = displayYear - 1\"><i\r\n class=\"he he-chevron-left\"></i></button>\r\n <div class=\"title\" (click)=\"goToYearRangeView()\">{{ displayYear }}</div>\r\n <button class=\"calendar-arrow\" (click)=\"displayYear = displayYear + 1\"><i\r\n class=\"he he-chevron-right\"></i></button>\r\n </div>\r\n <div class=\"month-grid\">\r\n <div class=\"month-cell\" *ngFor=\"let m of months; index as i\" (click)=\"selectMonth(i)\"\r\n [class.selected]=\"isMonthSelected(i)\" [class.today]=\"isMonthCurrent(i)\">{{ m }}\r\n </div>\r\n </div>\r\n </ng-container>\r\n\r\n <!-- year range view -->\r\n <ng-container *ngIf=\"!timeOnly && currentView === 'yearRange'\">\r\n <div class=\"header\">\r\n <button class=\"calendar-arrow\" (click)=\"prevYearRange()\"><i class=\"he he-chevron-left\"></i></button>\r\n <div class=\"title\">{{ yearRange[0] }} ~ {{ yearRange[yearRangeSize-1] }}</div>\r\n <button class=\"calendar-arrow\" (click)=\"nextYearRange()\"><i class=\"he he-chevron-right\"></i></button>\r\n </div>\r\n <div class=\"year-grid\">\r\n <div class=\"year-cell\" *ngFor=\"let y of yearRange\" (click)=\"selectYear(y)\"\r\n [class.selected]=\"isYearSelected(y)\" [class.today]=\"isYearCurrent(y)\">{{ y }}</div>\r\n </div>\r\n </ng-container>\r\n\r\n </div>\r\n</div>", styles: [".form-group.calendar{position:relative}.form-group.calendar .datepicker-group{left:0;width:100%;z-index:1000;padding:.5rem;color:#495057;min-width:240px;max-width:260px;border-radius:3px;background:#fff;box-shadow:0 2px 4px -1px #0003,0 4px 5px #00000024,0 1px 10px #0000001f}.form-group.calendar .datepicker-group .header{display:flex;font-weight:600;padding:5px;align-items:center;justify-content:space-between;border-bottom:1px solid #dee2e6}.form-group.calendar .datepicker-group .header .title{gap:8px;display:flex;font-size:15px;cursor:pointer;font-weight:600}.form-group.calendar .datepicker-group .header .calendar-arrow{width:28px;height:28px;border:none;line-height:1;cursor:pointer;background:none}.form-group.calendar .datepicker-group .header .calendar-arrow i{font-size:14px}.form-group.calendar .datepicker-group .header .calendar-arrow:hover{background:#f0f0f0}.form-group.calendar .datepicker-group .week-header{display:grid;padding:8px 0;font-size:13px;font-weight:700;text-align:center;grid-template-columns:repeat(7,1fr)}.form-group.calendar .datepicker-group .days-grid,.form-group.calendar .datepicker-group .month-grid,.form-group.calendar .datepicker-group .year-grid{gap:3px;padding:5px;display:grid;grid-template-columns:repeat(7,1fr)}.form-group.calendar .datepicker-group .days-grid .day-cell,.form-group.calendar .datepicker-group .days-grid .month-cell,.form-group.calendar .datepicker-group .days-grid .year-cell,.form-group.calendar .datepicker-group .month-grid .day-cell,.form-group.calendar .datepicker-group .month-grid .month-cell,.form-group.calendar .datepicker-group .month-grid .year-cell,.form-group.calendar .datepicker-group .year-grid .day-cell,.form-group.calendar .datepicker-group .year-grid .month-cell,.form-group.calendar .datepicker-group .year-grid .year-cell{display:flex;font-size:14px;cursor:pointer;align-items:center;justify-content:center}.form-group.calendar .datepicker-group .days-grid .day-cell.today,.form-group.calendar .datepicker-group .days-grid .month-cell.today,.form-group.calendar .datepicker-group .days-grid .year-cell.today,.form-group.calendar .datepicker-group .month-grid .day-cell.today,.form-group.calendar .datepicker-group .month-grid .month-cell.today,.form-group.calendar .datepicker-group .month-grid .year-cell.today,.form-group.calendar .datepicker-group .year-grid .day-cell.today,.form-group.calendar .datepicker-group .year-grid .month-cell.today,.form-group.calendar .datepicker-group .year-grid .year-cell.today{color:#37c0b3;font-weight:700;border:1px solid #37c0b3}.form-group.calendar .datepicker-group .days-grid .day-cell.selected,.form-group.calendar .datepicker-group .days-grid .day-cell:hover,.form-group.calendar .datepicker-group .days-grid .month-cell.selected,.form-group.calendar .datepicker-group .days-grid .month-cell:hover,.form-group.calendar .datepicker-group .days-grid .year-cell.selected,.form-group.calendar .datepicker-group .days-grid .year-cell:hover,.form-group.calendar .datepicker-group .month-grid .day-cell.selected,.form-group.calendar .datepicker-group .month-grid .day-cell:hover,.form-group.calendar .datepicker-group .month-grid .month-cell.selected,.form-group.calendar .datepicker-group .month-grid .month-cell:hover,.form-group.calendar .datepicker-group .month-grid .year-cell.selected,.form-group.calendar .datepicker-group .month-grid .year-cell:hover,.form-group.calendar .datepicker-group .year-grid .day-cell.selected,.form-group.calendar .datepicker-group .year-grid .day-cell:hover,.form-group.calendar .datepicker-group .year-grid .month-cell.selected,.form-group.calendar .datepicker-group .year-grid .month-cell:hover,.form-group.calendar .datepicker-group .year-grid .year-cell.selected,.form-group.calendar .datepicker-group .year-grid .year-cell:hover{color:#fff;background:#37c0b3}.form-group.calendar .datepicker-group .days-grid .day-cell.disabled,.form-group.calendar .datepicker-group .days-grid .month-cell.disabled,.form-group.calendar .datepicker-group .days-grid .year-cell.disabled,.form-group.calendar .datepicker-group .month-grid .day-cell.disabled,.form-group.calendar .datepicker-group .month-grid .month-cell.disabled,.form-group.calendar .datepicker-group .month-grid .year-cell.disabled,.form-group.calendar .datepicker-group .year-grid .day-cell.disabled,.form-group.calendar .datepicker-group .year-grid .month-cell.disabled,.form-group.calendar .datepicker-group .year-grid .year-cell.disabled{color:#e0e0e0;background:none;-webkit-user-select:none;user-select:none;cursor:not-allowed}.form-group.calendar .datepicker-group .days-grid .day-cell.disabled.today,.form-group.calendar .datepicker-group .days-grid .month-cell.disabled.today,.form-group.calendar .datepicker-group .days-grid .year-cell.disabled.today,.form-group.calendar .datepicker-group .month-grid .day-cell.disabled.today,.form-group.calendar .datepicker-group .month-grid .month-cell.disabled.today,.form-group.calendar .datepicker-group .month-grid .year-cell.disabled.today,.form-group.calendar .datepicker-group .year-grid .day-cell.disabled.today,.form-group.calendar .datepicker-group .year-grid .month-cell.disabled.today,.form-group.calendar .datepicker-group .year-grid .year-cell.disabled.today{color:#37c0b3}.form-group.calendar .datepicker-group .days-grid .day-cell.disabled.today:hover,.form-group.calendar .datepicker-group .days-grid .month-cell.disabled.today:hover,.form-group.calendar .datepicker-group .days-grid .year-cell.disabled.today:hover,.form-group.calendar .datepicker-group .month-grid .day-cell.disabled.today:hover,.form-group.calendar .datepicker-group .month-grid .month-cell.disabled.today:hover,.form-group.calendar .datepicker-group .month-grid .year-cell.disabled.today:hover,.form-group.calendar .datepicker-group .year-grid .day-cell.disabled.today:hover,.form-group.calendar .datepicker-group .year-grid .month-cell.disabled.today:hover,.form-group.calendar .datepicker-group .year-grid .year-cell.disabled.today:hover{color:#fff;background:#37c0b3}.form-group.calendar .datepicker-group .days-grid .day-cell.disabled:hover,.form-group.calendar .datepicker-group .days-grid .month-cell.disabled:hover,.form-group.calendar .datepicker-group .days-grid .year-cell.disabled:hover,.form-group.calendar .datepicker-group .month-grid .day-cell.disabled:hover,.form-group.calendar .datepicker-group .month-grid .month-cell.disabled:hover,.form-group.calendar .datepicker-group .month-grid .year-cell.disabled:hover,.form-group.calendar .datepicker-group .year-grid .day-cell.disabled:hover,.form-group.calendar .datepicker-group .year-grid .month-cell.disabled:hover,.form-group.calendar .datepicker-group .year-grid .year-cell.disabled:hover{color:#e0e0e0;background:transparent}.form-group.calendar .datepicker-group .days-grid .day-cell,.form-group.calendar .datepicker-group .month-grid .day-cell,.form-group.calendar .datepicker-group .year-grid .day-cell{padding:5px 2px;border-radius:50%}.form-group.calendar .datepicker-group .days-grid .day-cell.other-month:not(.selected):not(:hover),.form-group.calendar .datepicker-group .month-grid .day-cell.other-month:not(.selected):not(:hover),.form-group.calendar .datepicker-group .year-grid .day-cell.other-month:not(.selected):not(:hover){color:#c5c5c5}.form-group.calendar .datepicker-group .days-grid .month-cell,.form-group.calendar .datepicker-group .days-grid .year-cell,.form-group.calendar .datepicker-group .month-grid .month-cell,.form-group.calendar .datepicker-group .month-grid .year-cell,.form-group.calendar .datepicker-group .year-grid .month-cell,.form-group.calendar .datepicker-group .year-grid .year-cell{padding:8px 2px;border-radius:3px}.form-group.calendar .datepicker-group .days-grid.week-mode .day-cell{border-radius:4px}.form-group.calendar .datepicker-group .days-grid.week-mode .day-cell.week-hover:not(.selected){color:#0d6f7d;background:#e6f5f3}.form-group.calendar .datepicker-group .days-grid.range-mode .day-cell{border-radius:4px}.form-group.calendar .datepicker-group .days-grid.range-mode .day-cell.in-range:not(.range-start):not(.range-end),.form-group.calendar .datepicker-group .days-grid.range-mode .day-cell.range-hover:not(.range-start):not(.range-end){color:#0d6f7d;background:#e6f5f3;border-radius:0}.form-group.calendar .datepicker-group .days-grid.range-mode .day-cell.other-month.in-range:not(.range-start):not(.range-end),.form-group.calendar .datepicker-group .days-grid.range-mode .day-cell.other-month.range-hover:not(.range-start):not(.range-end){color:#0d6f7d}.form-group.calendar .datepicker-group .days-grid.range-mode .day-cell.range-start,.form-group.calendar .datepicker-group .days-grid.range-mode .day-cell.range-end,.form-group.calendar .datepicker-group .days-grid.range-mode .day-cell.selected{color:#fff;background:#37c0b3}.form-group.calendar .datepicker-group .days-grid.range-mode .day-cell.range-start:not(.range-end){border-radius:4px 0 0 4px}.form-group.calendar .datepicker-group .days-grid.range-mode .day-cell.range-end:not(.range-start){border-radius:0 4px 4px 0}.form-group.calendar .datepicker-group .days-grid.range-mode .day-cell:hover:not(.disabled):not(.range-start):not(.range-end){color:#0d6f7d;background:#e6f5f3}.form-group.calendar .datepicker-group .month-grid{grid-template-columns:repeat(3,1fr)}.form-group.calendar .datepicker-group .year-grid{grid-template-columns:repeat(4,1fr)}.form-group.calendar .datepicker-group .time-picker{display:flex;-webkit-user-select:none;user-select:none;align-items:center;justify-content:center}.form-group.calendar .datepicker-group .time-picker .ampm-toggle{gap:6px;display:flex;margin-left:1rem;flex-direction:column;justify-content:center}.form-group.calendar .datepicker-group .time-picker .ampm-toggle button{cursor:pointer;padding:3px 8px;font-size:.75rem;background:#fff;border:1px solid #cccccc}.form-group.calendar .datepicker-group .time-picker .ampm-toggle button.active{color:#fff;border-color:#37c0b3;background-color:#37c0b3}.form-group.calendar .datepicker-group .time-picker .time-select{display:flex;margin:0 .75rem;align-items:center;flex-direction:column}.form-group.calendar .datepicker-group .time-picker .time-select button{border:none;cursor:pointer;padding:4px 8px;background:transparent}.form-group.calendar .datepicker-group .time-picker .time-select button i{font-size:1rem}.form-group.calendar .datepicker-group .time-picker .time-select button:hover{background:#f0f0f0}.form-group.calendar .datepicker-group .time-picker .time-select .time-value{width:2rem;font-size:1rem;text-align:center;margin:2px 3px 4px}.form-group.calendar .datepicker-group .time-picker .time-separator{line-height:1;font-size:1rem}.form-group.calendar .clear{right:35px}.form-group.calendar.group-sm .clear{top:7px;right:35px}\n"] }]
|
|
1476
1732
|
}], ctorParameters: () => [{ type: i1.DatePipe }], propDecorators: { title: [{
|
|
1477
1733
|
type: Input
|
|
1478
1734
|
}], required: [{
|
|
@@ -1520,6 +1776,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
1520
1776
|
type: Output
|
|
1521
1777
|
}], weekSelected: [{
|
|
1522
1778
|
type: Output
|
|
1779
|
+
}], rangeSelected: [{
|
|
1780
|
+
type: Output
|
|
1523
1781
|
}], defaultDate: [{
|
|
1524
1782
|
type: Input
|
|
1525
1783
|
}], minDate: [{
|
|
@@ -3974,6 +4232,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
3974
4232
|
args: ['switchContainer']
|
|
3975
4233
|
}] } });
|
|
3976
4234
|
|
|
4235
|
+
const RICH_TEXT_EDITOR_DEFAULT_FEATURES = {
|
|
4236
|
+
bold: true,
|
|
4237
|
+
italic: true,
|
|
4238
|
+
underline: true,
|
|
4239
|
+
h1: true,
|
|
4240
|
+
h2: true,
|
|
4241
|
+
textColor: true,
|
|
4242
|
+
backgroundColor: true,
|
|
4243
|
+
alignLeft: true,
|
|
4244
|
+
alignCenter: true,
|
|
4245
|
+
alignRight: true,
|
|
4246
|
+
justify: true,
|
|
4247
|
+
indent: true,
|
|
4248
|
+
outdent: true,
|
|
4249
|
+
unorderedList: true,
|
|
4250
|
+
orderedList: true,
|
|
4251
|
+
link: true,
|
|
4252
|
+
image: true,
|
|
4253
|
+
undo: true,
|
|
4254
|
+
redo: true,
|
|
4255
|
+
clearFormatting: true,
|
|
4256
|
+
};
|
|
4257
|
+
|
|
3977
4258
|
/**
|
|
3978
4259
|
* Lightweight rich-text editor built on a `contenteditable` element and the
|
|
3979
4260
|
* browser's `document.execCommand` rich-editing API (the de-facto standard for
|
|
@@ -3984,9 +4265,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
3984
4265
|
* inner HTML string.
|
|
3985
4266
|
*/
|
|
3986
4267
|
class RichTextEditor {
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
link = true;
|
|
4268
|
+
/** Per-item toolbar visibility. Omitted keys default to visible. */
|
|
4269
|
+
features = {};
|
|
3990
4270
|
placeholder = 'Type here...';
|
|
3991
4271
|
readonly = false;
|
|
3992
4272
|
/** Disabled state, set by Reactive Forms through `setDisabledState`. */
|
|
@@ -4159,6 +4439,14 @@ class RichTextEditor {
|
|
|
4159
4439
|
trackByIndex(index) {
|
|
4160
4440
|
return index;
|
|
4161
4441
|
}
|
|
4442
|
+
/** Whether a toolbar item is visible (defaults to true when not configured). */
|
|
4443
|
+
isVisible(feature) {
|
|
4444
|
+
return this.features[feature] ?? RICH_TEXT_EDITOR_DEFAULT_FEATURES[feature];
|
|
4445
|
+
}
|
|
4446
|
+
/** Whether any of the given toolbar items are visible (for group separators). */
|
|
4447
|
+
hasAny(...features) {
|
|
4448
|
+
return features.some((feature) => this.isVisible(feature));
|
|
4449
|
+
}
|
|
4162
4450
|
// ---- Undo / redo / clear ----
|
|
4163
4451
|
undo() {
|
|
4164
4452
|
this.exec('undo');
|
|
@@ -4193,13 +4481,13 @@ class RichTextEditor {
|
|
|
4193
4481
|
selection.addRange(this.savedRange);
|
|
4194
4482
|
}
|
|
4195
4483
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: RichTextEditor, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4196
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.25", type: RichTextEditor, isStandalone: true, selector: "rich-text-editor", inputs: {
|
|
4484
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.25", type: RichTextEditor, isStandalone: true, selector: "rich-text-editor", inputs: { features: "features", placeholder: "placeholder", readonly: "readonly" }, host: { listeners: { "document:selectionchange": "saveSelection()", "document:mousedown": "onDocumentMouseDown($event)" } }, providers: [
|
|
4197
4485
|
{
|
|
4198
4486
|
provide: NG_VALUE_ACCESSOR,
|
|
4199
4487
|
useExisting: forwardRef(() => RichTextEditor),
|
|
4200
4488
|
multi: true,
|
|
4201
4489
|
},
|
|
4202
|
-
], viewQueries: [{ propertyName: "editorRef", first: true, predicate: ["editor"], descendants: true }], ngImport: i0, template: "<div class=\"text-editor\" [ngClass]=\"{'readonly': readonly || disabled}\">\n <div class=\"toolbar\" *ngIf=\"!readonly && !disabled\">\n <div class=\"toolbar-items\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyInlineStyle('bold')\" title=\"Bold\">\n <i class=\"he he-bold\"></i>\n </button>\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyInlineStyle('italic')\" title=\"Italic\">\n <i class=\"he he-italics\"></i>\n </button>\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyInlineStyle('underline')\" title=\"Underline\">\n <i class=\"he he-underline\"></i>\n </button>\n </div>\n <div class=\"toolbar-items\" *ngIf=\"header\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyBlockFormat('h1')\" title=\"Header 1\">\n <i class=\"he he-heading-1\"></i>\n </button>\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyBlockFormat('h2')\" title=\"Header 2\">\n <i class=\"he he-heading-2\"></i>\n </button>\n </div>\n <div class=\"toolbar-items more-gap\">\n <div class=\"color-tool\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"toggleColorMenu('text')\" title=\"Text Color\">\n <i class=\"he he-text-drop\"></i>\n </button>\n <div class=\"color-popover\" *ngIf=\"colorMenu === 'text'\">\n <div class=\"color-grid\">\n <button type=\"button\" class=\"color-swatch\" *ngFor=\"let c of palette\" [style.backgroundColor]=\"c\"\n [title]=\"c\" (mousedown)=\"$event.preventDefault()\" (click)=\"pickColor('text', c)\"></button>\n </div>\n <label class=\"color-custom\">\n <span>Custom</span>\n <input type=\"color\" (change)=\"pickCustomColor('text', $event)\" />\n </label>\n </div>\n </div>\n <div class=\"color-tool\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"toggleColorMenu('background')\" title=\"Background Color\">\n <i class=\"he he-background-drop\"></i>\n </button>\n <div class=\"color-popover\" *ngIf=\"colorMenu === 'background'\">\n <div class=\"color-grid\">\n <button type=\"button\" class=\"color-swatch\" *ngFor=\"let c of palette\" [style.backgroundColor]=\"c\"\n [title]=\"c\" (mousedown)=\"$event.preventDefault()\" (click)=\"pickColor('background', c)\"></button>\n </div>\n <label class=\"color-custom\">\n <span>Custom</span>\n <input type=\"color\" (change)=\"pickCustomColor('background', $event)\" />\n </label>\n </div>\n </div>\n </div>\n <div class=\"toolbar-items\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"setAlignment('left')\" title=\"Justify Left\">\n <i class=\"he he-left-align\"></i>\n </button>\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"setAlignment('center')\" title=\"Justify Center\">\n <i class=\"he he-center-align\"></i>\n </button>\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"setAlignment('right')\" title=\"Justify Right\">\n <i class=\"he he-right-align\"></i>\n </button>\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"setAlignment('justify')\" title=\"Justify Full\">\n <i class=\"he he-justify\"></i>\n </button>\n </div>\n <div class=\"toolbar-items\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"indent()\" title=\"Indent\">\n <i class=\"he he-text-indent-left\"></i>\n </button>\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"outdent()\" title=\"Outdent\">\n <i class=\"he he-text-indent-right\"></i>\n </button>\n </div>\n <div class=\"toolbar-items\" *ngIf=\"media\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyList('ul')\" title=\"Unordered list\">\n <i class=\"he he-unordered-list\"></i>\n </button>\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyList('ol')\" title=\"Ordered list\">\n <i class=\"he he-ordered-list\"></i>\n </button>\n </div>\n <div class=\"toolbar-items\" *ngIf=\"link\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"createLink()\" title=\"Link\">\n <i class=\"he he-link\"></i>\n </button>\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"insertImage()\" title=\"Image\">\n <i class=\"he he-image\"></i>\n </button>\n </div>\n <div class=\"toolbar-items\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"undo()\" title=\"Undo\">\n <i class=\"he he-undo\"></i>\n </button>\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"redo()\" title=\"Redo\">\n <i class=\"he he-redo\"></i>\n </button>\n </div>\n <div class=\"toolbar-items\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"clearFormatting()\" title=\"Clear Formatting\">\n <i class=\"he he-text-clear-format\"></i>\n </button>\n </div>\n </div>\n\n <div #editor class=\"editor-content\" [attr.contenteditable]=\"(readonly || disabled) ? 'false' : 'true'\" (input)=\"onInput()\" (blur)=\"onTouched()\"\n [attr.data-placeholder]=\"placeholder\">\n </div>\n\n <!-- Custom Modal for Link/Image URL -->\n <div class=\"editor-modal-overlay\" *ngIf=\"showModal\" (click)=\"cancelModal()\">\n <div class=\"editor-modal\" (click)=\"$event.stopPropagation()\">\n <div class=\"editor-modal-header\">\n <span>{{ modalType === 'link' ? 'Insert Link' : 'Insert Image' }}</span>\n <button type=\"button\" class=\"editor-modal-close\" (click)=\"cancelModal()\">\n <i class=\"he he-close\"></i>\n </button>\n </div>\n <div class=\"editor-modal-body\">\n <div class=\"url-list\">\n <div class=\"url-row\" *ngFor=\"let url of modalUrls; let i = index; trackBy: trackByIndex\">\n <div class=\"url-field\">\n <input type=\"text\" class=\"url-input\" [class.invalid]=\"isRowInvalid(modalUrls[i])\"\n [ngModel]=\"modalUrls[i]\"\n (ngModelChange)=\"modalUrls[i] = $event\"\n [placeholder]=\"modalType === 'link' ? 'https://example.com' : 'https://example.com/image.png'\" />\n <span class=\"url-error\" *ngIf=\"isRowInvalid(modalUrls[i])\">Enter a valid URL</span>\n </div>\n <button type=\"button\" class=\"url-remove-btn\" *ngIf=\"modalUrls.length > 1\" (click)=\"removeUrlRow(i)\" title=\"Remove\">\n <i class=\"he he-close\"></i>\n </button>\n </div>\n </div>\n <button type=\"button\" class=\"url-add-btn\" (click)=\"addUrlRow()\">\n + Add more\n </button>\n </div>\n <div class=\"editor-modal-footer\">\n <button type=\"button\" class=\"modal-btn cancel-btn\" (click)=\"cancelModal()\">Cancel</button>\n <button type=\"button\" class=\"modal-btn confirm-btn\" [disabled]=\"!hasValidUrl\" (click)=\"confirmModal()\">Insert</button>\n </div>\n </div>\n </div>\n</div>\n", styles: [".text-editor{border:1px solid #ccc}.text-editor .toolbar{gap:.75rem;display:flex;flex-wrap:wrap;background:#f8f8f8;padding:.75rem;border-bottom:1px solid #cccccc}.text-editor .toolbar .toolbar-items{height:18px;display:flex;flex-wrap:wrap;align-items:center;padding-right:.75rem;border-right:1px solid #969090}.text-editor .toolbar .toolbar-items button{cursor:pointer;min-width:25px;min-height:20px;border:0;display:grid;place-items:center;background:transparent}.text-editor .toolbar .toolbar-items button:hover{background:#eee}.text-editor .toolbar .toolbar-items button:hover i{color:#000}.text-editor .toolbar .toolbar-items .color-tool{position:relative}.text-editor .toolbar .toolbar-items i{font-size:13px;color:#3c4148}.text-editor .toolbar .toolbar-items i.he-bold{font-weight:600}.text-editor .toolbar .toolbar-items i.he-underline{font-size:14px}.text-editor .toolbar .toolbar-items i.he-text-drop{font-size:12px}.text-editor .toolbar .toolbar-items i.he-background-drop{top:-1px;font-size:12px}.text-editor .toolbar .toolbar-items i.he-heading-1,.text-editor .toolbar .toolbar-items i.he-link,.text-editor .toolbar .toolbar-items i.he-left-align,.text-editor .toolbar .toolbar-items i.he-center-align,.text-editor .toolbar .toolbar-items i.he-right-align,.text-editor .toolbar .toolbar-items i.he-justify{font-size:16px}.text-editor .toolbar .toolbar-items i.he-text-indent-left,.text-editor .toolbar .toolbar-items i.he-text-indent-right{font-size:17px}.text-editor .toolbar .toolbar-items i.he-heading-2{top:1px;font-size:16px}.text-editor .toolbar .toolbar-items i.he-unordered-list,.text-editor .toolbar .toolbar-items i.he-ordered-list{top:-1px;font-size:20px}.text-editor .toolbar .toolbar-items i.he-image{font-size:15px;font-weight:600}.text-editor .toolbar .toolbar-items i.he-redo,.text-editor .toolbar .toolbar-items i.he-undo{top:-1px;font-size:14px}.text-editor .toolbar .toolbar-items.more-gap{gap:5px}.text-editor .toolbar .toolbar-items:last-child{border-right:0}.text-editor .color-popover{top:calc(100% + 6px);left:0;z-index:30;padding:8px;position:absolute;background:#fff;border-radius:6px;border:1px solid #e0e0e0;box-shadow:0 4px 16px #00000026}.text-editor .color-popover .color-grid{gap:4px;display:grid;grid-template-columns:repeat(8,18px)}.text-editor .color-popover .color-swatch{width:18px;height:18px;padding:0;cursor:pointer;border-radius:3px;border:1px solid rgba(0,0,0,.15);transition:transform .1s ease}.text-editor .color-popover .color-swatch:hover{transform:scale(1.15)}.text-editor .color-popover .color-custom{gap:8px;display:flex;margin-top:8px;font-size:12px;color:#555;cursor:pointer;align-items:center;justify-content:space-between}.text-editor .color-popover .color-custom input[type=color]{width:28px;height:20px;padding:0;cursor:pointer;background:none;border:1px solid #cccccc}.text-editor .editor-content{outline:none;min-height:200px;position:relative;background:#fff;padding:.75rem}.text-editor .editor-content[data-placeholder]:empty:before{content:attr(data-placeholder);color:#aaa;pointer-events:none;position:absolute;left:.75rem;top:.75rem}.text-editor .editor-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:#00000073;display:flex;align-items:center;justify-content:center;z-index:10000}.text-editor .editor-modal{background:#fff;border-radius:8px;box-shadow:0 8px 32px #0003;width:420px;max-width:90vw;animation:modalFadeIn .2s ease}@keyframes modalFadeIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.text-editor .editor-modal-header{display:flex;align-items:center;justify-content:space-between;padding:14px 18px;border-bottom:1px solid #e8e8e8}.text-editor .editor-modal-header span{font-size:15px;font-weight:600;color:#1a1a1a}.text-editor .editor-modal-close{background:none;border:none;cursor:pointer;padding:4px;border-radius:4px;display:grid;place-items:center}.text-editor .editor-modal-close i{font-size:14px;color:#666}.text-editor .editor-modal-close:hover{background:#f0f0f0}.text-editor .editor-modal-close:hover i{color:#333}.text-editor .editor-modal-body{padding:16px 18px}.text-editor .editor-modal-body .url-list{max-height:200px;overflow-y:auto;margin-bottom:10px;padding-right:2px}.text-editor .editor-modal-body .url-row{display:flex;align-items:flex-start;gap:8px;margin-bottom:10px}.text-editor .editor-modal-body .url-field{flex:1;display:flex;flex-direction:column;gap:2px}.text-editor .editor-modal-body .url-input{width:100%;padding:8px 12px;border:1px solid #d0d0d0;border-radius:6px;font-size:13px;color:#333;outline:none;transition:border-color .2s}.text-editor .editor-modal-body .url-input:focus{border-color:#007bff;box-shadow:0 0 0 2px #007bff26}.text-editor .editor-modal-body .url-input::placeholder{color:#aaa}.text-editor .editor-modal-body .url-input.invalid{border-color:#e04040}.text-editor .editor-modal-body .url-input.invalid:focus{border-color:#e04040;box-shadow:0 0 0 2px #e0404026}.text-editor .editor-modal-body .url-error{font-size:11px;color:#e04040}.text-editor .editor-modal-body .url-remove-btn{background:none;border:1px solid #e0e0e0;border-radius:6px;cursor:pointer;padding:8px 9px;display:grid;place-items:center;transition:all .15s}.text-editor .editor-modal-body .url-remove-btn i{font-size:11px;color:#999}.text-editor .editor-modal-body .url-remove-btn:hover{background:#fff0f0;border-color:#faa}.text-editor .editor-modal-body .url-remove-btn:hover i{color:#e04040}.text-editor .editor-modal-body .url-add-btn{background:none;border:1px dashed #c0c0c0;border-radius:6px;cursor:pointer;padding:6px 14px;font-size:12px;color:#007bff;transition:all .15s;width:100%}.text-editor .editor-modal-body .url-add-btn:hover{background:#f0f8ff;border-color:#007bff}.text-editor .editor-modal-footer{display:flex;justify-content:flex-end;gap:10px;padding:12px 18px;border-top:1px solid #e8e8e8}.text-editor .editor-modal-footer .modal-btn{padding:7px 20px;border-radius:6px;font-size:13px;font-weight:500;cursor:pointer;transition:all .15s;border:1px solid transparent}.text-editor .editor-modal-footer .cancel-btn{background:#f5f5f5;color:#555;border-color:#ddd}.text-editor .editor-modal-footer .cancel-btn:hover{background:#eaeaea}.text-editor .editor-modal-footer .confirm-btn{background:#007bff;color:#fff}.text-editor .editor-modal-footer .confirm-btn:hover{background:#0069d9}.text-editor .editor-modal-footer .confirm-btn:disabled{opacity:.5;cursor:not-allowed}.text-editor .editor-modal-footer .confirm-btn:disabled:hover{background:#007bff}\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: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
|
|
4490
|
+
], viewQueries: [{ propertyName: "editorRef", first: true, predicate: ["editor"], descendants: true }], ngImport: i0, template: "<div class=\"text-editor\" [ngClass]=\"{'readonly': readonly || disabled}\">\n <div class=\"toolbar\" *ngIf=\"!readonly && !disabled\">\n <div class=\"toolbar-items\" *ngIf=\"hasAny('bold', 'italic', 'underline')\">\n <button type=\"button\" *ngIf=\"isVisible('bold')\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyInlineStyle('bold')\" title=\"Bold\">\n <i class=\"he he-bold\"></i>\n </button>\n <button type=\"button\" *ngIf=\"isVisible('italic')\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyInlineStyle('italic')\" title=\"Italic\">\n <i class=\"he he-italics\"></i>\n </button>\n <button type=\"button\" *ngIf=\"isVisible('underline')\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyInlineStyle('underline')\" title=\"Underline\">\n <i class=\"he he-underline\"></i>\n </button>\n </div>\n <div class=\"toolbar-items\" *ngIf=\"hasAny('h1', 'h2')\">\n <button type=\"button\" *ngIf=\"isVisible('h1')\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyBlockFormat('h1')\" title=\"Header 1\">\n <i class=\"he he-heading-1\"></i>\n </button>\n <button type=\"button\" *ngIf=\"isVisible('h2')\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyBlockFormat('h2')\" title=\"Header 2\">\n <i class=\"he he-heading-2\"></i>\n </button>\n </div>\n <div class=\"toolbar-items more-gap\" *ngIf=\"hasAny('textColor', 'backgroundColor')\">\n <div class=\"color-tool\" *ngIf=\"isVisible('textColor')\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"toggleColorMenu('text')\" title=\"Text Color\">\n <i class=\"he he-text-drop\"></i>\n </button>\n <div class=\"color-popover\" *ngIf=\"colorMenu === 'text'\">\n <div class=\"color-grid\">\n <button type=\"button\" class=\"color-swatch\" *ngFor=\"let c of palette\" [style.backgroundColor]=\"c\"\n [title]=\"c\" (mousedown)=\"$event.preventDefault()\" (click)=\"pickColor('text', c)\"></button>\n </div>\n <label class=\"color-custom\">\n <span>Custom</span>\n <input type=\"color\" (change)=\"pickCustomColor('text', $event)\" />\n </label>\n </div>\n </div>\n <div class=\"color-tool\" *ngIf=\"isVisible('backgroundColor')\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"toggleColorMenu('background')\" title=\"Background Color\">\n <i class=\"he he-background-drop\"></i>\n </button>\n <div class=\"color-popover\" *ngIf=\"colorMenu === 'background'\">\n <div class=\"color-grid\">\n <button type=\"button\" class=\"color-swatch\" *ngFor=\"let c of palette\" [style.backgroundColor]=\"c\"\n [title]=\"c\" (mousedown)=\"$event.preventDefault()\" (click)=\"pickColor('background', c)\"></button>\n </div>\n <label class=\"color-custom\">\n <span>Custom</span>\n <input type=\"color\" (change)=\"pickCustomColor('background', $event)\" />\n </label>\n </div>\n </div>\n </div>\n <div class=\"toolbar-items\" *ngIf=\"hasAny('alignLeft', 'alignCenter', 'alignRight', 'justify')\">\n <button type=\"button\" *ngIf=\"isVisible('alignLeft')\" (mousedown)=\"$event.preventDefault()\" (click)=\"setAlignment('left')\" title=\"Justify Left\">\n <i class=\"he he-left-align\"></i>\n </button>\n <button type=\"button\" *ngIf=\"isVisible('alignCenter')\" (mousedown)=\"$event.preventDefault()\" (click)=\"setAlignment('center')\" title=\"Justify Center\">\n <i class=\"he he-center-align\"></i>\n </button>\n <button type=\"button\" *ngIf=\"isVisible('alignRight')\" (mousedown)=\"$event.preventDefault()\" (click)=\"setAlignment('right')\" title=\"Justify Right\">\n <i class=\"he he-right-align\"></i>\n </button>\n <button type=\"button\" *ngIf=\"isVisible('justify')\" (mousedown)=\"$event.preventDefault()\" (click)=\"setAlignment('justify')\" title=\"Justify Full\">\n <i class=\"he he-justify\"></i>\n </button>\n </div>\n <div class=\"toolbar-items\" *ngIf=\"hasAny('indent', 'outdent')\">\n <button type=\"button\" *ngIf=\"isVisible('indent')\" (mousedown)=\"$event.preventDefault()\" (click)=\"indent()\" title=\"Indent\">\n <i class=\"he he-text-indent-left\"></i>\n </button>\n <button type=\"button\" *ngIf=\"isVisible('outdent')\" (mousedown)=\"$event.preventDefault()\" (click)=\"outdent()\" title=\"Outdent\">\n <i class=\"he he-text-indent-right\"></i>\n </button>\n </div>\n <div class=\"toolbar-items\" *ngIf=\"hasAny('unorderedList', 'orderedList')\">\n <button type=\"button\" *ngIf=\"isVisible('unorderedList')\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyList('ul')\" title=\"Unordered list\">\n <i class=\"he he-unordered-list\"></i>\n </button>\n <button type=\"button\" *ngIf=\"isVisible('orderedList')\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyList('ol')\" title=\"Ordered list\">\n <i class=\"he he-ordered-list\"></i>\n </button>\n </div>\n <div class=\"toolbar-items\" *ngIf=\"hasAny('link', 'image')\">\n <button type=\"button\" *ngIf=\"isVisible('link')\" (mousedown)=\"$event.preventDefault()\" (click)=\"createLink()\" title=\"Link\">\n <i class=\"he he-link\"></i>\n </button>\n <button type=\"button\" *ngIf=\"isVisible('image')\" (mousedown)=\"$event.preventDefault()\" (click)=\"insertImage()\" title=\"Image\">\n <i class=\"he he-image\"></i>\n </button>\n </div>\n <div class=\"toolbar-items\" *ngIf=\"hasAny('undo', 'redo')\">\n <button type=\"button\" *ngIf=\"isVisible('undo')\" (mousedown)=\"$event.preventDefault()\" (click)=\"undo()\" title=\"Undo\">\n <i class=\"he he-undo\"></i>\n </button>\n <button type=\"button\" *ngIf=\"isVisible('redo')\" (mousedown)=\"$event.preventDefault()\" (click)=\"redo()\" title=\"Redo\">\n <i class=\"he he-redo\"></i>\n </button>\n </div>\n <div class=\"toolbar-items\" *ngIf=\"isVisible('clearFormatting')\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"clearFormatting()\" title=\"Clear Formatting\">\n <i class=\"he he-text-clear-format\"></i>\n </button>\n </div>\n </div>\n\n <div #editor class=\"editor-content\" [attr.contenteditable]=\"(readonly || disabled) ? 'false' : 'true'\" (input)=\"onInput()\" (blur)=\"onTouched()\"\n [attr.data-placeholder]=\"placeholder\">\n </div>\n\n <!-- Custom Modal for Link/Image URL -->\n <div class=\"editor-modal-overlay\" *ngIf=\"showModal\" (click)=\"cancelModal()\">\n <div class=\"editor-modal\" (click)=\"$event.stopPropagation()\">\n <div class=\"editor-modal-header\">\n <span>{{ modalType === 'link' ? 'Insert Link' : 'Insert Image' }}</span>\n <button type=\"button\" class=\"editor-modal-close\" (click)=\"cancelModal()\">\n <i class=\"he he-close\"></i>\n </button>\n </div>\n <div class=\"editor-modal-body\">\n <div class=\"url-list\">\n <div class=\"url-row\" *ngFor=\"let url of modalUrls; let i = index; trackBy: trackByIndex\">\n <div class=\"url-field\">\n <input type=\"text\" class=\"url-input\" [class.invalid]=\"isRowInvalid(modalUrls[i])\"\n [ngModel]=\"modalUrls[i]\"\n (ngModelChange)=\"modalUrls[i] = $event\"\n [placeholder]=\"modalType === 'link' ? 'https://example.com' : 'https://example.com/image.png'\" />\n <span class=\"url-error\" *ngIf=\"isRowInvalid(modalUrls[i])\">Enter a valid URL</span>\n </div>\n <button type=\"button\" class=\"url-remove-btn\" *ngIf=\"modalUrls.length > 1\" (click)=\"removeUrlRow(i)\" title=\"Remove\">\n <i class=\"he he-close\"></i>\n </button>\n </div>\n </div>\n <button type=\"button\" class=\"url-add-btn\" (click)=\"addUrlRow()\">\n + Add more\n </button>\n </div>\n <div class=\"editor-modal-footer\">\n <button type=\"button\" class=\"modal-btn cancel-btn\" (click)=\"cancelModal()\">Cancel</button>\n <button type=\"button\" class=\"modal-btn confirm-btn\" [disabled]=\"!hasValidUrl\" (click)=\"confirmModal()\">Insert</button>\n </div>\n </div>\n </div>\n</div>\n", styles: [".text-editor{border:1px solid #ccc}.text-editor .toolbar{gap:.75rem;display:flex;flex-wrap:wrap;background:#f8f8f8;padding:.75rem;border-bottom:1px solid #cccccc}.text-editor .toolbar .toolbar-items{height:18px;display:flex;flex-wrap:wrap;align-items:center;padding-right:.75rem;border-right:1px solid #969090}.text-editor .toolbar .toolbar-items button{cursor:pointer;min-width:25px;min-height:20px;border:0;display:grid;place-items:center;background:transparent}.text-editor .toolbar .toolbar-items button:hover{background:#eee}.text-editor .toolbar .toolbar-items button:hover i{color:#000}.text-editor .toolbar .toolbar-items .color-tool{position:relative}.text-editor .toolbar .toolbar-items i{font-size:13px;color:#3c4148}.text-editor .toolbar .toolbar-items i.he-bold{font-weight:600}.text-editor .toolbar .toolbar-items i.he-underline{font-size:14px}.text-editor .toolbar .toolbar-items i.he-text-drop{font-size:12px}.text-editor .toolbar .toolbar-items i.he-background-drop{top:-1px;font-size:12px}.text-editor .toolbar .toolbar-items i.he-heading-1,.text-editor .toolbar .toolbar-items i.he-link,.text-editor .toolbar .toolbar-items i.he-left-align,.text-editor .toolbar .toolbar-items i.he-center-align,.text-editor .toolbar .toolbar-items i.he-right-align,.text-editor .toolbar .toolbar-items i.he-justify{font-size:16px}.text-editor .toolbar .toolbar-items i.he-text-indent-left,.text-editor .toolbar .toolbar-items i.he-text-indent-right{font-size:17px}.text-editor .toolbar .toolbar-items i.he-heading-2{top:1px;font-size:16px}.text-editor .toolbar .toolbar-items i.he-unordered-list,.text-editor .toolbar .toolbar-items i.he-ordered-list{top:-1px;font-size:20px}.text-editor .toolbar .toolbar-items i.he-image{font-size:15px;font-weight:600}.text-editor .toolbar .toolbar-items i.he-redo,.text-editor .toolbar .toolbar-items i.he-undo{top:-1px;font-size:14px}.text-editor .toolbar .toolbar-items.more-gap{gap:5px}.text-editor .toolbar .toolbar-items:last-child{border-right:0}.text-editor .color-popover{top:calc(100% + 6px);left:0;z-index:30;padding:8px;position:absolute;background:#fff;border-radius:6px;border:1px solid #e0e0e0;box-shadow:0 4px 16px #00000026}.text-editor .color-popover .color-grid{gap:4px;display:grid;grid-template-columns:repeat(8,18px)}.text-editor .color-popover .color-swatch{width:18px;height:18px;padding:0;cursor:pointer;border-radius:3px;border:1px solid rgba(0,0,0,.15);transition:transform .1s ease}.text-editor .color-popover .color-swatch:hover{transform:scale(1.15)}.text-editor .color-popover .color-custom{gap:8px;display:flex;margin-top:8px;font-size:12px;color:#555;cursor:pointer;align-items:center;justify-content:space-between}.text-editor .color-popover .color-custom input[type=color]{width:28px;height:20px;padding:0;cursor:pointer;background:none;border:1px solid #cccccc}.text-editor .editor-content{outline:none;min-height:200px;position:relative;background:#fff;padding:.75rem}.text-editor .editor-content[data-placeholder]:empty:before{content:attr(data-placeholder);color:#aaa;pointer-events:none;position:absolute;left:.75rem;top:.75rem}.text-editor .editor-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:#00000073;display:flex;align-items:center;justify-content:center;z-index:10000}.text-editor .editor-modal{background:#fff;border-radius:8px;box-shadow:0 8px 32px #0003;width:420px;max-width:90vw;animation:modalFadeIn .2s ease}@keyframes modalFadeIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.text-editor .editor-modal-header{display:flex;align-items:center;justify-content:space-between;padding:14px 18px;border-bottom:1px solid #e8e8e8}.text-editor .editor-modal-header span{font-size:15px;font-weight:600;color:#1a1a1a}.text-editor .editor-modal-close{background:none;border:none;cursor:pointer;padding:4px;border-radius:4px;display:grid;place-items:center}.text-editor .editor-modal-close i{font-size:14px;color:#666}.text-editor .editor-modal-close:hover{background:#f0f0f0}.text-editor .editor-modal-close:hover i{color:#333}.text-editor .editor-modal-body{padding:16px 18px}.text-editor .editor-modal-body .url-list{max-height:200px;overflow-y:auto;margin-bottom:10px;padding-right:2px}.text-editor .editor-modal-body .url-row{display:flex;align-items:flex-start;gap:8px;margin-bottom:10px}.text-editor .editor-modal-body .url-field{flex:1;display:flex;flex-direction:column;gap:2px}.text-editor .editor-modal-body .url-input{width:100%;padding:8px 12px;border:1px solid #d0d0d0;border-radius:6px;font-size:13px;color:#333;outline:none;transition:border-color .2s}.text-editor .editor-modal-body .url-input:focus{border-color:#007bff;box-shadow:0 0 0 2px #007bff26}.text-editor .editor-modal-body .url-input::placeholder{color:#aaa}.text-editor .editor-modal-body .url-input.invalid{border-color:#e04040}.text-editor .editor-modal-body .url-input.invalid:focus{border-color:#e04040;box-shadow:0 0 0 2px #e0404026}.text-editor .editor-modal-body .url-error{font-size:11px;color:#e04040}.text-editor .editor-modal-body .url-remove-btn{background:none;border:1px solid #e0e0e0;border-radius:6px;cursor:pointer;padding:8px 9px;display:grid;place-items:center;transition:all .15s}.text-editor .editor-modal-body .url-remove-btn i{font-size:11px;color:#999}.text-editor .editor-modal-body .url-remove-btn:hover{background:#fff0f0;border-color:#faa}.text-editor .editor-modal-body .url-remove-btn:hover i{color:#e04040}.text-editor .editor-modal-body .url-add-btn{background:none;border:1px dashed #c0c0c0;border-radius:6px;cursor:pointer;padding:6px 14px;font-size:12px;color:#007bff;transition:all .15s;width:100%}.text-editor .editor-modal-body .url-add-btn:hover{background:#f0f8ff;border-color:#007bff}.text-editor .editor-modal-footer{display:flex;justify-content:flex-end;gap:10px;padding:12px 18px;border-top:1px solid #e8e8e8}.text-editor .editor-modal-footer .modal-btn{padding:7px 20px;border-radius:6px;font-size:13px;font-weight:500;cursor:pointer;transition:all .15s;border:1px solid transparent}.text-editor .editor-modal-footer .cancel-btn{background:#f5f5f5;color:#555;border-color:#ddd}.text-editor .editor-modal-footer .cancel-btn:hover{background:#eaeaea}.text-editor .editor-modal-footer .confirm-btn{background:#007bff;color:#fff}.text-editor .editor-modal-footer .confirm-btn:hover{background:#0069d9}.text-editor .editor-modal-footer .confirm-btn:disabled{opacity:.5;cursor:not-allowed}.text-editor .editor-modal-footer .confirm-btn:disabled:hover{background:#007bff}\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: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
|
|
4203
4491
|
}
|
|
4204
4492
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: RichTextEditor, decorators: [{
|
|
4205
4493
|
type: Component,
|
|
@@ -4209,12 +4497,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
4209
4497
|
useExisting: forwardRef(() => RichTextEditor),
|
|
4210
4498
|
multi: true,
|
|
4211
4499
|
},
|
|
4212
|
-
], template: "<div class=\"text-editor\" [ngClass]=\"{'readonly': readonly || disabled}\">\n <div class=\"toolbar\" *ngIf=\"!readonly && !disabled\">\n <div class=\"toolbar-items\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyInlineStyle('bold')\" title=\"Bold\">\n <i class=\"he he-bold\"></i>\n </button>\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyInlineStyle('italic')\" title=\"Italic\">\n <i class=\"he he-italics\"></i>\n </button>\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyInlineStyle('underline')\" title=\"Underline\">\n <i class=\"he he-underline\"></i>\n </button>\n </div>\n <div class=\"toolbar-items\" *ngIf=\"header\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyBlockFormat('h1')\" title=\"Header 1\">\n <i class=\"he he-heading-1\"></i>\n </button>\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyBlockFormat('h2')\" title=\"Header 2\">\n <i class=\"he he-heading-2\"></i>\n </button>\n </div>\n <div class=\"toolbar-items more-gap\">\n <div class=\"color-tool\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"toggleColorMenu('text')\" title=\"Text Color\">\n <i class=\"he he-text-drop\"></i>\n </button>\n <div class=\"color-popover\" *ngIf=\"colorMenu === 'text'\">\n <div class=\"color-grid\">\n <button type=\"button\" class=\"color-swatch\" *ngFor=\"let c of palette\" [style.backgroundColor]=\"c\"\n [title]=\"c\" (mousedown)=\"$event.preventDefault()\" (click)=\"pickColor('text', c)\"></button>\n </div>\n <label class=\"color-custom\">\n <span>Custom</span>\n <input type=\"color\" (change)=\"pickCustomColor('text', $event)\" />\n </label>\n </div>\n </div>\n <div class=\"color-tool\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"toggleColorMenu('background')\" title=\"Background Color\">\n <i class=\"he he-background-drop\"></i>\n </button>\n <div class=\"color-popover\" *ngIf=\"colorMenu === 'background'\">\n <div class=\"color-grid\">\n <button type=\"button\" class=\"color-swatch\" *ngFor=\"let c of palette\" [style.backgroundColor]=\"c\"\n [title]=\"c\" (mousedown)=\"$event.preventDefault()\" (click)=\"pickColor('background', c)\"></button>\n </div>\n <label class=\"color-custom\">\n <span>Custom</span>\n <input type=\"color\" (change)=\"pickCustomColor('background', $event)\" />\n </label>\n </div>\n </div>\n </div>\n <div class=\"toolbar-items\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"setAlignment('left')\" title=\"Justify Left\">\n <i class=\"he he-left-align\"></i>\n </button>\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"setAlignment('center')\" title=\"Justify Center\">\n <i class=\"he he-center-align\"></i>\n </button>\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"setAlignment('right')\" title=\"Justify Right\">\n <i class=\"he he-right-align\"></i>\n </button>\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"setAlignment('justify')\" title=\"Justify Full\">\n <i class=\"he he-justify\"></i>\n </button>\n </div>\n <div class=\"toolbar-items\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"indent()\" title=\"Indent\">\n <i class=\"he he-text-indent-left\"></i>\n </button>\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"outdent()\" title=\"Outdent\">\n <i class=\"he he-text-indent-right\"></i>\n </button>\n </div>\n <div class=\"toolbar-items\" *ngIf=\"media\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyList('ul')\" title=\"Unordered list\">\n <i class=\"he he-unordered-list\"></i>\n </button>\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyList('ol')\" title=\"Ordered list\">\n <i class=\"he he-ordered-list\"></i>\n </button>\n </div>\n <div class=\"toolbar-items\" *ngIf=\"link\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"createLink()\" title=\"Link\">\n <i class=\"he he-link\"></i>\n </button>\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"insertImage()\" title=\"Image\">\n <i class=\"he he-image\"></i>\n </button>\n </div>\n <div class=\"toolbar-items\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"undo()\" title=\"Undo\">\n <i class=\"he he-undo\"></i>\n </button>\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"redo()\" title=\"Redo\">\n <i class=\"he he-redo\"></i>\n </button>\n </div>\n <div class=\"toolbar-items\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"clearFormatting()\" title=\"Clear Formatting\">\n <i class=\"he he-text-clear-format\"></i>\n </button>\n </div>\n </div>\n\n <div #editor class=\"editor-content\" [attr.contenteditable]=\"(readonly || disabled) ? 'false' : 'true'\" (input)=\"onInput()\" (blur)=\"onTouched()\"\n [attr.data-placeholder]=\"placeholder\">\n </div>\n\n <!-- Custom Modal for Link/Image URL -->\n <div class=\"editor-modal-overlay\" *ngIf=\"showModal\" (click)=\"cancelModal()\">\n <div class=\"editor-modal\" (click)=\"$event.stopPropagation()\">\n <div class=\"editor-modal-header\">\n <span>{{ modalType === 'link' ? 'Insert Link' : 'Insert Image' }}</span>\n <button type=\"button\" class=\"editor-modal-close\" (click)=\"cancelModal()\">\n <i class=\"he he-close\"></i>\n </button>\n </div>\n <div class=\"editor-modal-body\">\n <div class=\"url-list\">\n <div class=\"url-row\" *ngFor=\"let url of modalUrls; let i = index; trackBy: trackByIndex\">\n <div class=\"url-field\">\n <input type=\"text\" class=\"url-input\" [class.invalid]=\"isRowInvalid(modalUrls[i])\"\n [ngModel]=\"modalUrls[i]\"\n (ngModelChange)=\"modalUrls[i] = $event\"\n [placeholder]=\"modalType === 'link' ? 'https://example.com' : 'https://example.com/image.png'\" />\n <span class=\"url-error\" *ngIf=\"isRowInvalid(modalUrls[i])\">Enter a valid URL</span>\n </div>\n <button type=\"button\" class=\"url-remove-btn\" *ngIf=\"modalUrls.length > 1\" (click)=\"removeUrlRow(i)\" title=\"Remove\">\n <i class=\"he he-close\"></i>\n </button>\n </div>\n </div>\n <button type=\"button\" class=\"url-add-btn\" (click)=\"addUrlRow()\">\n + Add more\n </button>\n </div>\n <div class=\"editor-modal-footer\">\n <button type=\"button\" class=\"modal-btn cancel-btn\" (click)=\"cancelModal()\">Cancel</button>\n <button type=\"button\" class=\"modal-btn confirm-btn\" [disabled]=\"!hasValidUrl\" (click)=\"confirmModal()\">Insert</button>\n </div>\n </div>\n </div>\n</div>\n", styles: [".text-editor{border:1px solid #ccc}.text-editor .toolbar{gap:.75rem;display:flex;flex-wrap:wrap;background:#f8f8f8;padding:.75rem;border-bottom:1px solid #cccccc}.text-editor .toolbar .toolbar-items{height:18px;display:flex;flex-wrap:wrap;align-items:center;padding-right:.75rem;border-right:1px solid #969090}.text-editor .toolbar .toolbar-items button{cursor:pointer;min-width:25px;min-height:20px;border:0;display:grid;place-items:center;background:transparent}.text-editor .toolbar .toolbar-items button:hover{background:#eee}.text-editor .toolbar .toolbar-items button:hover i{color:#000}.text-editor .toolbar .toolbar-items .color-tool{position:relative}.text-editor .toolbar .toolbar-items i{font-size:13px;color:#3c4148}.text-editor .toolbar .toolbar-items i.he-bold{font-weight:600}.text-editor .toolbar .toolbar-items i.he-underline{font-size:14px}.text-editor .toolbar .toolbar-items i.he-text-drop{font-size:12px}.text-editor .toolbar .toolbar-items i.he-background-drop{top:-1px;font-size:12px}.text-editor .toolbar .toolbar-items i.he-heading-1,.text-editor .toolbar .toolbar-items i.he-link,.text-editor .toolbar .toolbar-items i.he-left-align,.text-editor .toolbar .toolbar-items i.he-center-align,.text-editor .toolbar .toolbar-items i.he-right-align,.text-editor .toolbar .toolbar-items i.he-justify{font-size:16px}.text-editor .toolbar .toolbar-items i.he-text-indent-left,.text-editor .toolbar .toolbar-items i.he-text-indent-right{font-size:17px}.text-editor .toolbar .toolbar-items i.he-heading-2{top:1px;font-size:16px}.text-editor .toolbar .toolbar-items i.he-unordered-list,.text-editor .toolbar .toolbar-items i.he-ordered-list{top:-1px;font-size:20px}.text-editor .toolbar .toolbar-items i.he-image{font-size:15px;font-weight:600}.text-editor .toolbar .toolbar-items i.he-redo,.text-editor .toolbar .toolbar-items i.he-undo{top:-1px;font-size:14px}.text-editor .toolbar .toolbar-items.more-gap{gap:5px}.text-editor .toolbar .toolbar-items:last-child{border-right:0}.text-editor .color-popover{top:calc(100% + 6px);left:0;z-index:30;padding:8px;position:absolute;background:#fff;border-radius:6px;border:1px solid #e0e0e0;box-shadow:0 4px 16px #00000026}.text-editor .color-popover .color-grid{gap:4px;display:grid;grid-template-columns:repeat(8,18px)}.text-editor .color-popover .color-swatch{width:18px;height:18px;padding:0;cursor:pointer;border-radius:3px;border:1px solid rgba(0,0,0,.15);transition:transform .1s ease}.text-editor .color-popover .color-swatch:hover{transform:scale(1.15)}.text-editor .color-popover .color-custom{gap:8px;display:flex;margin-top:8px;font-size:12px;color:#555;cursor:pointer;align-items:center;justify-content:space-between}.text-editor .color-popover .color-custom input[type=color]{width:28px;height:20px;padding:0;cursor:pointer;background:none;border:1px solid #cccccc}.text-editor .editor-content{outline:none;min-height:200px;position:relative;background:#fff;padding:.75rem}.text-editor .editor-content[data-placeholder]:empty:before{content:attr(data-placeholder);color:#aaa;pointer-events:none;position:absolute;left:.75rem;top:.75rem}.text-editor .editor-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:#00000073;display:flex;align-items:center;justify-content:center;z-index:10000}.text-editor .editor-modal{background:#fff;border-radius:8px;box-shadow:0 8px 32px #0003;width:420px;max-width:90vw;animation:modalFadeIn .2s ease}@keyframes modalFadeIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.text-editor .editor-modal-header{display:flex;align-items:center;justify-content:space-between;padding:14px 18px;border-bottom:1px solid #e8e8e8}.text-editor .editor-modal-header span{font-size:15px;font-weight:600;color:#1a1a1a}.text-editor .editor-modal-close{background:none;border:none;cursor:pointer;padding:4px;border-radius:4px;display:grid;place-items:center}.text-editor .editor-modal-close i{font-size:14px;color:#666}.text-editor .editor-modal-close:hover{background:#f0f0f0}.text-editor .editor-modal-close:hover i{color:#333}.text-editor .editor-modal-body{padding:16px 18px}.text-editor .editor-modal-body .url-list{max-height:200px;overflow-y:auto;margin-bottom:10px;padding-right:2px}.text-editor .editor-modal-body .url-row{display:flex;align-items:flex-start;gap:8px;margin-bottom:10px}.text-editor .editor-modal-body .url-field{flex:1;display:flex;flex-direction:column;gap:2px}.text-editor .editor-modal-body .url-input{width:100%;padding:8px 12px;border:1px solid #d0d0d0;border-radius:6px;font-size:13px;color:#333;outline:none;transition:border-color .2s}.text-editor .editor-modal-body .url-input:focus{border-color:#007bff;box-shadow:0 0 0 2px #007bff26}.text-editor .editor-modal-body .url-input::placeholder{color:#aaa}.text-editor .editor-modal-body .url-input.invalid{border-color:#e04040}.text-editor .editor-modal-body .url-input.invalid:focus{border-color:#e04040;box-shadow:0 0 0 2px #e0404026}.text-editor .editor-modal-body .url-error{font-size:11px;color:#e04040}.text-editor .editor-modal-body .url-remove-btn{background:none;border:1px solid #e0e0e0;border-radius:6px;cursor:pointer;padding:8px 9px;display:grid;place-items:center;transition:all .15s}.text-editor .editor-modal-body .url-remove-btn i{font-size:11px;color:#999}.text-editor .editor-modal-body .url-remove-btn:hover{background:#fff0f0;border-color:#faa}.text-editor .editor-modal-body .url-remove-btn:hover i{color:#e04040}.text-editor .editor-modal-body .url-add-btn{background:none;border:1px dashed #c0c0c0;border-radius:6px;cursor:pointer;padding:6px 14px;font-size:12px;color:#007bff;transition:all .15s;width:100%}.text-editor .editor-modal-body .url-add-btn:hover{background:#f0f8ff;border-color:#007bff}.text-editor .editor-modal-footer{display:flex;justify-content:flex-end;gap:10px;padding:12px 18px;border-top:1px solid #e8e8e8}.text-editor .editor-modal-footer .modal-btn{padding:7px 20px;border-radius:6px;font-size:13px;font-weight:500;cursor:pointer;transition:all .15s;border:1px solid transparent}.text-editor .editor-modal-footer .cancel-btn{background:#f5f5f5;color:#555;border-color:#ddd}.text-editor .editor-modal-footer .cancel-btn:hover{background:#eaeaea}.text-editor .editor-modal-footer .confirm-btn{background:#007bff;color:#fff}.text-editor .editor-modal-footer .confirm-btn:hover{background:#0069d9}.text-editor .editor-modal-footer .confirm-btn:disabled{opacity:.5;cursor:not-allowed}.text-editor .editor-modal-footer .confirm-btn:disabled:hover{background:#007bff}\n"] }]
|
|
4213
|
-
}], propDecorators: {
|
|
4214
|
-
type: Input
|
|
4215
|
-
}], media: [{
|
|
4216
|
-
type: Input
|
|
4217
|
-
}], link: [{
|
|
4500
|
+
], template: "<div class=\"text-editor\" [ngClass]=\"{'readonly': readonly || disabled}\">\n <div class=\"toolbar\" *ngIf=\"!readonly && !disabled\">\n <div class=\"toolbar-items\" *ngIf=\"hasAny('bold', 'italic', 'underline')\">\n <button type=\"button\" *ngIf=\"isVisible('bold')\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyInlineStyle('bold')\" title=\"Bold\">\n <i class=\"he he-bold\"></i>\n </button>\n <button type=\"button\" *ngIf=\"isVisible('italic')\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyInlineStyle('italic')\" title=\"Italic\">\n <i class=\"he he-italics\"></i>\n </button>\n <button type=\"button\" *ngIf=\"isVisible('underline')\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyInlineStyle('underline')\" title=\"Underline\">\n <i class=\"he he-underline\"></i>\n </button>\n </div>\n <div class=\"toolbar-items\" *ngIf=\"hasAny('h1', 'h2')\">\n <button type=\"button\" *ngIf=\"isVisible('h1')\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyBlockFormat('h1')\" title=\"Header 1\">\n <i class=\"he he-heading-1\"></i>\n </button>\n <button type=\"button\" *ngIf=\"isVisible('h2')\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyBlockFormat('h2')\" title=\"Header 2\">\n <i class=\"he he-heading-2\"></i>\n </button>\n </div>\n <div class=\"toolbar-items more-gap\" *ngIf=\"hasAny('textColor', 'backgroundColor')\">\n <div class=\"color-tool\" *ngIf=\"isVisible('textColor')\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"toggleColorMenu('text')\" title=\"Text Color\">\n <i class=\"he he-text-drop\"></i>\n </button>\n <div class=\"color-popover\" *ngIf=\"colorMenu === 'text'\">\n <div class=\"color-grid\">\n <button type=\"button\" class=\"color-swatch\" *ngFor=\"let c of palette\" [style.backgroundColor]=\"c\"\n [title]=\"c\" (mousedown)=\"$event.preventDefault()\" (click)=\"pickColor('text', c)\"></button>\n </div>\n <label class=\"color-custom\">\n <span>Custom</span>\n <input type=\"color\" (change)=\"pickCustomColor('text', $event)\" />\n </label>\n </div>\n </div>\n <div class=\"color-tool\" *ngIf=\"isVisible('backgroundColor')\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"toggleColorMenu('background')\" title=\"Background Color\">\n <i class=\"he he-background-drop\"></i>\n </button>\n <div class=\"color-popover\" *ngIf=\"colorMenu === 'background'\">\n <div class=\"color-grid\">\n <button type=\"button\" class=\"color-swatch\" *ngFor=\"let c of palette\" [style.backgroundColor]=\"c\"\n [title]=\"c\" (mousedown)=\"$event.preventDefault()\" (click)=\"pickColor('background', c)\"></button>\n </div>\n <label class=\"color-custom\">\n <span>Custom</span>\n <input type=\"color\" (change)=\"pickCustomColor('background', $event)\" />\n </label>\n </div>\n </div>\n </div>\n <div class=\"toolbar-items\" *ngIf=\"hasAny('alignLeft', 'alignCenter', 'alignRight', 'justify')\">\n <button type=\"button\" *ngIf=\"isVisible('alignLeft')\" (mousedown)=\"$event.preventDefault()\" (click)=\"setAlignment('left')\" title=\"Justify Left\">\n <i class=\"he he-left-align\"></i>\n </button>\n <button type=\"button\" *ngIf=\"isVisible('alignCenter')\" (mousedown)=\"$event.preventDefault()\" (click)=\"setAlignment('center')\" title=\"Justify Center\">\n <i class=\"he he-center-align\"></i>\n </button>\n <button type=\"button\" *ngIf=\"isVisible('alignRight')\" (mousedown)=\"$event.preventDefault()\" (click)=\"setAlignment('right')\" title=\"Justify Right\">\n <i class=\"he he-right-align\"></i>\n </button>\n <button type=\"button\" *ngIf=\"isVisible('justify')\" (mousedown)=\"$event.preventDefault()\" (click)=\"setAlignment('justify')\" title=\"Justify Full\">\n <i class=\"he he-justify\"></i>\n </button>\n </div>\n <div class=\"toolbar-items\" *ngIf=\"hasAny('indent', 'outdent')\">\n <button type=\"button\" *ngIf=\"isVisible('indent')\" (mousedown)=\"$event.preventDefault()\" (click)=\"indent()\" title=\"Indent\">\n <i class=\"he he-text-indent-left\"></i>\n </button>\n <button type=\"button\" *ngIf=\"isVisible('outdent')\" (mousedown)=\"$event.preventDefault()\" (click)=\"outdent()\" title=\"Outdent\">\n <i class=\"he he-text-indent-right\"></i>\n </button>\n </div>\n <div class=\"toolbar-items\" *ngIf=\"hasAny('unorderedList', 'orderedList')\">\n <button type=\"button\" *ngIf=\"isVisible('unorderedList')\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyList('ul')\" title=\"Unordered list\">\n <i class=\"he he-unordered-list\"></i>\n </button>\n <button type=\"button\" *ngIf=\"isVisible('orderedList')\" (mousedown)=\"$event.preventDefault()\" (click)=\"applyList('ol')\" title=\"Ordered list\">\n <i class=\"he he-ordered-list\"></i>\n </button>\n </div>\n <div class=\"toolbar-items\" *ngIf=\"hasAny('link', 'image')\">\n <button type=\"button\" *ngIf=\"isVisible('link')\" (mousedown)=\"$event.preventDefault()\" (click)=\"createLink()\" title=\"Link\">\n <i class=\"he he-link\"></i>\n </button>\n <button type=\"button\" *ngIf=\"isVisible('image')\" (mousedown)=\"$event.preventDefault()\" (click)=\"insertImage()\" title=\"Image\">\n <i class=\"he he-image\"></i>\n </button>\n </div>\n <div class=\"toolbar-items\" *ngIf=\"hasAny('undo', 'redo')\">\n <button type=\"button\" *ngIf=\"isVisible('undo')\" (mousedown)=\"$event.preventDefault()\" (click)=\"undo()\" title=\"Undo\">\n <i class=\"he he-undo\"></i>\n </button>\n <button type=\"button\" *ngIf=\"isVisible('redo')\" (mousedown)=\"$event.preventDefault()\" (click)=\"redo()\" title=\"Redo\">\n <i class=\"he he-redo\"></i>\n </button>\n </div>\n <div class=\"toolbar-items\" *ngIf=\"isVisible('clearFormatting')\">\n <button type=\"button\" (mousedown)=\"$event.preventDefault()\" (click)=\"clearFormatting()\" title=\"Clear Formatting\">\n <i class=\"he he-text-clear-format\"></i>\n </button>\n </div>\n </div>\n\n <div #editor class=\"editor-content\" [attr.contenteditable]=\"(readonly || disabled) ? 'false' : 'true'\" (input)=\"onInput()\" (blur)=\"onTouched()\"\n [attr.data-placeholder]=\"placeholder\">\n </div>\n\n <!-- Custom Modal for Link/Image URL -->\n <div class=\"editor-modal-overlay\" *ngIf=\"showModal\" (click)=\"cancelModal()\">\n <div class=\"editor-modal\" (click)=\"$event.stopPropagation()\">\n <div class=\"editor-modal-header\">\n <span>{{ modalType === 'link' ? 'Insert Link' : 'Insert Image' }}</span>\n <button type=\"button\" class=\"editor-modal-close\" (click)=\"cancelModal()\">\n <i class=\"he he-close\"></i>\n </button>\n </div>\n <div class=\"editor-modal-body\">\n <div class=\"url-list\">\n <div class=\"url-row\" *ngFor=\"let url of modalUrls; let i = index; trackBy: trackByIndex\">\n <div class=\"url-field\">\n <input type=\"text\" class=\"url-input\" [class.invalid]=\"isRowInvalid(modalUrls[i])\"\n [ngModel]=\"modalUrls[i]\"\n (ngModelChange)=\"modalUrls[i] = $event\"\n [placeholder]=\"modalType === 'link' ? 'https://example.com' : 'https://example.com/image.png'\" />\n <span class=\"url-error\" *ngIf=\"isRowInvalid(modalUrls[i])\">Enter a valid URL</span>\n </div>\n <button type=\"button\" class=\"url-remove-btn\" *ngIf=\"modalUrls.length > 1\" (click)=\"removeUrlRow(i)\" title=\"Remove\">\n <i class=\"he he-close\"></i>\n </button>\n </div>\n </div>\n <button type=\"button\" class=\"url-add-btn\" (click)=\"addUrlRow()\">\n + Add more\n </button>\n </div>\n <div class=\"editor-modal-footer\">\n <button type=\"button\" class=\"modal-btn cancel-btn\" (click)=\"cancelModal()\">Cancel</button>\n <button type=\"button\" class=\"modal-btn confirm-btn\" [disabled]=\"!hasValidUrl\" (click)=\"confirmModal()\">Insert</button>\n </div>\n </div>\n </div>\n</div>\n", styles: [".text-editor{border:1px solid #ccc}.text-editor .toolbar{gap:.75rem;display:flex;flex-wrap:wrap;background:#f8f8f8;padding:.75rem;border-bottom:1px solid #cccccc}.text-editor .toolbar .toolbar-items{height:18px;display:flex;flex-wrap:wrap;align-items:center;padding-right:.75rem;border-right:1px solid #969090}.text-editor .toolbar .toolbar-items button{cursor:pointer;min-width:25px;min-height:20px;border:0;display:grid;place-items:center;background:transparent}.text-editor .toolbar .toolbar-items button:hover{background:#eee}.text-editor .toolbar .toolbar-items button:hover i{color:#000}.text-editor .toolbar .toolbar-items .color-tool{position:relative}.text-editor .toolbar .toolbar-items i{font-size:13px;color:#3c4148}.text-editor .toolbar .toolbar-items i.he-bold{font-weight:600}.text-editor .toolbar .toolbar-items i.he-underline{font-size:14px}.text-editor .toolbar .toolbar-items i.he-text-drop{font-size:12px}.text-editor .toolbar .toolbar-items i.he-background-drop{top:-1px;font-size:12px}.text-editor .toolbar .toolbar-items i.he-heading-1,.text-editor .toolbar .toolbar-items i.he-link,.text-editor .toolbar .toolbar-items i.he-left-align,.text-editor .toolbar .toolbar-items i.he-center-align,.text-editor .toolbar .toolbar-items i.he-right-align,.text-editor .toolbar .toolbar-items i.he-justify{font-size:16px}.text-editor .toolbar .toolbar-items i.he-text-indent-left,.text-editor .toolbar .toolbar-items i.he-text-indent-right{font-size:17px}.text-editor .toolbar .toolbar-items i.he-heading-2{top:1px;font-size:16px}.text-editor .toolbar .toolbar-items i.he-unordered-list,.text-editor .toolbar .toolbar-items i.he-ordered-list{top:-1px;font-size:20px}.text-editor .toolbar .toolbar-items i.he-image{font-size:15px;font-weight:600}.text-editor .toolbar .toolbar-items i.he-redo,.text-editor .toolbar .toolbar-items i.he-undo{top:-1px;font-size:14px}.text-editor .toolbar .toolbar-items.more-gap{gap:5px}.text-editor .toolbar .toolbar-items:last-child{border-right:0}.text-editor .color-popover{top:calc(100% + 6px);left:0;z-index:30;padding:8px;position:absolute;background:#fff;border-radius:6px;border:1px solid #e0e0e0;box-shadow:0 4px 16px #00000026}.text-editor .color-popover .color-grid{gap:4px;display:grid;grid-template-columns:repeat(8,18px)}.text-editor .color-popover .color-swatch{width:18px;height:18px;padding:0;cursor:pointer;border-radius:3px;border:1px solid rgba(0,0,0,.15);transition:transform .1s ease}.text-editor .color-popover .color-swatch:hover{transform:scale(1.15)}.text-editor .color-popover .color-custom{gap:8px;display:flex;margin-top:8px;font-size:12px;color:#555;cursor:pointer;align-items:center;justify-content:space-between}.text-editor .color-popover .color-custom input[type=color]{width:28px;height:20px;padding:0;cursor:pointer;background:none;border:1px solid #cccccc}.text-editor .editor-content{outline:none;min-height:200px;position:relative;background:#fff;padding:.75rem}.text-editor .editor-content[data-placeholder]:empty:before{content:attr(data-placeholder);color:#aaa;pointer-events:none;position:absolute;left:.75rem;top:.75rem}.text-editor .editor-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:#00000073;display:flex;align-items:center;justify-content:center;z-index:10000}.text-editor .editor-modal{background:#fff;border-radius:8px;box-shadow:0 8px 32px #0003;width:420px;max-width:90vw;animation:modalFadeIn .2s ease}@keyframes modalFadeIn{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.text-editor .editor-modal-header{display:flex;align-items:center;justify-content:space-between;padding:14px 18px;border-bottom:1px solid #e8e8e8}.text-editor .editor-modal-header span{font-size:15px;font-weight:600;color:#1a1a1a}.text-editor .editor-modal-close{background:none;border:none;cursor:pointer;padding:4px;border-radius:4px;display:grid;place-items:center}.text-editor .editor-modal-close i{font-size:14px;color:#666}.text-editor .editor-modal-close:hover{background:#f0f0f0}.text-editor .editor-modal-close:hover i{color:#333}.text-editor .editor-modal-body{padding:16px 18px}.text-editor .editor-modal-body .url-list{max-height:200px;overflow-y:auto;margin-bottom:10px;padding-right:2px}.text-editor .editor-modal-body .url-row{display:flex;align-items:flex-start;gap:8px;margin-bottom:10px}.text-editor .editor-modal-body .url-field{flex:1;display:flex;flex-direction:column;gap:2px}.text-editor .editor-modal-body .url-input{width:100%;padding:8px 12px;border:1px solid #d0d0d0;border-radius:6px;font-size:13px;color:#333;outline:none;transition:border-color .2s}.text-editor .editor-modal-body .url-input:focus{border-color:#007bff;box-shadow:0 0 0 2px #007bff26}.text-editor .editor-modal-body .url-input::placeholder{color:#aaa}.text-editor .editor-modal-body .url-input.invalid{border-color:#e04040}.text-editor .editor-modal-body .url-input.invalid:focus{border-color:#e04040;box-shadow:0 0 0 2px #e0404026}.text-editor .editor-modal-body .url-error{font-size:11px;color:#e04040}.text-editor .editor-modal-body .url-remove-btn{background:none;border:1px solid #e0e0e0;border-radius:6px;cursor:pointer;padding:8px 9px;display:grid;place-items:center;transition:all .15s}.text-editor .editor-modal-body .url-remove-btn i{font-size:11px;color:#999}.text-editor .editor-modal-body .url-remove-btn:hover{background:#fff0f0;border-color:#faa}.text-editor .editor-modal-body .url-remove-btn:hover i{color:#e04040}.text-editor .editor-modal-body .url-add-btn{background:none;border:1px dashed #c0c0c0;border-radius:6px;cursor:pointer;padding:6px 14px;font-size:12px;color:#007bff;transition:all .15s;width:100%}.text-editor .editor-modal-body .url-add-btn:hover{background:#f0f8ff;border-color:#007bff}.text-editor .editor-modal-footer{display:flex;justify-content:flex-end;gap:10px;padding:12px 18px;border-top:1px solid #e8e8e8}.text-editor .editor-modal-footer .modal-btn{padding:7px 20px;border-radius:6px;font-size:13px;font-weight:500;cursor:pointer;transition:all .15s;border:1px solid transparent}.text-editor .editor-modal-footer .cancel-btn{background:#f5f5f5;color:#555;border-color:#ddd}.text-editor .editor-modal-footer .cancel-btn:hover{background:#eaeaea}.text-editor .editor-modal-footer .confirm-btn{background:#007bff;color:#fff}.text-editor .editor-modal-footer .confirm-btn:hover{background:#0069d9}.text-editor .editor-modal-footer .confirm-btn:disabled{opacity:.5;cursor:not-allowed}.text-editor .editor-modal-footer .confirm-btn:disabled:hover{background:#007bff}\n"] }]
|
|
4501
|
+
}], propDecorators: { features: [{
|
|
4218
4502
|
type: Input
|
|
4219
4503
|
}], placeholder: [{
|
|
4220
4504
|
type: Input
|
|
@@ -4343,5 +4627,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
4343
4627
|
* Generated bundle index. Do not edit.
|
|
4344
4628
|
*/
|
|
4345
4629
|
|
|
4346
|
-
export { AutocompleteControl, CalendarControl, CheckboxControl, ColorPicker, InputControl, MultiselectControl, PaginatedAutocompleteControl, RadioControl, RichTextEditor, SelectControl, SwitchControl, TextareaControl };
|
|
4630
|
+
export { AutocompleteControl, CalendarControl, CheckboxControl, ColorPicker, InputControl, MultiselectControl, PaginatedAutocompleteControl, RICH_TEXT_EDITOR_DEFAULT_FEATURES, RadioControl, RichTextEditor, SelectControl, SwitchControl, TextareaControl };
|
|
4347
4631
|
//# sourceMappingURL=nexheal-lib.mjs.map
|