ngx-kit 6.1.0 → 6.2.0
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/README.md +3 -3
- package/angle-selector/README.md +34 -34
- package/box-shadow/README.md +33 -33
- package/color-picker/README.md +49 -49
- package/data-table/README.md +113 -113
- package/date-picker/README.md +69 -69
- package/dialog/README.md +92 -92
- package/drawer-menu/README.md +77 -77
- package/dropzone/README.md +422 -422
- package/fesm2022/ngx-kit-angle-selector.mjs +2 -2
- package/fesm2022/ngx-kit-angle-selector.mjs.map +1 -1
- package/fesm2022/ngx-kit-box-shadow.mjs +2 -2
- package/fesm2022/ngx-kit-box-shadow.mjs.map +1 -1
- package/fesm2022/ngx-kit-color-picker.mjs +4 -4
- package/fesm2022/ngx-kit-color-picker.mjs.map +1 -1
- package/fesm2022/ngx-kit-data-table.mjs +2 -2
- package/fesm2022/ngx-kit-data-table.mjs.map +1 -1
- package/fesm2022/ngx-kit-date-picker.mjs +1322 -200
- package/fesm2022/ngx-kit-date-picker.mjs.map +1 -1
- package/fesm2022/ngx-kit-dialog.mjs +2 -2
- package/fesm2022/ngx-kit-dialog.mjs.map +1 -1
- package/fesm2022/ngx-kit-drawer-menu.mjs +2 -2
- package/fesm2022/ngx-kit-drawer-menu.mjs.map +1 -1
- package/fesm2022/ngx-kit-dropzone.mjs +2 -2
- package/fesm2022/ngx-kit-dropzone.mjs.map +1 -1
- package/fesm2022/ngx-kit-form-field.mjs.map +1 -1
- package/fesm2022/ngx-kit-gallery.mjs +2 -2
- package/fesm2022/ngx-kit-gallery.mjs.map +1 -1
- package/fesm2022/ngx-kit-gradient-picker.mjs.map +1 -1
- package/fesm2022/ngx-kit-image-editor.mjs +75 -11
- package/fesm2022/ngx-kit-image-editor.mjs.map +1 -1
- package/fesm2022/ngx-kit-menu.mjs +8 -8
- package/fesm2022/ngx-kit-menu.mjs.map +1 -1
- package/fesm2022/ngx-kit-message.mjs.map +1 -1
- package/fesm2022/ngx-kit-notify.mjs.map +1 -1
- package/fesm2022/ngx-kit-shared.mjs +2 -2
- package/fesm2022/ngx-kit-shared.mjs.map +1 -1
- package/fesm2022/ngx-kit-time-picker.mjs +2 -2
- package/fesm2022/ngx-kit-time-picker.mjs.map +1 -1
- package/gallery/README.md +71 -71
- package/gradient-picker/README.md +41 -41
- package/menu/README.md +85 -85
- package/message/README.md +70 -70
- package/notify/README.md +58 -58
- package/package.json +1 -1
- package/shared/README.md +117 -117
- package/time-picker/README.md +95 -95
- package/types/ngx-kit-date-picker.d.ts +302 -36
- package/types/ngx-kit-dropzone.d.ts +5 -5
- package/types/ngx-kit-image-editor.d.ts +29 -4
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, inject, Injectable, EventEmitter, forwardRef, Output, Input, Component,
|
|
2
|
+
import { InjectionToken, inject, Injectable, input, EventEmitter, forwardRef, Output, Input, Component, ViewContainerRef, Renderer2, HostListener, Directive, viewChild, ChangeDetectionStrategy } from '@angular/core';
|
|
3
3
|
import { NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
|
|
4
4
|
import * as i1 from '@angular/common';
|
|
5
5
|
import { CommonModule } from '@angular/common';
|
|
6
|
-
import {
|
|
6
|
+
import { OverlayService } from 'ngx-kit/shared';
|
|
7
7
|
|
|
8
8
|
class NgxDatePickerConfig {
|
|
9
9
|
previousButtonTemplate;
|
|
@@ -11,8 +11,6 @@ class NgxDatePickerConfig {
|
|
|
11
11
|
caretDownIconTemplate;
|
|
12
12
|
todayButton = true;
|
|
13
13
|
clearButton = true;
|
|
14
|
-
clearButtonText = 'Clear';
|
|
15
|
-
todayButtonText = 'Today';
|
|
16
14
|
}
|
|
17
15
|
|
|
18
16
|
/**
|
|
@@ -185,6 +183,7 @@ function twoDigitPad(num) {
|
|
|
185
183
|
|
|
186
184
|
class GregorianAdapter {
|
|
187
185
|
startOfWeek = 0;
|
|
186
|
+
weekStartDay = 0;
|
|
188
187
|
get longMonths() {
|
|
189
188
|
return [
|
|
190
189
|
'January',
|
|
@@ -299,13 +298,26 @@ class GregorianAdapter {
|
|
|
299
298
|
// return new Date(date).toLocaleDateString('en-US', option);
|
|
300
299
|
return genFormatDate(date, format, this.longMonths, this.longDays);
|
|
301
300
|
}
|
|
301
|
+
getStartOfWeek(date) {
|
|
302
|
+
const d = new Date(date);
|
|
303
|
+
d.setHours(0, 0, 0, 0);
|
|
304
|
+
const delta = (d.getDay() - this.weekStartDay + 7) % 7;
|
|
305
|
+
d.setDate(d.getDate() - delta);
|
|
306
|
+
return d;
|
|
307
|
+
}
|
|
308
|
+
getEndOfWeek(date) {
|
|
309
|
+
const d = this.getStartOfWeek(date);
|
|
310
|
+
d.setDate(d.getDate() + 6);
|
|
311
|
+
d.setHours(23, 59, 59, 999);
|
|
312
|
+
return d;
|
|
313
|
+
}
|
|
302
314
|
getStartOf(date, t) {
|
|
303
315
|
if (!date) {
|
|
304
316
|
return date;
|
|
305
317
|
}
|
|
306
318
|
switch (t) {
|
|
307
319
|
case 'year':
|
|
308
|
-
return new Date(date.getFullYear(),
|
|
320
|
+
return new Date(date.getFullYear(), 0, 1);
|
|
309
321
|
case 'month':
|
|
310
322
|
return new Date(date.getFullYear(), date.getMonth(), 1);
|
|
311
323
|
case 'day':
|
|
@@ -615,6 +627,7 @@ var Jalali;
|
|
|
615
627
|
class JalaliAdapter {
|
|
616
628
|
// shanbeh
|
|
617
629
|
startOfWeek = 1;
|
|
630
|
+
weekStartDay = 6;
|
|
618
631
|
dariMonth = false;
|
|
619
632
|
get longMonths() {
|
|
620
633
|
return [
|
|
@@ -654,7 +667,7 @@ class JalaliAdapter {
|
|
|
654
667
|
minutes: date.getMinutes(),
|
|
655
668
|
seconds: date.getSeconds(),
|
|
656
669
|
milliseconds: date.getMilliseconds(),
|
|
657
|
-
dayOfWeek: date.getDay() + this.startOfWeek,
|
|
670
|
+
dayOfWeek: (date.getDay() + this.startOfWeek) % 7,
|
|
658
671
|
};
|
|
659
672
|
}
|
|
660
673
|
today() {
|
|
@@ -763,6 +776,19 @@ class JalaliAdapter {
|
|
|
763
776
|
return genFormatDate(date, format, this.longMonths, this.longDays);
|
|
764
777
|
}
|
|
765
778
|
// _______________________________________________________________________________________
|
|
779
|
+
getStartOfWeek(date) {
|
|
780
|
+
const d = new Date(date);
|
|
781
|
+
d.setHours(0, 0, 0, 0);
|
|
782
|
+
const delta = (d.getDay() - this.weekStartDay + 7) % 7;
|
|
783
|
+
d.setDate(d.getDate() - delta);
|
|
784
|
+
return d;
|
|
785
|
+
}
|
|
786
|
+
getEndOfWeek(date) {
|
|
787
|
+
const d = this.getStartOfWeek(date);
|
|
788
|
+
d.setDate(d.getDate() + 6);
|
|
789
|
+
d.setHours(23, 59, 59, 999);
|
|
790
|
+
return d;
|
|
791
|
+
}
|
|
766
792
|
getStartOf(date, t) {
|
|
767
793
|
if (!date) {
|
|
768
794
|
return date;
|
|
@@ -925,6 +951,7 @@ var HijriConverter;
|
|
|
925
951
|
class HijriAdapter {
|
|
926
952
|
/** یکشنبه = 0 (همخوان با تقویم میلادی برای سادگی) */
|
|
927
953
|
startOfWeek = 0;
|
|
954
|
+
weekStartDay = 0;
|
|
928
955
|
get longMonths() {
|
|
929
956
|
return [
|
|
930
957
|
'محرم',
|
|
@@ -1010,6 +1037,19 @@ class HijriAdapter {
|
|
|
1010
1037
|
}
|
|
1011
1038
|
return new Intl.DateTimeFormat('ar-SA-u-ca-islamic-umalqura', options).format(jsDate);
|
|
1012
1039
|
}
|
|
1040
|
+
getStartOfWeek(date) {
|
|
1041
|
+
const d = new Date(date);
|
|
1042
|
+
d.setHours(0, 0, 0, 0);
|
|
1043
|
+
const delta = (d.getDay() - this.weekStartDay + 7) % 7;
|
|
1044
|
+
d.setDate(d.getDate() - delta);
|
|
1045
|
+
return d;
|
|
1046
|
+
}
|
|
1047
|
+
getEndOfWeek(date) {
|
|
1048
|
+
const d = this.getStartOfWeek(date);
|
|
1049
|
+
d.setDate(d.getDate() + 6);
|
|
1050
|
+
d.setHours(23, 59, 59, 999);
|
|
1051
|
+
return d;
|
|
1052
|
+
}
|
|
1013
1053
|
getStartOf(date, t) {
|
|
1014
1054
|
if (!date)
|
|
1015
1055
|
return date;
|
|
@@ -1252,6 +1292,7 @@ var ChineseConverter;
|
|
|
1252
1292
|
class ChineseAdapter {
|
|
1253
1293
|
/** یکشنبه = 0 */
|
|
1254
1294
|
startOfWeek = 0;
|
|
1295
|
+
weekStartDay = 0;
|
|
1255
1296
|
get longMonths() {
|
|
1256
1297
|
return [
|
|
1257
1298
|
'正月',
|
|
@@ -1342,6 +1383,19 @@ class ChineseAdapter {
|
|
|
1342
1383
|
}
|
|
1343
1384
|
return new Intl.DateTimeFormat('zh-CN-u-ca-chinese', options).format(jsDate);
|
|
1344
1385
|
}
|
|
1386
|
+
getStartOfWeek(date) {
|
|
1387
|
+
const d = new Date(date);
|
|
1388
|
+
d.setHours(0, 0, 0, 0);
|
|
1389
|
+
const delta = (d.getDay() - this.weekStartDay + 7) % 7;
|
|
1390
|
+
d.setDate(d.getDate() - delta);
|
|
1391
|
+
return d;
|
|
1392
|
+
}
|
|
1393
|
+
getEndOfWeek(date) {
|
|
1394
|
+
const d = this.getStartOfWeek(date);
|
|
1395
|
+
d.setDate(d.getDate() + 6);
|
|
1396
|
+
d.setHours(23, 59, 59, 999);
|
|
1397
|
+
return d;
|
|
1398
|
+
}
|
|
1345
1399
|
getStartOf(date, t) {
|
|
1346
1400
|
if (!date)
|
|
1347
1401
|
return date;
|
|
@@ -1440,6 +1494,22 @@ class NgxDatePickerBase {
|
|
|
1440
1494
|
minDate = null;
|
|
1441
1495
|
maxDate = null;
|
|
1442
1496
|
renderCalendar(view, selected, events, callback) {
|
|
1497
|
+
switch (view) {
|
|
1498
|
+
case 'month':
|
|
1499
|
+
this.renderDay(selected, events);
|
|
1500
|
+
break;
|
|
1501
|
+
case 'week':
|
|
1502
|
+
this.renderWeek();
|
|
1503
|
+
break;
|
|
1504
|
+
case 'day':
|
|
1505
|
+
this.renderWeek();
|
|
1506
|
+
break;
|
|
1507
|
+
}
|
|
1508
|
+
this.displayMonth = this.months[this.currMonth] ?? '';
|
|
1509
|
+
if (callback)
|
|
1510
|
+
callback();
|
|
1511
|
+
}
|
|
1512
|
+
renderِDatePicker(view, selected, events, callback) {
|
|
1443
1513
|
switch (view) {
|
|
1444
1514
|
case 'day':
|
|
1445
1515
|
this.renderDay(selected, events);
|
|
@@ -1450,14 +1520,10 @@ class NgxDatePickerBase {
|
|
|
1450
1520
|
case 'year':
|
|
1451
1521
|
this.renderYear();
|
|
1452
1522
|
break;
|
|
1453
|
-
case 'week':
|
|
1454
|
-
this.renderWeek();
|
|
1455
|
-
break;
|
|
1456
1523
|
}
|
|
1457
|
-
this.displayMonth = this.months[this.currMonth];
|
|
1458
|
-
if (callback)
|
|
1524
|
+
this.displayMonth = this.months[this.currMonth] ?? '';
|
|
1525
|
+
if (callback)
|
|
1459
1526
|
callback();
|
|
1460
|
-
}
|
|
1461
1527
|
}
|
|
1462
1528
|
renderYear() {
|
|
1463
1529
|
this.viewYears = [];
|
|
@@ -1482,10 +1548,9 @@ class NgxDatePickerBase {
|
|
|
1482
1548
|
});
|
|
1483
1549
|
}
|
|
1484
1550
|
}
|
|
1485
|
-
|
|
1486
|
-
renderWeek() {
|
|
1551
|
+
renderWeek(anchorDate) {
|
|
1487
1552
|
this.viewWeeks = [];
|
|
1488
|
-
for (let t = 0; t
|
|
1553
|
+
for (let t = 0; t < 24; t += 0.5) {
|
|
1489
1554
|
this.viewWeeks.push({
|
|
1490
1555
|
time: t,
|
|
1491
1556
|
displayTime: convertNumberToTime(t),
|
|
@@ -1495,134 +1560,172 @@ class NgxDatePickerBase {
|
|
|
1495
1560
|
});
|
|
1496
1561
|
}
|
|
1497
1562
|
}
|
|
1498
|
-
|
|
1563
|
+
/** Returns the seven real dates belonging to the locale's week. */
|
|
1564
|
+
getWeekDates(anchor) {
|
|
1565
|
+
const start = this.adapter.getStartOfWeek(anchor);
|
|
1566
|
+
return Array.from({ length: 7 }, (_, index) => {
|
|
1567
|
+
const d = new Date(start);
|
|
1568
|
+
d.setDate(start.getDate() + index);
|
|
1569
|
+
d.setHours(0, 0, 0, 0);
|
|
1570
|
+
return d;
|
|
1571
|
+
});
|
|
1572
|
+
}
|
|
1573
|
+
getEventsForDate(date, events) {
|
|
1574
|
+
return this.getEvents(date, events);
|
|
1575
|
+
}
|
|
1576
|
+
normalizeEvent(event) {
|
|
1577
|
+
const start = event.start instanceof Date ? new Date(event.start) : new Date(event.start);
|
|
1578
|
+
const rawEnd = event.end
|
|
1579
|
+
? event.end instanceof Date
|
|
1580
|
+
? new Date(event.end)
|
|
1581
|
+
: new Date(event.end)
|
|
1582
|
+
: new Date(start);
|
|
1583
|
+
if (Number.isNaN(start.getTime()))
|
|
1584
|
+
return { event, start: new Date(NaN), end: new Date(NaN) };
|
|
1585
|
+
// Day-calendar events use an inclusive end date. For timed events, the actual
|
|
1586
|
+
// end instant is respected. An omitted end means a one-day event.
|
|
1587
|
+
const end = Number.isNaN(rawEnd.getTime()) ? new Date(start) : rawEnd;
|
|
1588
|
+
return { event, start, end: end < start ? new Date(start) : end };
|
|
1589
|
+
}
|
|
1590
|
+
/**
|
|
1591
|
+
* Renders a 6-row month grid and attaches events to every visible day.
|
|
1592
|
+
*
|
|
1593
|
+
* The event list is normalized to MsEventViewer so the template can draw
|
|
1594
|
+
* continuation edges similar to FullCalendar's month view.
|
|
1595
|
+
*/
|
|
1596
|
+
renderDay(selected, events) {
|
|
1499
1597
|
this.viewDays = [];
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
for (let i =
|
|
1505
|
-
const
|
|
1598
|
+
const firstDayOfMonth = this.adapter.firstDayofMonth(this.currYear, this.currMonth);
|
|
1599
|
+
const lastDateOfMonth = this.adapter.lastDateofMonth(this.currYear, this.currMonth);
|
|
1600
|
+
const lastDayOfMonth = this.adapter.lastDayofMonth(this.currYear, this.currMonth);
|
|
1601
|
+
const lastDateOfLastMonth = this.adapter.lastDateofLastMonth(this.currYear, this.currMonth);
|
|
1602
|
+
for (let i = firstDayOfMonth; i > 0; i--) {
|
|
1603
|
+
const day = lastDateOfLastMonth - i + 1;
|
|
1506
1604
|
const date = this.adapter.getDate({
|
|
1507
1605
|
locale: this._locale,
|
|
1508
1606
|
year: this.currYear,
|
|
1509
1607
|
month: this.currMonth - 1,
|
|
1510
|
-
day
|
|
1608
|
+
day,
|
|
1511
1609
|
});
|
|
1512
1610
|
this.viewDays.push({
|
|
1513
|
-
day
|
|
1611
|
+
day,
|
|
1514
1612
|
active: false,
|
|
1515
1613
|
isToday: false,
|
|
1516
1614
|
selected: false,
|
|
1517
1615
|
date,
|
|
1616
|
+
events: this.getEvents(date, events),
|
|
1518
1617
|
});
|
|
1519
1618
|
}
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
let isToday = i === today.day && this.currMonth === today.month && this.currYear === today.year;
|
|
1619
|
+
for (let day = 1; day <= lastDateOfMonth; day++) {
|
|
1620
|
+
const today = this.adapter.today();
|
|
1621
|
+
const isToday = day === today.day && this.currMonth === today.month && this.currYear === today.year;
|
|
1524
1622
|
const date = this.adapter.getDate({
|
|
1525
1623
|
locale: this._locale,
|
|
1526
1624
|
year: this.currYear,
|
|
1527
1625
|
month: this.currMonth,
|
|
1528
|
-
day
|
|
1626
|
+
day,
|
|
1529
1627
|
});
|
|
1530
|
-
const events = this.getEvents(date, _events);
|
|
1531
1628
|
this.viewDays.push({
|
|
1532
|
-
day
|
|
1629
|
+
day,
|
|
1533
1630
|
active: this.checkActiveDate(date),
|
|
1534
|
-
isToday
|
|
1535
|
-
selected:
|
|
1631
|
+
isToday,
|
|
1632
|
+
selected: day === selected?.day &&
|
|
1536
1633
|
selected.month === this.currMonth &&
|
|
1537
1634
|
selected.year === this.currYear,
|
|
1538
1635
|
date,
|
|
1539
|
-
events,
|
|
1636
|
+
events: this.getEvents(date, events),
|
|
1540
1637
|
});
|
|
1541
1638
|
}
|
|
1542
|
-
for (let i =
|
|
1543
|
-
const
|
|
1639
|
+
for (let i = lastDayOfMonth; i < 6; i++) {
|
|
1640
|
+
const day = i - lastDayOfMonth + 1;
|
|
1544
1641
|
const date = this.adapter.getDate({
|
|
1545
1642
|
locale: this._locale,
|
|
1546
1643
|
year: this.currYear,
|
|
1547
1644
|
month: this.currMonth + 1,
|
|
1548
|
-
day
|
|
1645
|
+
day,
|
|
1549
1646
|
});
|
|
1550
1647
|
this.viewDays.push({
|
|
1551
|
-
day
|
|
1648
|
+
day,
|
|
1552
1649
|
active: false,
|
|
1553
1650
|
isToday: false,
|
|
1554
1651
|
selected: false,
|
|
1555
1652
|
date,
|
|
1653
|
+
events: this.getEvents(date, events),
|
|
1556
1654
|
});
|
|
1557
1655
|
}
|
|
1558
1656
|
}
|
|
1559
1657
|
checkActiveDate(date) {
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
return false;
|
|
1563
|
-
}
|
|
1564
|
-
else if (c > 0) {
|
|
1565
|
-
return false;
|
|
1566
|
-
}
|
|
1567
|
-
return true;
|
|
1658
|
+
const c = clampDate(date, this.minDate, this.maxDate);
|
|
1659
|
+
return c === 0;
|
|
1568
1660
|
}
|
|
1569
1661
|
checkActiveMonth(year, month) {
|
|
1570
|
-
|
|
1571
|
-
|
|
1662
|
+
const fd = this.adapter.getDate({ locale: this._locale, year, month, day: 1 });
|
|
1663
|
+
const ld = this.adapter.getDate({
|
|
1572
1664
|
locale: this._locale,
|
|
1573
1665
|
year,
|
|
1574
1666
|
month,
|
|
1575
1667
|
day: this.adapter.lastDateofMonth(year, month),
|
|
1576
1668
|
});
|
|
1577
|
-
|
|
1578
|
-
|
|
1669
|
+
const min = this.adapter.getStartOf(this.minDate, 'month');
|
|
1670
|
+
const max = this.adapter.getLastOf(this.maxDate, 'month');
|
|
1579
1671
|
return clampMonth(fd, min, max) === 0 && clampMonth(ld, min, max) === 0;
|
|
1580
1672
|
}
|
|
1581
|
-
// g(d: Date | null) {
|
|
1582
|
-
// if (d)
|
|
1583
|
-
// return d.getFullYear() + '/' + d.getMonth() + '/' + d.getDate();
|
|
1584
|
-
// else return '';
|
|
1585
|
-
// }
|
|
1586
1673
|
checkActiveYear(year) {
|
|
1587
1674
|
const d = this.adapter.getDate({ locale: this._locale, year, month: 1, day: 1 });
|
|
1588
|
-
|
|
1589
|
-
if (c < 0) {
|
|
1590
|
-
return false;
|
|
1591
|
-
}
|
|
1592
|
-
else if (c > 0) {
|
|
1593
|
-
return false;
|
|
1594
|
-
}
|
|
1595
|
-
return true;
|
|
1675
|
+
return clampYear(d, this.minDate, this.maxDate) === 0;
|
|
1596
1676
|
}
|
|
1597
1677
|
getEvents(date, events) {
|
|
1598
|
-
if (!events
|
|
1678
|
+
if (!events?.length)
|
|
1599
1679
|
return [];
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1680
|
+
return events
|
|
1681
|
+
.filter((event) => {
|
|
1682
|
+
const start = event.start instanceof Date ? event.start : new Date(event.start);
|
|
1683
|
+
const end = event.end
|
|
1684
|
+
? event.end instanceof Date
|
|
1685
|
+
? event.end
|
|
1686
|
+
: new Date(event.end)
|
|
1687
|
+
: start;
|
|
1688
|
+
return compareDate(date, start) >= 0 && compareDate(date, end) <= 0;
|
|
1689
|
+
})
|
|
1690
|
+
.map((event) => {
|
|
1691
|
+
const start = event.start instanceof Date ? event.start : new Date(event.start);
|
|
1692
|
+
const end = event.end
|
|
1693
|
+
? event.end instanceof Date
|
|
1694
|
+
? event.end
|
|
1695
|
+
: new Date(event.end)
|
|
1696
|
+
: start;
|
|
1697
|
+
return {
|
|
1698
|
+
...event,
|
|
1699
|
+
continuesBefore: compareDate(start, date) < 0,
|
|
1700
|
+
continuesAfter: compareDate(end, date) > 0,
|
|
1701
|
+
isStart: compareDate(start, date) === 0,
|
|
1702
|
+
isEnd: compareDate(end, date) === 0,
|
|
1703
|
+
};
|
|
1609
1704
|
});
|
|
1610
|
-
// console.log('event', date, eventList);
|
|
1611
|
-
return eventList;
|
|
1612
1705
|
}
|
|
1613
1706
|
}
|
|
1614
1707
|
|
|
1708
|
+
const NGX_CALENDAR_LOCALIZATION = new InjectionToken('ngx-calendar-localization', {
|
|
1709
|
+
factory: () => DEFAULT_NGX_CALENDAR_LOCALIZATION,
|
|
1710
|
+
});
|
|
1711
|
+
class NgxCalendarLocalization {
|
|
1712
|
+
clear = 'Clear';
|
|
1713
|
+
today = 'Today';
|
|
1714
|
+
/** Range picker labels. */
|
|
1715
|
+
rangeStart = 'Start date';
|
|
1716
|
+
rangeEnd = 'End date';
|
|
1717
|
+
day = 'Day';
|
|
1718
|
+
month = 'Month';
|
|
1719
|
+
week = 'Week';
|
|
1720
|
+
year = 'Year';
|
|
1721
|
+
event = 'Event';
|
|
1722
|
+
}
|
|
1723
|
+
const DEFAULT_NGX_CALENDAR_LOCALIZATION = new NgxCalendarLocalization();
|
|
1724
|
+
|
|
1615
1725
|
class NgxInputDatePickerComponent extends NgxDatePickerBase {
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
if (!val || val == 'auto') {
|
|
1620
|
-
this.theme = this.browserService.prefersDarkMode ? 'dark' : 'light';
|
|
1621
|
-
}
|
|
1622
|
-
else {
|
|
1623
|
-
this.theme = val;
|
|
1624
|
-
}
|
|
1625
|
-
}
|
|
1726
|
+
defaultLocalization = inject(NGX_CALENDAR_LOCALIZATION);
|
|
1727
|
+
localize = input(this.defaultLocalization, /* @ts-ignore */
|
|
1728
|
+
...(ngDevMode ? [{ debugName: "localize" }] : /* istanbul ignore next */ []));
|
|
1626
1729
|
config = new NgxDatePickerConfig();
|
|
1627
1730
|
set setConfig(val) {
|
|
1628
1731
|
this.config = { ...new NgxDatePickerConfig(), ...val };
|
|
@@ -1652,7 +1755,6 @@ class NgxInputDatePickerComponent extends NgxDatePickerBase {
|
|
|
1652
1755
|
}
|
|
1653
1756
|
view = 'day';
|
|
1654
1757
|
change = new EventEmitter();
|
|
1655
|
-
wrapperWidth = 40 * 7 + 20;
|
|
1656
1758
|
selected;
|
|
1657
1759
|
calendarHeader = '';
|
|
1658
1760
|
isDisabled = false;
|
|
@@ -1681,7 +1783,7 @@ class NgxInputDatePickerComponent extends NgxDatePickerBase {
|
|
|
1681
1783
|
let l = this.adapter.toLocale(this.selected.date);
|
|
1682
1784
|
this.currYear = l.year;
|
|
1683
1785
|
this.currMonth = l.month ?? 1;
|
|
1684
|
-
this.
|
|
1786
|
+
this.renderِDatePicker(this.view);
|
|
1685
1787
|
}
|
|
1686
1788
|
}
|
|
1687
1789
|
writeValue(value) {
|
|
@@ -1729,8 +1831,8 @@ class NgxInputDatePickerComponent extends NgxDatePickerBase {
|
|
|
1729
1831
|
setDisabledState(disabled) {
|
|
1730
1832
|
this.isDisabled = disabled;
|
|
1731
1833
|
}
|
|
1732
|
-
|
|
1733
|
-
super.
|
|
1834
|
+
renderِDatePicker(view) {
|
|
1835
|
+
super.renderِDatePicker(view, this.selected, [], () => {
|
|
1734
1836
|
let d = this.selected?.date;
|
|
1735
1837
|
this.calendarHeader =
|
|
1736
1838
|
(d && this.adapter.formatDate(this.adapter.toLocale(d), 'EEEE - d MMMM, yyyy')) ?? '';
|
|
@@ -1746,7 +1848,7 @@ class NgxInputDatePickerComponent extends NgxDatePickerBase {
|
|
|
1746
1848
|
}
|
|
1747
1849
|
changeView(v) {
|
|
1748
1850
|
this.view = v;
|
|
1749
|
-
this.
|
|
1851
|
+
this.renderِDatePicker(this.view);
|
|
1750
1852
|
}
|
|
1751
1853
|
next() {
|
|
1752
1854
|
if (this.view === 'year') {
|
|
@@ -1763,7 +1865,7 @@ class NgxInputDatePickerComponent extends NgxDatePickerBase {
|
|
|
1763
1865
|
this.currYear = date.getFullYear();
|
|
1764
1866
|
this.currMonth = date.getMonth();
|
|
1765
1867
|
}
|
|
1766
|
-
this.
|
|
1868
|
+
this.renderِDatePicker(this.view);
|
|
1767
1869
|
}
|
|
1768
1870
|
previous() {
|
|
1769
1871
|
if (this.view === 'year') {
|
|
@@ -1780,7 +1882,7 @@ class NgxInputDatePickerComponent extends NgxDatePickerBase {
|
|
|
1780
1882
|
this.currYear = date.getFullYear();
|
|
1781
1883
|
this.currMonth = date.getMonth();
|
|
1782
1884
|
}
|
|
1783
|
-
this.
|
|
1885
|
+
this.renderِDatePicker(this.view);
|
|
1784
1886
|
}
|
|
1785
1887
|
selectDay(ev, item) {
|
|
1786
1888
|
ev.stopPropagation();
|
|
@@ -1817,7 +1919,7 @@ class NgxInputDatePickerComponent extends NgxDatePickerBase {
|
|
|
1817
1919
|
ev.stopPropagation();
|
|
1818
1920
|
}
|
|
1819
1921
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NgxInputDatePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1820
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: NgxInputDatePickerComponent, isStandalone: true, selector: "ngx-date-picker", inputs: {
|
|
1922
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: NgxInputDatePickerComponent, isStandalone: true, selector: "ngx-date-picker", inputs: { localize: { classPropertyName: "localize", publicName: "localize", isSignal: true, isRequired: false, transformFunction: null }, setConfig: { classPropertyName: "setConfig", publicName: "config", isSignal: false, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: false, isRequired: false, transformFunction: null }, setMin: { classPropertyName: "setMin", publicName: "min", isSignal: false, isRequired: false, transformFunction: null }, setMax: { classPropertyName: "setMax", publicName: "max", isSignal: false, isRequired: false, transformFunction: null }, view: { classPropertyName: "view", publicName: "view", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { change: "change" }, providers: [
|
|
1821
1923
|
DateAdapterRegistry,
|
|
1822
1924
|
{
|
|
1823
1925
|
provide: NG_VALUE_ACCESSOR,
|
|
@@ -1829,7 +1931,7 @@ class NgxInputDatePickerComponent extends NgxDatePickerBase {
|
|
|
1829
1931
|
useExisting: forwardRef(() => NgxInputDatePickerComponent),
|
|
1830
1932
|
multi: true,
|
|
1831
1933
|
},
|
|
1832
|
-
], usesInheritance: true, ngImport: i0, template: "<div\r\n class=\"
|
|
1934
|
+
], usesInheritance: true, ngImport: i0, template: "<div class=\"wrapper\" #datepickerWrapper (click)=\"stopPagination($event)\">\r\n <div class=\"header\">\r\n <svg\r\n class=\"calendar-icon\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\">\r\n <path\r\n d=\"M16 2V6M8 2V6\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.5\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M13 4H11C7.22876 4 5.34315 4 4.17157 5.17157C3 6.34315 3 8.22876 3 12V14C3 17.7712 3 19.6569 4.17157 20.8284C5.34315 22 7.22876 22 11 22H13C16.7712 22 18.6569 22 19.8284 20.8284C21 19.6569 21 17.7712 21 14V12C21 8.22876 21 6.34315 19.8284 5.17157C18.6569 4 16.7712 4 13 4Z\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.5\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M3 10H21\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.5\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M11.9955 14H12.0045M11.9955 18H12.0045M15.991 14H16M8 14H8.00897M8 18H8.00897\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n {{ calendarHeader }}\r\n </div>\r\n <div class=\"sub-header\">\r\n <div class=\"icons\">\r\n <span id=\"prev\" (click)=\"previous()\">\r\n <ng-template\r\n [ngTemplateOutlet]=\"\r\n config.previousButtonTemplate || defaultPreviousBTNTemplate\r\n \"></ng-template>\r\n </span>\r\n </div>\r\n <span class=\"current-date\">\r\n <span (click)=\"changeView('year')\">\r\n {{ currYear }}\r\n <ng-template\r\n [ngTemplateOutlet]=\"config.caretDownIconTemplate || defaultCaretDownIcon\"></ng-template>\r\n </span>\r\n <span (click)=\"changeView('month')\">\r\n {{ displayMonth }}\r\n <ng-template\r\n [ngTemplateOutlet]=\"config.caretDownIconTemplate || defaultCaretDownIcon\"></ng-template>\r\n </span>\r\n </span>\r\n <div class=\"icons\">\r\n <span id=\"next\" (click)=\"next()\">\r\n <ng-template\r\n [ngTemplateOutlet]=\"config.nextButtonTemplate || defaultNextBTNTemplate\"></ng-template>\r\n </span>\r\n </div>\r\n </div>\r\n <div class=\"calendar\">\r\n @if (view === 'day') {\r\n <ul class=\"weeks\">\r\n @for (w of weekDays; track $index) {\r\n <li [title]=\"w.name\">\r\n {{ w.min }}\r\n </li>\r\n }\r\n </ul>\r\n <ul class=\"days\">\r\n @for (item of viewDays; track $index) {\r\n <li\r\n [class.de-active]=\"!item.active\"\r\n [class.today]=\"item.isToday\"\r\n [class.selected]=\"item.selected\"\r\n (click)=\"selectDay($event, item)\">\r\n {{ item.day }}\r\n </li>\r\n }\r\n </ul>\r\n } @else if (view === 'month') {\r\n <ul class=\"months\">\r\n @for (item of viewMonths; track $index; let i = $index) {\r\n <li\r\n [class.de-active]=\"!item.active\"\r\n [class.today]=\"item.isToday\"\r\n [class.selected]=\"item.selected\"\r\n (click)=\"selectMonth($event, item)\">\r\n {{ i + 1 }}.{{ item.displayMonth }}\r\n </li>\r\n }\r\n </ul>\r\n } @else if (view === 'year') {\r\n <ul class=\"years\">\r\n @for (item of viewYears; track $index) {\r\n <li\r\n [class.de-active]=\"!item.active\"\r\n [class.today]=\"item.isToday\"\r\n [class.selected]=\"item.selected\"\r\n (click)=\"selectYear($event, item)\">\r\n {{ item.year }}\r\n </li>\r\n }\r\n </ul>\r\n }\r\n <!-- <pre>\r\n currYear={{currYear}}\r\n currMonth={{currMonth}}\r\n {{selected|json}}\r\n </pre> -->\r\n <div class=\"calendar-footer\">\r\n @if (config.clearButton) {\r\n <button (click)=\"clear()\">\r\n {{ localize().clear }}\r\n </button>\r\n }\r\n @if (config.todayButton) {\r\n <button (click)=\"gotoToday()\">\r\n {{ localize().today }}\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<ng-template #defaultPreviousBTNTemplate>\r\n <svg width=\"15px\" height=\"40px\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 320 512\">\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M224 480c-8.188 0-16.38-3.125-22.62-9.375l-192-192c-12.5-12.5-12.5-32.75 0-45.25l192-192c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25L77.25 256l169.4 169.4c12.5 12.5 12.5 32.75 0 45.25C240.4 476.9 232.2 480 224 480z\" />\r\n </svg>\r\n</ng-template>\r\n\r\n<ng-template #defaultNextBTNTemplate>\r\n <svg width=\"15px\" height=\"40px\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 320 512\">\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M96 480c-8.188 0-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L242.8 256L73.38 86.63c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l192 192c12.5 12.5 12.5 32.75 0 45.25l-192 192C112.4 476.9 104.2 480 96 480z\" />\r\n </svg>\r\n</ng-template>\r\n\r\n<ng-template #defaultCaretDownIcon>\r\n <svg width=\"10px\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 320 512\">\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M310.6 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z\" />\r\n </svg>\r\n</ng-template>\r\n", styles: [":host{--ngx-color-bg: light-dark(#fff, #0e1428);--ngx-color-text: light-dark(#000, #fff);--ngx-border-color: light-dark(#c0c0c0, #c0c0c0);--ngx-datepicker-header-bg: light-dark( linear-gradient(to right, #643edf, #865bf3), linear-gradient(to right, #34158c, #441ba8) );--ngx-datepicker-header-text: light-dark(#fff, #fff);--ngx-datepicker-subheader-bg: light-dark(#e0d5ef, #0f1529);--ngx-datepicker-subheader-text: light-dark(#272727, #d2b9f9);--ngx-datepicker-font-size: 12px;--ngx-datepicker-active-bg: light-dark( linear-gradient(to bottom, #8753ff, #5325c9), linear-gradient(to bottom, #8753ff, #5325c9) );--ngx-datepicker-active-text: light-dark(#fff, #fff);--ngx-datepicker-today-color: light-dark(#5325c9, #5325c9)}.wrapper{background:var(--ngx-color-bg);box-shadow:0 15px 40px #0000001f;color:var(--ngx-color-text);border-radius:6px;overflow:hidden;font-size:var(--ngx-datepicker-font-size);width:330px}.wrapper .header{display:flex;align-items:center;justify-content:center;text-align:center;padding:15px 15px 10px;background:var(--ngx-datepicker-header-bg);color:var(--ngx-datepicker-header-text);font-size:1.5em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wrapper .calendar-icon{background-color:#f3f3f33f;border-radius:29px;padding:6px;width:40px;height:40px;corner-shape:squircle;margin:0 6px}.wrapper .sub-header{display:flex;align-items:center;padding:5px 10px;background-color:var(--ngx-datepicker-subheader-bg);color:var(--ngx-datepicker-subheader-text)}.wrapper .sub-header .current-date{font-size:1.5em;flex:auto;display:flex;align-items:center}.wrapper .sub-header .current-date span{flex:auto;text-align:center}.wrapper .sub-header .icons{display:flex}.wrapper .sub-header .icons span{height:38px;width:38px;margin:0 1px;cursor:pointer;color:#878787;text-align:center;line-height:38px;font-size:1.9rem;-webkit-user-select:none;user-select:none;border:1px rgba(176,176,176,.0901960784) solid;border-radius:5px}.wrapper .sub-header .icons span:hover{background:#f2f2f225}.wrapper .calendar-footer{display:flex;justify-content:space-between;gap:5px}.wrapper .calendar-footer button{outline:none;background:none;color:inherit;border:none;border-radius:4px;padding:8px 15px;box-shadow:none;transition:all .3s;border:1px rgba(168,168,168,.1411764706) solid}.wrapper .calendar-footer button:not([disabled]):hover{cursor:pointer;background:#816ef175}.calendar{padding:10px}.calendar ul{display:flex;flex-wrap:wrap;list-style:none;text-align:center;padding:0;margin:0}.calendar .days{margin-bottom:20px}.calendar .days li{width:14.2857142857%;aspect-ratio:1/1}.calendar .months{margin-bottom:20px}.calendar .months li{width:33.3333333333%;height:44px}.calendar .years{margin-bottom:20px}.calendar .years li{width:25%;height:44px}.calendar li{z-index:1;cursor:pointer;position:relative;color:#333;font-size:1.2em;border-radius:50px;display:flex;align-items:center;justify-content:center;border:1px transparent solid;transition:all .3s;color:inherit}.calendar li:not(.active):hover{background:#dfdfdf68}.calendar li.de-active{opacity:.2}.calendar li.selected{background:var(--ngx-datepicker-active-bg)!important;color:var(--ngx-datepicker-active-text)}.calendar li.today{border:1px var(--ngx-datepicker-today-color) solid!important}.calendar .weeks{border-bottom:1px rgba(231,231,231,.3450980392) solid;margin-bottom:10px;padding-bottom:5px}.calendar .weeks li{font-weight:500;cursor:default;flex:auto;flex-wrap:nowrap}.calendar .weeks li:hover{background:none}::ng-deep body[dir=rtl] .wrapper .sub-header .icons #next,::ng-deep body[dir=rtl] .wrapper .sub-header .icons #prev,::ng-deep html[dir=rtl] .wrapper .sub-header .icons #next,::ng-deep html[dir=rtl] .wrapper .sub-header .icons #prev{transform:rotate(180deg)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
|
|
1833
1935
|
}
|
|
1834
1936
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NgxInputDatePickerComponent, decorators: [{
|
|
1835
1937
|
type: Component,
|
|
@@ -1845,13 +1947,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
1845
1947
|
useExisting: forwardRef(() => NgxInputDatePickerComponent),
|
|
1846
1948
|
multi: true,
|
|
1847
1949
|
},
|
|
1848
|
-
], host: {
|
|
1849
|
-
|
|
1850
|
-
}, template: "<div\r\n class=\"wrapper\"\r\n #datepickerWrapper\r\n [style.width.px]=\"wrapperWidth\"\r\n (click)=\"stopPagination($event)\">\r\n <div class=\"header\">\r\n {{ calendarHeader }}\r\n </div>\r\n <div class=\"sub-header\">\r\n <div class=\"icons\">\r\n <span id=\"prev\" class=\"material-symbols-rounded\" (click)=\"previous()\">\r\n <ng-template\r\n [ngTemplateOutlet]=\"\r\n config.previousButtonTemplate || defaultPreviousBTNTemplate\r\n \"></ng-template>\r\n </span>\r\n </div>\r\n <span class=\"current-date\">\r\n <span (click)=\"changeView('year')\">\r\n {{ currYear }}\r\n <ng-template\r\n [ngTemplateOutlet]=\"config.caretDownIconTemplate || defaultCaretDownIcon\"></ng-template>\r\n </span>\r\n <span (click)=\"changeView('month')\">\r\n {{ displayMonth }}\r\n <ng-template\r\n [ngTemplateOutlet]=\"config.caretDownIconTemplate || defaultCaretDownIcon\"></ng-template>\r\n </span>\r\n </span>\r\n <div class=\"icons\">\r\n <span id=\"next\" class=\"material-symbols-rounded\" (click)=\"next()\">\r\n <ng-template\r\n [ngTemplateOutlet]=\"config.nextButtonTemplate || defaultNextBTNTemplate\"></ng-template>\r\n </span>\r\n </div>\r\n </div>\r\n <div class=\"calendar\">\r\n @if (view === 'day') {\r\n <ul class=\"weeks\">\r\n @for (w of weekDays; track $index) {\r\n <li [title]=\"w.name\">\r\n {{ w.min }}\r\n </li>\r\n }\r\n </ul>\r\n <ul class=\"days\">\r\n @for (item of viewDays; track $index) {\r\n <li\r\n [class.de-active]=\"!item.active\"\r\n [class.today]=\"item.isToday\"\r\n [class.selected]=\"item.selected\"\r\n (click)=\"selectDay($event, item)\">\r\n {{ item.day }}\r\n </li>\r\n }\r\n </ul>\r\n } @else if (view === 'month') {\r\n <ul class=\"months\">\r\n @for (item of viewMonths; track $index; let i = $index) {\r\n <li\r\n [class.de-active]=\"!item.active\"\r\n [class.today]=\"item.isToday\"\r\n [class.selected]=\"item.selected\"\r\n (click)=\"selectMonth($event, item)\">\r\n {{ i + 1 }}.{{ item.displayMonth }}\r\n </li>\r\n }\r\n </ul>\r\n } @else if (view === 'year') {\r\n <ul class=\"years\">\r\n @for (item of viewYears; track $index) {\r\n <li\r\n [class.de-active]=\"!item.active\"\r\n [class.today]=\"item.isToday\"\r\n [class.selected]=\"item.selected\"\r\n (click)=\"selectYear($event, item)\">\r\n {{ item.year }}\r\n </li>\r\n }\r\n </ul>\r\n }\r\n <!-- <pre>\r\n currYear={{currYear}}\r\n currMonth={{currMonth}}\r\n {{selected|json}}\r\n </pre> -->\r\n <div class=\"calendar-footer\">\r\n @if (config.clearButton) {\r\n <button (click)=\"clear()\">\r\n {{ config.clearButtonText }}\r\n </button>\r\n }\r\n @if (config.todayButton) {\r\n <button (click)=\"gotoToday()\">\r\n {{ config.todayButtonText }}\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<ng-template #defaultPreviousBTNTemplate>\r\n <svg width=\"15px\" height=\"40px\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 320 512\">\r\n <path\r\n class=\"fa-secondary\"\r\n d=\"M224 480c-8.188 0-16.38-3.125-22.62-9.375l-192-192c-12.5-12.5-12.5-32.75 0-45.25l192-192c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25L77.25 256l169.4 169.4c12.5 12.5 12.5 32.75 0 45.25C240.4 476.9 232.2 480 224 480z\" />\r\n </svg>\r\n</ng-template>\r\n\r\n<ng-template #defaultNextBTNTemplate>\r\n <svg width=\"15px\" height=\"40px\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 320 512\">\r\n <path\r\n class=\"fa-secondary\"\r\n d=\"M96 480c-8.188 0-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L242.8 256L73.38 86.63c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l192 192c12.5 12.5 12.5 32.75 0 45.25l-192 192C112.4 476.9 104.2 480 96 480z\" />\r\n </svg>\r\n</ng-template>\r\n\r\n<ng-template #defaultCaretDownIcon>\r\n <svg width=\"10px\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 320 512\">\r\n <path\r\n class=\"fa-secondary\"\r\n d=\"M310.6 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z\" />\r\n </svg>\r\n</ng-template>\r\n", styles: [":host{--ngx-color-bg: #fff;--ngx-color-text: #000;--ngx-border-color: #c0c0c0;--ngx-datepicker-header-bg: #6200ee;--ngx-datepicker-header-text: #fff;--ngx-datepicker-subheader-bg: #e0d5ef;--ngx-datepicker-subheader-text: #272727}:host-context(.dark){--ngx-color-bg: #222;--ngx-color-text: #fff;--ngx-border-color: #c0c0c0;--ngx-datepicker-header-bg: #6200ee;--ngx-datepicker-header-text: #fff;--ngx-datepicker-subheader-bg: #8e819e;--ngx-datepicker-subheader-text: #272727}.wrapper{background:var(--ngx-color-bg);box-shadow:0 15px 40px #0000001f;color:var(--ngx-color-text);border-radius:6px;overflow:hidden}.wrapper .header{display:block;padding:15px 15px 10px;background-color:var(--ngx-datepicker-header-bg);color:var(--ngx-datepicker-header-text);font-size:18px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center}.wrapper .sub-header{display:flex;align-items:center;padding:5px 10px;background-color:var(--ngx-datepicker-subheader-bg);color:var(--ngx-datepicker-subheader-text)}.wrapper .sub-header .current-date{font-size:1rem;font-weight:800;flex:auto;display:flex;align-items:center}.wrapper .sub-header .current-date span{flex:auto;text-align:center}.wrapper .sub-header .icons{display:flex}.wrapper .sub-header .icons span{height:38px;width:38px;margin:0 1px;cursor:pointer;color:#878787;text-align:center;line-height:38px;font-size:1.9rem;-webkit-user-select:none;user-select:none;border-radius:50%}.wrapper .sub-header .icons span:hover{background:#f2f2f272}.wrapper .calendar-footer{display:flex;justify-content:space-between;gap:5px}.wrapper .calendar-footer button{outline:none;background:none;color:inherit;border:none;border-radius:4px;padding:8px 15px;box-shadow:none;transition:all .3s}.wrapper .calendar-footer button:not([disabled]):hover{cursor:pointer;background:#816ef175}.calendar{padding:10px}.calendar ul{display:flex;flex-wrap:wrap;list-style:none;text-align:center;padding:0;margin:0}.calendar .days{margin-bottom:20px}.calendar .days li{height:40px;width:40px}.calendar .months{margin-bottom:20px}.calendar .months li{height:40px;width:33%}.calendar .years{margin-bottom:20px}.calendar .years li{height:40px;width:25%}.calendar li{z-index:1;cursor:pointer;position:relative;color:#333;font-size:12px;border-radius:50px;display:flex;align-items:center;justify-content:center;border:1px transparent solid;transition:all .3s;color:inherit}.calendar li:not(.active):hover{background:#dfdfdf68}.calendar li.de-active{opacity:.2}.calendar li.selected{border:1px #1216fa solid}.calendar li.today{background-color:#9b59b6}.calendar .weeks{border-bottom:1px rgba(231,231,231,.3450980392) solid;margin-bottom:10px;padding-bottom:5px}.calendar .weeks li{font-weight:500;cursor:default;flex:auto;flex-wrap:nowrap}.calendar .weeks li:hover{background:none}::ng-deep body[dir=rtl] .wrapper .sub-header .icons #next,::ng-deep body[dir=rtl] .wrapper .sub-header .icons #prev,::ng-deep html[dir=rtl] .wrapper .sub-header .icons #next,::ng-deep html[dir=rtl] .wrapper .sub-header .icons #prev{transform:rotate(180deg)}\n"] }]
|
|
1851
|
-
}], ctorParameters: () => [], propDecorators: { setTheme: [{
|
|
1852
|
-
type: Input,
|
|
1853
|
-
args: ['theme']
|
|
1854
|
-
}], setConfig: [{
|
|
1950
|
+
], template: "<div class=\"wrapper\" #datepickerWrapper (click)=\"stopPagination($event)\">\r\n <div class=\"header\">\r\n <svg\r\n class=\"calendar-icon\"\r\n width=\"24\"\r\n height=\"24\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\">\r\n <path\r\n d=\"M16 2V6M8 2V6\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.5\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M13 4H11C7.22876 4 5.34315 4 4.17157 5.17157C3 6.34315 3 8.22876 3 12V14C3 17.7712 3 19.6569 4.17157 20.8284C5.34315 22 7.22876 22 11 22H13C16.7712 22 18.6569 22 19.8284 20.8284C21 19.6569 21 17.7712 21 14V12C21 8.22876 21 6.34315 19.8284 5.17157C18.6569 4 16.7712 4 13 4Z\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.5\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M3 10H21\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"1.5\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M11.9955 14H12.0045M11.9955 18H12.0045M15.991 14H16M8 14H8.00897M8 18H8.00897\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n {{ calendarHeader }}\r\n </div>\r\n <div class=\"sub-header\">\r\n <div class=\"icons\">\r\n <span id=\"prev\" (click)=\"previous()\">\r\n <ng-template\r\n [ngTemplateOutlet]=\"\r\n config.previousButtonTemplate || defaultPreviousBTNTemplate\r\n \"></ng-template>\r\n </span>\r\n </div>\r\n <span class=\"current-date\">\r\n <span (click)=\"changeView('year')\">\r\n {{ currYear }}\r\n <ng-template\r\n [ngTemplateOutlet]=\"config.caretDownIconTemplate || defaultCaretDownIcon\"></ng-template>\r\n </span>\r\n <span (click)=\"changeView('month')\">\r\n {{ displayMonth }}\r\n <ng-template\r\n [ngTemplateOutlet]=\"config.caretDownIconTemplate || defaultCaretDownIcon\"></ng-template>\r\n </span>\r\n </span>\r\n <div class=\"icons\">\r\n <span id=\"next\" (click)=\"next()\">\r\n <ng-template\r\n [ngTemplateOutlet]=\"config.nextButtonTemplate || defaultNextBTNTemplate\"></ng-template>\r\n </span>\r\n </div>\r\n </div>\r\n <div class=\"calendar\">\r\n @if (view === 'day') {\r\n <ul class=\"weeks\">\r\n @for (w of weekDays; track $index) {\r\n <li [title]=\"w.name\">\r\n {{ w.min }}\r\n </li>\r\n }\r\n </ul>\r\n <ul class=\"days\">\r\n @for (item of viewDays; track $index) {\r\n <li\r\n [class.de-active]=\"!item.active\"\r\n [class.today]=\"item.isToday\"\r\n [class.selected]=\"item.selected\"\r\n (click)=\"selectDay($event, item)\">\r\n {{ item.day }}\r\n </li>\r\n }\r\n </ul>\r\n } @else if (view === 'month') {\r\n <ul class=\"months\">\r\n @for (item of viewMonths; track $index; let i = $index) {\r\n <li\r\n [class.de-active]=\"!item.active\"\r\n [class.today]=\"item.isToday\"\r\n [class.selected]=\"item.selected\"\r\n (click)=\"selectMonth($event, item)\">\r\n {{ i + 1 }}.{{ item.displayMonth }}\r\n </li>\r\n }\r\n </ul>\r\n } @else if (view === 'year') {\r\n <ul class=\"years\">\r\n @for (item of viewYears; track $index) {\r\n <li\r\n [class.de-active]=\"!item.active\"\r\n [class.today]=\"item.isToday\"\r\n [class.selected]=\"item.selected\"\r\n (click)=\"selectYear($event, item)\">\r\n {{ item.year }}\r\n </li>\r\n }\r\n </ul>\r\n }\r\n <!-- <pre>\r\n currYear={{currYear}}\r\n currMonth={{currMonth}}\r\n {{selected|json}}\r\n </pre> -->\r\n <div class=\"calendar-footer\">\r\n @if (config.clearButton) {\r\n <button (click)=\"clear()\">\r\n {{ localize().clear }}\r\n </button>\r\n }\r\n @if (config.todayButton) {\r\n <button (click)=\"gotoToday()\">\r\n {{ localize().today }}\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<ng-template #defaultPreviousBTNTemplate>\r\n <svg width=\"15px\" height=\"40px\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 320 512\">\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M224 480c-8.188 0-16.38-3.125-22.62-9.375l-192-192c-12.5-12.5-12.5-32.75 0-45.25l192-192c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25L77.25 256l169.4 169.4c12.5 12.5 12.5 32.75 0 45.25C240.4 476.9 232.2 480 224 480z\" />\r\n </svg>\r\n</ng-template>\r\n\r\n<ng-template #defaultNextBTNTemplate>\r\n <svg width=\"15px\" height=\"40px\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 320 512\">\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M96 480c-8.188 0-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L242.8 256L73.38 86.63c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l192 192c12.5 12.5 12.5 32.75 0 45.25l-192 192C112.4 476.9 104.2 480 96 480z\" />\r\n </svg>\r\n</ng-template>\r\n\r\n<ng-template #defaultCaretDownIcon>\r\n <svg width=\"10px\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 320 512\">\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M310.6 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z\" />\r\n </svg>\r\n</ng-template>\r\n", styles: [":host{--ngx-color-bg: light-dark(#fff, #0e1428);--ngx-color-text: light-dark(#000, #fff);--ngx-border-color: light-dark(#c0c0c0, #c0c0c0);--ngx-datepicker-header-bg: light-dark( linear-gradient(to right, #643edf, #865bf3), linear-gradient(to right, #34158c, #441ba8) );--ngx-datepicker-header-text: light-dark(#fff, #fff);--ngx-datepicker-subheader-bg: light-dark(#e0d5ef, #0f1529);--ngx-datepicker-subheader-text: light-dark(#272727, #d2b9f9);--ngx-datepicker-font-size: 12px;--ngx-datepicker-active-bg: light-dark( linear-gradient(to bottom, #8753ff, #5325c9), linear-gradient(to bottom, #8753ff, #5325c9) );--ngx-datepicker-active-text: light-dark(#fff, #fff);--ngx-datepicker-today-color: light-dark(#5325c9, #5325c9)}.wrapper{background:var(--ngx-color-bg);box-shadow:0 15px 40px #0000001f;color:var(--ngx-color-text);border-radius:6px;overflow:hidden;font-size:var(--ngx-datepicker-font-size);width:330px}.wrapper .header{display:flex;align-items:center;justify-content:center;text-align:center;padding:15px 15px 10px;background:var(--ngx-datepicker-header-bg);color:var(--ngx-datepicker-header-text);font-size:1.5em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wrapper .calendar-icon{background-color:#f3f3f33f;border-radius:29px;padding:6px;width:40px;height:40px;corner-shape:squircle;margin:0 6px}.wrapper .sub-header{display:flex;align-items:center;padding:5px 10px;background-color:var(--ngx-datepicker-subheader-bg);color:var(--ngx-datepicker-subheader-text)}.wrapper .sub-header .current-date{font-size:1.5em;flex:auto;display:flex;align-items:center}.wrapper .sub-header .current-date span{flex:auto;text-align:center}.wrapper .sub-header .icons{display:flex}.wrapper .sub-header .icons span{height:38px;width:38px;margin:0 1px;cursor:pointer;color:#878787;text-align:center;line-height:38px;font-size:1.9rem;-webkit-user-select:none;user-select:none;border:1px rgba(176,176,176,.0901960784) solid;border-radius:5px}.wrapper .sub-header .icons span:hover{background:#f2f2f225}.wrapper .calendar-footer{display:flex;justify-content:space-between;gap:5px}.wrapper .calendar-footer button{outline:none;background:none;color:inherit;border:none;border-radius:4px;padding:8px 15px;box-shadow:none;transition:all .3s;border:1px rgba(168,168,168,.1411764706) solid}.wrapper .calendar-footer button:not([disabled]):hover{cursor:pointer;background:#816ef175}.calendar{padding:10px}.calendar ul{display:flex;flex-wrap:wrap;list-style:none;text-align:center;padding:0;margin:0}.calendar .days{margin-bottom:20px}.calendar .days li{width:14.2857142857%;aspect-ratio:1/1}.calendar .months{margin-bottom:20px}.calendar .months li{width:33.3333333333%;height:44px}.calendar .years{margin-bottom:20px}.calendar .years li{width:25%;height:44px}.calendar li{z-index:1;cursor:pointer;position:relative;color:#333;font-size:1.2em;border-radius:50px;display:flex;align-items:center;justify-content:center;border:1px transparent solid;transition:all .3s;color:inherit}.calendar li:not(.active):hover{background:#dfdfdf68}.calendar li.de-active{opacity:.2}.calendar li.selected{background:var(--ngx-datepicker-active-bg)!important;color:var(--ngx-datepicker-active-text)}.calendar li.today{border:1px var(--ngx-datepicker-today-color) solid!important}.calendar .weeks{border-bottom:1px rgba(231,231,231,.3450980392) solid;margin-bottom:10px;padding-bottom:5px}.calendar .weeks li{font-weight:500;cursor:default;flex:auto;flex-wrap:nowrap}.calendar .weeks li:hover{background:none}::ng-deep body[dir=rtl] .wrapper .sub-header .icons #next,::ng-deep body[dir=rtl] .wrapper .sub-header .icons #prev,::ng-deep html[dir=rtl] .wrapper .sub-header .icons #next,::ng-deep html[dir=rtl] .wrapper .sub-header .icons #prev{transform:rotate(180deg)}\n"] }]
|
|
1951
|
+
}], ctorParameters: () => [], propDecorators: { localize: [{ type: i0.Input, args: [{ isSignal: true, alias: "localize", required: false }] }], setConfig: [{
|
|
1855
1952
|
type: Input,
|
|
1856
1953
|
args: ['config']
|
|
1857
1954
|
}], locale: [{
|
|
@@ -1871,7 +1968,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
1871
1968
|
class NgxInputDatePicker {
|
|
1872
1969
|
el;
|
|
1873
1970
|
dateAdapterRegistry = inject(DateAdapterRegistry);
|
|
1874
|
-
theme = 'auto';
|
|
1875
1971
|
openOnCLick = input(true, /* @ts-ignore */
|
|
1876
1972
|
...(ngDevMode ? [{ debugName: "openOnCLick" }] : /* istanbul ignore next */ []));
|
|
1877
1973
|
change = new EventEmitter();
|
|
@@ -1984,7 +2080,6 @@ class NgxInputDatePicker {
|
|
|
1984
2080
|
instance.locale = this._locale;
|
|
1985
2081
|
instance.minDate = this.min;
|
|
1986
2082
|
instance.maxDate = this.max;
|
|
1987
|
-
instance.setTheme = this.theme;
|
|
1988
2083
|
instance.updateConfig(this.config);
|
|
1989
2084
|
instance.writeValue(this.value);
|
|
1990
2085
|
instance.change.subscribe((c) => {
|
|
@@ -2045,7 +2140,7 @@ class NgxInputDatePicker {
|
|
|
2045
2140
|
}
|
|
2046
2141
|
}
|
|
2047
2142
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NgxInputDatePicker, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
2048
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.4", type: NgxInputDatePicker, isStandalone: true, selector: "[ngxInputDatePicker]", inputs: {
|
|
2143
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.4", type: NgxInputDatePicker, isStandalone: true, selector: "[ngxInputDatePicker]", inputs: { openOnCLick: { classPropertyName: "openOnCLick", publicName: "openOnCLick", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: false, isRequired: false, transformFunction: null }, displayFormat: { classPropertyName: "displayFormat", publicName: "displayFormat", isSignal: false, isRequired: false, transformFunction: null }, setMin: { classPropertyName: "setMin", publicName: "min", isSignal: false, isRequired: false, transformFunction: null }, setMax: { classPropertyName: "setMax", publicName: "max", isSignal: false, isRequired: false, transformFunction: null }, setConfig: { classPropertyName: "setConfig", publicName: "config", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { change: "change" }, host: { listeners: { "click": "onClick($event)", "input": "onInput($event)", "blur": "onBlur()" }, properties: { "attr.readOnly": "true" }, classAttribute: "ngx-datepicker-input" }, providers: [
|
|
2049
2144
|
DateAdapterRegistry,
|
|
2050
2145
|
{
|
|
2051
2146
|
provide: NG_VALUE_ACCESSOR,
|
|
@@ -2082,9 +2177,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
2082
2177
|
},
|
|
2083
2178
|
],
|
|
2084
2179
|
}]
|
|
2085
|
-
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: {
|
|
2086
|
-
type: Input
|
|
2087
|
-
}], openOnCLick: [{ type: i0.Input, args: [{ isSignal: true, alias: "openOnCLick", required: false }] }], change: [{
|
|
2180
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { openOnCLick: [{ type: i0.Input, args: [{ isSignal: true, alias: "openOnCLick", required: false }] }], change: [{
|
|
2088
2181
|
type: Output
|
|
2089
2182
|
}], locale: [{
|
|
2090
2183
|
type: Input
|
|
@@ -2110,17 +2203,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
2110
2203
|
args: ['blur']
|
|
2111
2204
|
}] } });
|
|
2112
2205
|
|
|
2206
|
+
const HOUR_HEIGHT = 64;
|
|
2207
|
+
const HALF_HOUR_HEIGHT = HOUR_HEIGHT / 2;
|
|
2208
|
+
const MIN_EVENT_MINUTES = 30;
|
|
2209
|
+
const MONTH_ROW_COUNT = 6;
|
|
2210
|
+
const MONTH_COLUMN_COUNT = 7;
|
|
2113
2211
|
class NgxCalendarComponent extends NgxDatePickerBase {
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
if (!val || val == 'auto') {
|
|
2118
|
-
this.theme = this.browserService.prefersDarkMode ? 'dark' : 'light';
|
|
2119
|
-
}
|
|
2120
|
-
else {
|
|
2121
|
-
this.theme = val;
|
|
2122
|
-
}
|
|
2123
|
-
}
|
|
2212
|
+
defaultLocalization = inject(NGX_CALENDAR_LOCALIZATION);
|
|
2213
|
+
localize = input(this.defaultLocalization, /* @ts-ignore */
|
|
2214
|
+
...(ngDevMode ? [{ debugName: "localize" }] : /* istanbul ignore next */ []));
|
|
2124
2215
|
_config = new NgxDatePickerConfig();
|
|
2125
2216
|
set config(val) {
|
|
2126
2217
|
this._config = { ...new NgxDatePickerConfig(), ...val };
|
|
@@ -2128,150 +2219,626 @@ class NgxCalendarComponent extends NgxDatePickerBase {
|
|
|
2128
2219
|
set locale(val) {
|
|
2129
2220
|
this._locale = val;
|
|
2130
2221
|
this.adapter = this.dateAdapterRegistry.resolve(this._locale);
|
|
2131
|
-
this.
|
|
2222
|
+
if (this.currYear !== undefined)
|
|
2223
|
+
this.syncAnchorToLocale();
|
|
2224
|
+
this.renderCalendar(this.view);
|
|
2132
2225
|
}
|
|
2133
|
-
/** The minimum valid date. */
|
|
2134
2226
|
set setMin(value) {
|
|
2135
2227
|
const validValue = deserialize(value);
|
|
2136
2228
|
if (!sameDate(validValue, this.minDate)) {
|
|
2137
2229
|
this.minDate = validValue;
|
|
2230
|
+
this.renderCalendar(this.view);
|
|
2138
2231
|
}
|
|
2139
2232
|
}
|
|
2140
|
-
/** The maximum valid date. */
|
|
2141
2233
|
set setMax(value) {
|
|
2142
2234
|
const validValue = deserialize(value);
|
|
2143
2235
|
if (!sameDate(validValue, this.maxDate)) {
|
|
2144
2236
|
this.maxDate = validValue;
|
|
2237
|
+
this.renderCalendar(this.view);
|
|
2145
2238
|
}
|
|
2146
2239
|
}
|
|
2147
|
-
view = '
|
|
2240
|
+
view = 'month';
|
|
2148
2241
|
_events = [];
|
|
2149
2242
|
set events(val) {
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2243
|
+
this._events = Array.isArray(val) ? val : [];
|
|
2244
|
+
if (this.anchorDate)
|
|
2245
|
+
this.renderCalendar(this.view);
|
|
2246
|
+
}
|
|
2247
|
+
get events() {
|
|
2248
|
+
return this._events;
|
|
2153
2249
|
}
|
|
2154
2250
|
dateChange = new EventEmitter();
|
|
2155
2251
|
selectEvent = new EventEmitter();
|
|
2156
|
-
|
|
2157
|
-
|
|
2252
|
+
eventChange = new EventEmitter();
|
|
2253
|
+
eventsChange = new EventEmitter();
|
|
2158
2254
|
selected;
|
|
2255
|
+
anchorDate;
|
|
2256
|
+
eventViewItems = [];
|
|
2257
|
+
monthEventSegments = [];
|
|
2258
|
+
monthEventRows = Array.from({ length: MONTH_ROW_COUNT }, () => []);
|
|
2259
|
+
weekDays = [];
|
|
2260
|
+
allDayByColumn = [];
|
|
2261
|
+
timeSlots = Array.from({ length: 48 }, (_, i) => i * 30);
|
|
2262
|
+
hourHeight = HOUR_HEIGHT;
|
|
2263
|
+
timeColumnWidth = 64;
|
|
2159
2264
|
calendarWrapper = viewChild('calendarWrapper', /* @ts-ignore */
|
|
2160
2265
|
...(ngDevMode ? [{ debugName: "calendarWrapper" }] : /* istanbul ignore next */ []));
|
|
2266
|
+
interaction = null;
|
|
2161
2267
|
constructor() {
|
|
2162
2268
|
super();
|
|
2163
2269
|
}
|
|
2164
2270
|
ngOnInit() {
|
|
2165
2271
|
this.months = this.adapter.longMonths;
|
|
2166
2272
|
this.weeks = this.adapter.longDays;
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
this.
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
}
|
|
2173
|
-
else {
|
|
2174
|
-
this.gotoToday();
|
|
2175
|
-
}
|
|
2273
|
+
this.anchorDate = this.selected
|
|
2274
|
+
? new Date(this.selected)
|
|
2275
|
+
: this.adapter.getDate(this.adapter.today());
|
|
2276
|
+
this.syncAnchorToLocale();
|
|
2277
|
+
this.renderCalendar(this.view);
|
|
2176
2278
|
}
|
|
2177
|
-
|
|
2279
|
+
onResize() {
|
|
2178
2280
|
this.calcCellSize();
|
|
2179
2281
|
}
|
|
2180
|
-
|
|
2181
|
-
this.
|
|
2282
|
+
onDocumentPointerMove(event) {
|
|
2283
|
+
if (!this.interaction || event.pointerId !== this.interaction.pointerId)
|
|
2284
|
+
return;
|
|
2285
|
+
this.updateEventInteraction(event);
|
|
2286
|
+
}
|
|
2287
|
+
onDocumentPointerUp(event) {
|
|
2288
|
+
if (!this.interaction || event.pointerId !== this.interaction.pointerId)
|
|
2289
|
+
return;
|
|
2290
|
+
this.finishEventInteraction(event, false);
|
|
2291
|
+
}
|
|
2292
|
+
onDocumentPointerCancel(event) {
|
|
2293
|
+
if (!this.interaction || event.pointerId !== this.interaction.pointerId)
|
|
2294
|
+
return;
|
|
2295
|
+
this.finishEventInteraction(event, true);
|
|
2182
2296
|
}
|
|
2183
2297
|
calcCellSize() {
|
|
2184
2298
|
const fullWidth = this.calendarWrapper()?.nativeElement?.clientWidth ?? 0;
|
|
2185
|
-
|
|
2186
|
-
this.
|
|
2187
|
-
|
|
2188
|
-
|
|
2299
|
+
this.minHeight = fullWidth > this.defaultHeight ? this.defaultHeight : Math.max(fullWidth, 320);
|
|
2300
|
+
this.weeks = fullWidth <= 500 ? this.adapter.shortDays : this.adapter.longDays;
|
|
2301
|
+
}
|
|
2302
|
+
renderCalendar(view) {
|
|
2303
|
+
if (!this.anchorDate)
|
|
2304
|
+
return;
|
|
2305
|
+
this.syncAnchorToLocale();
|
|
2306
|
+
switch (view) {
|
|
2307
|
+
case 'month':
|
|
2308
|
+
super.renderCalendar('month', undefined, this.renderEvents);
|
|
2309
|
+
this.buildMonthEventSegments();
|
|
2310
|
+
break;
|
|
2311
|
+
case 'week':
|
|
2312
|
+
case 'day':
|
|
2313
|
+
this.renderTimedView();
|
|
2314
|
+
break;
|
|
2315
|
+
case 'event':
|
|
2316
|
+
this.renderEventView();
|
|
2317
|
+
break;
|
|
2318
|
+
}
|
|
2319
|
+
this.displayMonth = this.months[this.currMonth] ?? '';
|
|
2320
|
+
queueMicrotask(() => this.calcCellSize());
|
|
2321
|
+
}
|
|
2322
|
+
get renderEvents() {
|
|
2323
|
+
return this._events;
|
|
2324
|
+
}
|
|
2325
|
+
syncAnchorToLocale() {
|
|
2326
|
+
const localeDate = this.adapter.toLocale(this.anchorDate);
|
|
2327
|
+
this.currYear = localeDate.year;
|
|
2328
|
+
this.currMonth = localeDate.month ?? 0;
|
|
2329
|
+
this.months = this.adapter.longMonths;
|
|
2330
|
+
this.weeks = this.adapter.longDays;
|
|
2331
|
+
}
|
|
2332
|
+
renderTimedView() {
|
|
2333
|
+
const dates = this.getWeekDates(this.anchorDate);
|
|
2334
|
+
const visibleDates = this.view === 'day' ? [new Date(this.startOfDay(this.anchorDate))] : dates;
|
|
2335
|
+
this.weekDays = visibleDates.map((date, column) => ({
|
|
2336
|
+
date,
|
|
2337
|
+
label: this.adapter.formatDate(this.adapter.toLocale(date), 'full') ?? '',
|
|
2338
|
+
dayNumber: String(this.adapter.toLocale(date).day),
|
|
2339
|
+
isToday: sameDate(date, this.adapter.getDate(this.adapter.today())),
|
|
2340
|
+
events: this.buildTimedEventsForDay(date, column, visibleDates.length),
|
|
2341
|
+
}));
|
|
2342
|
+
this.allDayByColumn = this.weekDays.map((day, column) => this.buildAllDayEventsForDay(day.date, column));
|
|
2343
|
+
this.viewWeeks = this.timeSlots.map((minutes) => ({
|
|
2344
|
+
time: minutes / 60,
|
|
2345
|
+
displayTime: this.formatTime(minutes),
|
|
2346
|
+
weeks: visibleDates.map(() => ''),
|
|
2347
|
+
active: true,
|
|
2348
|
+
selected: false,
|
|
2349
|
+
}));
|
|
2350
|
+
}
|
|
2351
|
+
/**
|
|
2352
|
+
* Builds a collision layout per overlap cluster. Each cluster gets its own
|
|
2353
|
+
* column count, which prevents a short 09:00 event from being unnecessarily
|
|
2354
|
+
* squeezed because another event overlaps at 15:00.
|
|
2355
|
+
*/
|
|
2356
|
+
buildTimedEventsForDay(date, column, columnCount) {
|
|
2357
|
+
const dayStart = this.startOfDay(date);
|
|
2358
|
+
const dayEnd = this.endOfDay(date);
|
|
2359
|
+
const candidates = this.normalizedEvents()
|
|
2360
|
+
.filter(({ start, end, source }) => !source.allDay &&
|
|
2361
|
+
!Number.isNaN(start.getTime()) &&
|
|
2362
|
+
end.getTime() >= dayStart.getTime() &&
|
|
2363
|
+
start.getTime() <= dayEnd.getTime())
|
|
2364
|
+
.map(({ source, start, end }) => {
|
|
2365
|
+
const segmentStart = new Date(Math.max(start.getTime(), dayStart.getTime()));
|
|
2366
|
+
const segmentEnd = new Date(Math.min(end.getTime(), dayEnd.getTime()));
|
|
2367
|
+
return {
|
|
2368
|
+
...source,
|
|
2369
|
+
start,
|
|
2370
|
+
end,
|
|
2371
|
+
segmentStart,
|
|
2372
|
+
segmentEnd,
|
|
2373
|
+
allDay: false,
|
|
2374
|
+
continuesBefore: start.getTime() < dayStart.getTime(),
|
|
2375
|
+
continuesAfter: end.getTime() > dayEnd.getTime(),
|
|
2376
|
+
isStart: start.getTime() >= dayStart.getTime() && start.getTime() <= dayEnd.getTime(),
|
|
2377
|
+
isEnd: end.getTime() >= dayStart.getTime() && end.getTime() <= dayEnd.getTime(),
|
|
2378
|
+
column,
|
|
2379
|
+
columnCount,
|
|
2380
|
+
};
|
|
2381
|
+
})
|
|
2382
|
+
.sort((a, b) => a.segmentStart.getTime() - b.segmentStart.getTime() ||
|
|
2383
|
+
b.segmentEnd.getTime() - a.segmentEnd.getTime());
|
|
2384
|
+
const result = [];
|
|
2385
|
+
let cluster = [];
|
|
2386
|
+
let clusterLanes = [];
|
|
2387
|
+
let clusterEnd = -Infinity;
|
|
2388
|
+
const flushCluster = () => {
|
|
2389
|
+
if (!cluster.length)
|
|
2390
|
+
return;
|
|
2391
|
+
const laneCount = clusterLanes.length;
|
|
2392
|
+
for (const item of cluster) {
|
|
2393
|
+
item.columnCount = laneCount;
|
|
2394
|
+
}
|
|
2395
|
+
result.push(...cluster);
|
|
2396
|
+
cluster = [];
|
|
2397
|
+
clusterLanes = [];
|
|
2398
|
+
clusterEnd = -Infinity;
|
|
2399
|
+
};
|
|
2400
|
+
for (const e of candidates) {
|
|
2401
|
+
const start = e.segmentStart.getTime();
|
|
2402
|
+
if (cluster.length && start > clusterEnd)
|
|
2403
|
+
flushCluster();
|
|
2404
|
+
let lane = clusterLanes.findIndex((items) => {
|
|
2405
|
+
const last = items[items.length - 1];
|
|
2406
|
+
return last.segmentEnd.getTime() <= start;
|
|
2407
|
+
});
|
|
2408
|
+
if (lane < 0) {
|
|
2409
|
+
lane = clusterLanes.length;
|
|
2410
|
+
clusterLanes.push([]);
|
|
2411
|
+
}
|
|
2412
|
+
const positioned = { ...e, lane, column: lane };
|
|
2413
|
+
clusterLanes[lane].push(positioned);
|
|
2414
|
+
cluster.push(positioned);
|
|
2415
|
+
clusterEnd = Math.max(clusterEnd, e.segmentEnd.getTime());
|
|
2416
|
+
const startMinutes = e.segmentStart.getHours() * 60 + e.segmentStart.getMinutes();
|
|
2417
|
+
const endMinutes = e.segmentEnd.getHours() * 60 + e.segmentEnd.getMinutes();
|
|
2418
|
+
const effectiveEnd = Math.max(endMinutes, startMinutes + MIN_EVENT_MINUTES);
|
|
2419
|
+
positioned.top = (startMinutes / 60) * HOUR_HEIGHT;
|
|
2420
|
+
positioned.height = Math.max(((effectiveEnd - startMinutes) / 60) * HOUR_HEIGHT, 28);
|
|
2421
|
+
}
|
|
2422
|
+
flushCluster();
|
|
2423
|
+
return result
|
|
2424
|
+
.concat(cluster)
|
|
2425
|
+
.map(({ lane, segmentStart, segmentEnd, ...event }) => event);
|
|
2426
|
+
}
|
|
2427
|
+
buildAllDayEventsForDay(date, column) {
|
|
2428
|
+
const dayStart = this.startOfDay(date);
|
|
2429
|
+
const dayEnd = this.endOfDay(date);
|
|
2430
|
+
return this.normalizedEvents()
|
|
2431
|
+
.filter(({ source, start, end }) => !!source.allDay &&
|
|
2432
|
+
!Number.isNaN(start.getTime()) &&
|
|
2433
|
+
end.getTime() >= dayStart.getTime() &&
|
|
2434
|
+
start.getTime() <= dayEnd.getTime())
|
|
2435
|
+
.map(({ source, start, end }) => ({
|
|
2436
|
+
...source,
|
|
2437
|
+
start,
|
|
2438
|
+
end,
|
|
2439
|
+
top: 0,
|
|
2440
|
+
height: 24,
|
|
2441
|
+
allDay: true,
|
|
2442
|
+
column,
|
|
2443
|
+
columnCount: 1,
|
|
2444
|
+
continuesBefore: start.getTime() < dayStart.getTime(),
|
|
2445
|
+
continuesAfter: end.getTime() > dayEnd.getTime(),
|
|
2446
|
+
isStart: start.getTime() >= dayStart.getTime() && start.getTime() <= dayEnd.getTime(),
|
|
2447
|
+
isEnd: end.getTime() >= dayStart.getTime() && end.getTime() <= dayEnd.getTime(),
|
|
2448
|
+
}));
|
|
2449
|
+
}
|
|
2450
|
+
/** Creates FullCalendar-style horizontal segments for the six visible month rows. */
|
|
2451
|
+
buildMonthEventSegments() {
|
|
2452
|
+
const visibleDays = this.viewDays;
|
|
2453
|
+
if (!visibleDays.length) {
|
|
2454
|
+
this.monthEventSegments = [];
|
|
2455
|
+
this.monthEventRows = Array.from({ length: MONTH_ROW_COUNT }, () => []);
|
|
2456
|
+
return;
|
|
2189
2457
|
}
|
|
2190
|
-
|
|
2191
|
-
|
|
2458
|
+
const gridStart = this.startOfDay(visibleDays[0].date);
|
|
2459
|
+
const gridEnd = this.endOfDay(visibleDays[visibleDays.length - 1].date);
|
|
2460
|
+
const segments = [];
|
|
2461
|
+
for (const { source, start, end } of this.normalizedEvents()) {
|
|
2462
|
+
if (Number.isNaN(start.getTime()) ||
|
|
2463
|
+
end.getTime() < gridStart.getTime() ||
|
|
2464
|
+
start.getTime() > gridEnd.getTime())
|
|
2465
|
+
continue;
|
|
2466
|
+
const clippedStart = new Date(Math.max(start.getTime(), gridStart.getTime()));
|
|
2467
|
+
const clippedEnd = new Date(Math.min(end.getTime(), gridEnd.getTime()));
|
|
2468
|
+
const firstIndex = this.dayIndexInMonthGrid(clippedStart, gridStart);
|
|
2469
|
+
const lastIndex = this.dayIndexInMonthGrid(clippedEnd, gridStart);
|
|
2470
|
+
for (let index = Math.max(0, firstIndex); index <= Math.min(visibleDays.length - 1, lastIndex);) {
|
|
2471
|
+
const row = Math.floor(index / MONTH_COLUMN_COUNT);
|
|
2472
|
+
const rowEndIndex = Math.min((row + 1) * MONTH_COLUMN_COUNT - 1, lastIndex);
|
|
2473
|
+
const startColumn = index % MONTH_COLUMN_COUNT;
|
|
2474
|
+
const endColumn = rowEndIndex % MONTH_COLUMN_COUNT;
|
|
2475
|
+
const segmentStart = new Date(visibleDays[index].date);
|
|
2476
|
+
const segmentEnd = this.endOfDay(visibleDays[rowEndIndex].date);
|
|
2477
|
+
segments.push({
|
|
2478
|
+
...source,
|
|
2479
|
+
start,
|
|
2480
|
+
end,
|
|
2481
|
+
row,
|
|
2482
|
+
startColumn,
|
|
2483
|
+
endColumn,
|
|
2484
|
+
continuesBefore: start.getTime() < segmentStart.getTime(),
|
|
2485
|
+
continuesAfter: end.getTime() > segmentEnd.getTime(),
|
|
2486
|
+
isStart: start.getTime() >= segmentStart.getTime() && start.getTime() <= segmentEnd.getTime(),
|
|
2487
|
+
isEnd: end.getTime() >= segmentStart.getTime() && end.getTime() <= segmentEnd.getTime(),
|
|
2488
|
+
lane: 0,
|
|
2489
|
+
});
|
|
2490
|
+
index = rowEndIndex + 1;
|
|
2491
|
+
}
|
|
2192
2492
|
}
|
|
2493
|
+
// Stable ordering makes the same events keep the same visual lane while navigating.
|
|
2494
|
+
segments.sort((a, b) => a.row - b.row ||
|
|
2495
|
+
a.startColumn - b.startColumn ||
|
|
2496
|
+
a.start.getTime() - b.start.getTime() ||
|
|
2497
|
+
String(a.title ?? '').localeCompare(String(b.title ?? '')));
|
|
2498
|
+
// Assign lanes independently inside every week row.
|
|
2499
|
+
const lanesByRow = new Map();
|
|
2500
|
+
for (const segment of segments) {
|
|
2501
|
+
const lanes = lanesByRow.get(segment.row) ?? [];
|
|
2502
|
+
let lane = lanes.findIndex((items) => items.every((item) => item.endColumn < segment.startColumn));
|
|
2503
|
+
if (lane < 0) {
|
|
2504
|
+
lane = lanes.length;
|
|
2505
|
+
lanes.push([]);
|
|
2506
|
+
}
|
|
2507
|
+
segment.lane = lane;
|
|
2508
|
+
lanes[lane].push(segment);
|
|
2509
|
+
lanesByRow.set(segment.row, lanes);
|
|
2510
|
+
}
|
|
2511
|
+
this.monthEventSegments = segments;
|
|
2512
|
+
this.monthEventRows = Array.from({ length: MONTH_ROW_COUNT }, () => []);
|
|
2513
|
+
for (const segment of segments)
|
|
2514
|
+
this.monthEventRows[segment.row].push(segment);
|
|
2515
|
+
}
|
|
2516
|
+
dayIndexInMonthGrid(date, gridStart) {
|
|
2517
|
+
const a = this.startOfDay(date);
|
|
2518
|
+
const b = this.startOfDay(gridStart);
|
|
2519
|
+
const aUtc = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
|
|
2520
|
+
const bUtc = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());
|
|
2521
|
+
return Math.round((aUtc - bUtc) / 86_400_000);
|
|
2522
|
+
}
|
|
2523
|
+
normalizedEvents() {
|
|
2524
|
+
return this.renderEventSources().map((source) => {
|
|
2525
|
+
const normalized = this.normalizeEvent(source);
|
|
2526
|
+
return { source, start: normalized.start, end: normalized.end };
|
|
2527
|
+
});
|
|
2193
2528
|
}
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2529
|
+
renderEventSources() {
|
|
2530
|
+
if (!this.interaction?.active)
|
|
2531
|
+
return this._events;
|
|
2532
|
+
return this._events.map((event) => this.sameEvent(event, this.interaction.source) ? this.interaction.preview : event);
|
|
2533
|
+
}
|
|
2534
|
+
renderEventView() {
|
|
2535
|
+
const monthStart = this.adapter.getDate({
|
|
2536
|
+
locale: this._locale,
|
|
2537
|
+
year: this.currYear,
|
|
2538
|
+
month: this.currMonth,
|
|
2539
|
+
day: 1,
|
|
2540
|
+
});
|
|
2541
|
+
const monthEnd = this.adapter.getDate({
|
|
2542
|
+
locale: this._locale,
|
|
2543
|
+
year: this.currYear,
|
|
2544
|
+
month: this.currMonth,
|
|
2545
|
+
day: this.adapter.lastDateofMonth(this.currYear, this.currMonth),
|
|
2546
|
+
});
|
|
2547
|
+
this.eventViewItems = this.renderEventSources()
|
|
2548
|
+
.map((event) => {
|
|
2549
|
+
const n = this.normalizeEvent(event);
|
|
2550
|
+
return { event: event, start: n.start, end: n.end };
|
|
2551
|
+
})
|
|
2552
|
+
.filter(({ start, end }) => compareDate(end, monthStart) >= 0 && compareDate(start, monthEnd) <= 0)
|
|
2553
|
+
.sort((a, b) => a.start.getTime() - b.start.getTime());
|
|
2554
|
+
}
|
|
2555
|
+
get headerText() {
|
|
2556
|
+
if (!this.anchorDate)
|
|
2557
|
+
return '';
|
|
2558
|
+
if (this.view === 'day') {
|
|
2559
|
+
return this.adapter.formatDate(this.adapter.toLocale(this.anchorDate), 'full') ?? '';
|
|
2560
|
+
}
|
|
2561
|
+
if (this.view === 'week') {
|
|
2562
|
+
const days = this.getWeekDates(this.anchorDate);
|
|
2563
|
+
return this.formatDateRange(days[0], days[6]);
|
|
2564
|
+
}
|
|
2565
|
+
return `${this.displayMonth} ${this.currYear}`;
|
|
2566
|
+
}
|
|
2567
|
+
formatDateRange(start, end) {
|
|
2568
|
+
const s = this.adapter.toLocale(start);
|
|
2569
|
+
const e = this.adapter.toLocale(end);
|
|
2570
|
+
const startText = this.adapter.formatDate(s, 'd MMMM') ?? '';
|
|
2571
|
+
const endText = this.adapter.formatDate(e, 'd MMMM') ?? '';
|
|
2572
|
+
return s.year === e.year
|
|
2573
|
+
? `${startText} – ${endText}, ${s.year}`
|
|
2574
|
+
: `${startText}, ${s.year} – ${endText}, ${e.year}`;
|
|
2575
|
+
}
|
|
2576
|
+
formatEventDate(date) {
|
|
2577
|
+
return this.adapter.formatDate(this.adapter.toLocale(date), 'd MMMM, yyyy') ?? '';
|
|
2578
|
+
}
|
|
2579
|
+
formatTime(minutes) {
|
|
2580
|
+
return `${String(Math.floor(minutes / 60)).padStart(2, '0')}:${String(minutes % 60).padStart(2, '0')}`;
|
|
2197
2581
|
}
|
|
2198
2582
|
changeView(v) {
|
|
2583
|
+
this.cancelEventInteraction();
|
|
2199
2584
|
this.view = v;
|
|
2200
|
-
this.renderCalendar(
|
|
2585
|
+
this.renderCalendar(v);
|
|
2201
2586
|
}
|
|
2202
2587
|
gotoToday() {
|
|
2203
|
-
|
|
2204
|
-
this.
|
|
2205
|
-
this.
|
|
2206
|
-
this.
|
|
2207
|
-
this.
|
|
2588
|
+
this.cancelEventInteraction();
|
|
2589
|
+
this.anchorDate = this.adapter.getDate(this.adapter.today());
|
|
2590
|
+
this.selected = new Date(this.anchorDate);
|
|
2591
|
+
this.syncAnchorToLocale();
|
|
2592
|
+
this.renderCalendar(this.view);
|
|
2208
2593
|
}
|
|
2209
2594
|
selectDay(ev, item) {
|
|
2210
2595
|
ev.stopPropagation();
|
|
2211
2596
|
if (item.active) {
|
|
2597
|
+
this.selected = item.date;
|
|
2598
|
+
this.anchorDate = new Date(item.date);
|
|
2212
2599
|
this.dateChange.emit(item);
|
|
2600
|
+
this.renderCalendar(this.view);
|
|
2213
2601
|
}
|
|
2214
2602
|
}
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
if (item.active) {
|
|
2218
|
-
this.currMonth = item.month;
|
|
2219
|
-
this.changeView('day');
|
|
2220
|
-
}
|
|
2603
|
+
next() {
|
|
2604
|
+
this.navigate(1);
|
|
2221
2605
|
}
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
if (item.active) {
|
|
2225
|
-
this.currYear = item.year;
|
|
2226
|
-
this.changeView('month');
|
|
2227
|
-
}
|
|
2606
|
+
previous() {
|
|
2607
|
+
this.navigate(-1);
|
|
2228
2608
|
}
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2609
|
+
navigate(direction) {
|
|
2610
|
+
const d = new Date(this.anchorDate);
|
|
2611
|
+
if (this.view === 'month' || this.view === 'event') {
|
|
2612
|
+
const locale = this.adapter.toLocale(d);
|
|
2613
|
+
this.anchorDate = this.adapter.getDate({
|
|
2614
|
+
locale: this._locale,
|
|
2615
|
+
year: locale.year,
|
|
2616
|
+
month: locale.month + direction,
|
|
2617
|
+
day: 1,
|
|
2618
|
+
});
|
|
2235
2619
|
}
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
this.
|
|
2239
|
-
this.currMonth = date.getMonth();
|
|
2620
|
+
else {
|
|
2621
|
+
d.setDate(d.getDate() + direction * (this.view === 'week' ? 7 : 1));
|
|
2622
|
+
this.anchorDate = d;
|
|
2240
2623
|
}
|
|
2624
|
+
this.syncAnchorToLocale();
|
|
2241
2625
|
this.renderCalendar(this.view);
|
|
2242
2626
|
}
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2627
|
+
onclickEvent(ev, item, event) {
|
|
2628
|
+
ev.stopPropagation();
|
|
2629
|
+
this.selectEvent.emit({ date: item.date, event });
|
|
2630
|
+
}
|
|
2631
|
+
onTimedEventClick(ev, event, date) {
|
|
2632
|
+
ev.stopPropagation();
|
|
2633
|
+
if (this.interaction?.active)
|
|
2634
|
+
return;
|
|
2635
|
+
this.selectEvent.emit({ date, event });
|
|
2636
|
+
}
|
|
2637
|
+
startMonthEventInteraction(ev, segment, type = 'move') {
|
|
2638
|
+
if (ev.button !== 0)
|
|
2639
|
+
return;
|
|
2640
|
+
ev.preventDefault();
|
|
2641
|
+
ev.stopPropagation();
|
|
2642
|
+
this.beginInteraction(ev, segment, type, 'month');
|
|
2643
|
+
}
|
|
2644
|
+
startTimedEventInteraction(ev, event, type = 'move') {
|
|
2645
|
+
if (ev.button !== 0)
|
|
2646
|
+
return;
|
|
2647
|
+
ev.preventDefault();
|
|
2648
|
+
ev.stopPropagation();
|
|
2649
|
+
this.beginInteraction(ev, event, type, event.allDay ? 'all-day' : 'timed');
|
|
2650
|
+
}
|
|
2651
|
+
beginInteraction(ev, event, type, _surface) {
|
|
2652
|
+
const source = this._events.find((candidate) => this.sameEvent(candidate, event));
|
|
2653
|
+
if (!source)
|
|
2654
|
+
return;
|
|
2655
|
+
this.interaction = {
|
|
2656
|
+
type,
|
|
2657
|
+
source,
|
|
2658
|
+
previousEvent: { ...source },
|
|
2659
|
+
pointerId: ev.pointerId,
|
|
2660
|
+
startX: ev.clientX,
|
|
2661
|
+
startY: ev.clientY,
|
|
2662
|
+
originColumn: 0,
|
|
2663
|
+
originRow: 0,
|
|
2664
|
+
preview: { ...source },
|
|
2665
|
+
deltaDays: 0,
|
|
2666
|
+
deltaMinutes: 0,
|
|
2667
|
+
active: true,
|
|
2668
|
+
surface: _surface,
|
|
2669
|
+
};
|
|
2670
|
+
}
|
|
2671
|
+
updateEventInteraction(ev) {
|
|
2672
|
+
const state = this.interaction;
|
|
2673
|
+
if (!state)
|
|
2674
|
+
return;
|
|
2675
|
+
const monthMetrics = state.surface === 'month' ? this.monthPointerDelta(ev) : null;
|
|
2676
|
+
const timedMetrics = state.surface === 'timed' ? this.timedPointerDelta(ev) : null;
|
|
2677
|
+
const allDayMetrics = state.surface === 'all-day' ? this.allDayPointerDelta(ev) : null;
|
|
2678
|
+
let deltaDays = monthMetrics?.days ?? timedMetrics?.days ?? allDayMetrics?.days ?? 0;
|
|
2679
|
+
let deltaMinutes = timedMetrics?.minutes ?? 0;
|
|
2680
|
+
const preview = this.applyEventDelta(state.source, state.type, deltaDays, deltaMinutes);
|
|
2681
|
+
if (!this.isWithinBounds(preview))
|
|
2682
|
+
return;
|
|
2683
|
+
state.preview = preview;
|
|
2684
|
+
state.deltaDays = deltaDays;
|
|
2685
|
+
state.deltaMinutes = deltaMinutes;
|
|
2686
|
+
this.renderCalendar(this.view);
|
|
2687
|
+
}
|
|
2688
|
+
finishEventInteraction(ev, cancelled) {
|
|
2689
|
+
const state = this.interaction;
|
|
2690
|
+
if (!state)
|
|
2691
|
+
return;
|
|
2692
|
+
if (!cancelled)
|
|
2693
|
+
this.updateEventInteraction(ev);
|
|
2694
|
+
const changed = !this.sameEventValue(state.source, state.preview);
|
|
2695
|
+
this.interaction = null;
|
|
2696
|
+
if (!cancelled && changed) {
|
|
2697
|
+
const updated = this._events.map((event) => this.sameEvent(event, state.source) ? state.preview : event);
|
|
2698
|
+
this._events = updated;
|
|
2699
|
+
this.eventChange.emit({
|
|
2700
|
+
event: state.preview,
|
|
2701
|
+
previousEvent: state.previousEvent,
|
|
2702
|
+
interaction: state.type,
|
|
2703
|
+
deltaDays: state.deltaDays,
|
|
2704
|
+
deltaMinutes: state.deltaMinutes,
|
|
2705
|
+
});
|
|
2706
|
+
this.eventsChange.emit(updated);
|
|
2254
2707
|
}
|
|
2255
2708
|
this.renderCalendar(this.view);
|
|
2256
2709
|
}
|
|
2257
|
-
|
|
2258
|
-
this.
|
|
2259
|
-
|
|
2260
|
-
|
|
2710
|
+
cancelEventInteraction() {
|
|
2711
|
+
if (!this.interaction)
|
|
2712
|
+
return;
|
|
2713
|
+
this.interaction = null;
|
|
2714
|
+
}
|
|
2715
|
+
monthPointerDelta(ev) {
|
|
2716
|
+
if (!this.interaction || this.view !== 'month')
|
|
2717
|
+
return null;
|
|
2718
|
+
const root = this.calendarWrapper()?.nativeElement.querySelector('.days');
|
|
2719
|
+
if (!root)
|
|
2720
|
+
return null;
|
|
2721
|
+
const rect = root.getBoundingClientRect();
|
|
2722
|
+
const cellWidth = rect.width / MONTH_COLUMN_COUNT;
|
|
2723
|
+
const cellHeight = rect.height / MONTH_ROW_COUNT;
|
|
2724
|
+
const startColumn = Math.max(0, Math.min(MONTH_COLUMN_COUNT - 1, Math.floor((this.interaction.startX - rect.left) / cellWidth)));
|
|
2725
|
+
const currentColumn = Math.max(0, Math.min(MONTH_COLUMN_COUNT - 1, Math.floor((ev.clientX - rect.left) / cellWidth)));
|
|
2726
|
+
const startRow = Math.max(0, Math.min(MONTH_ROW_COUNT - 1, Math.floor((this.interaction.startY - rect.top) / cellHeight)));
|
|
2727
|
+
const currentRow = Math.max(0, Math.min(MONTH_ROW_COUNT - 1, Math.floor((ev.clientY - rect.top) / cellHeight)));
|
|
2728
|
+
return { days: (currentRow - startRow) * 7 + (currentColumn - startColumn) };
|
|
2729
|
+
}
|
|
2730
|
+
allDayPointerDelta(ev) {
|
|
2731
|
+
if (!this.interaction || this.view === 'month' || this.view === 'event')
|
|
2732
|
+
return null;
|
|
2733
|
+
const root = this.calendarWrapper()?.nativeElement.querySelector('.all-day-row');
|
|
2734
|
+
if (!root)
|
|
2735
|
+
return null;
|
|
2736
|
+
const columns = Array.from(root.querySelectorAll('.all-day-cell'));
|
|
2737
|
+
if (!columns.length)
|
|
2738
|
+
return null;
|
|
2739
|
+
const indexAt = (x) => {
|
|
2740
|
+
const index = columns.findIndex((column) => {
|
|
2741
|
+
const rect = column.getBoundingClientRect();
|
|
2742
|
+
return x >= rect.left && x <= rect.right;
|
|
2743
|
+
});
|
|
2744
|
+
return index < 0 ? 0 : index;
|
|
2745
|
+
};
|
|
2746
|
+
return { days: indexAt(ev.clientX) - indexAt(this.interaction.startX) };
|
|
2747
|
+
}
|
|
2748
|
+
timedPointerDelta(ev) {
|
|
2749
|
+
if (!this.interaction || (this.view !== 'day' && this.view !== 'week'))
|
|
2750
|
+
return null;
|
|
2751
|
+
const root = this.calendarWrapper()?.nativeElement.querySelector('.time-grid');
|
|
2752
|
+
if (!root)
|
|
2753
|
+
return null;
|
|
2754
|
+
const columns = Array.from(root.querySelectorAll('.day-column'));
|
|
2755
|
+
if (!columns.length)
|
|
2756
|
+
return null;
|
|
2757
|
+
const startColumn = this.columnAtPoint(columns, this.interaction.startX, this.interaction.startY);
|
|
2758
|
+
const currentColumn = this.columnAtPoint(columns, ev.clientX, ev.clientY);
|
|
2759
|
+
const startIndex = startColumn ?? 0;
|
|
2760
|
+
const currentIndex = currentColumn ?? startIndex;
|
|
2761
|
+
const rect = (columns[currentIndex] ?? columns[0]).getBoundingClientRect();
|
|
2762
|
+
const startRect = (columns[startIndex] ?? columns[0]).getBoundingClientRect();
|
|
2763
|
+
const startMinute = this.snapMinutes(((this.interaction.startY - startRect.top) / HALF_HOUR_HEIGHT) * 30);
|
|
2764
|
+
const currentMinute = this.snapMinutes(((ev.clientY - rect.top) / HALF_HOUR_HEIGHT) * 30);
|
|
2765
|
+
return { days: currentIndex - startIndex, minutes: currentMinute - startMinute };
|
|
2766
|
+
}
|
|
2767
|
+
columnAtPoint(columns, x, y) {
|
|
2768
|
+
const index = columns.findIndex((column) => {
|
|
2769
|
+
const rect = column.getBoundingClientRect();
|
|
2770
|
+
return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom;
|
|
2261
2771
|
});
|
|
2772
|
+
return index < 0 ? null : index;
|
|
2773
|
+
}
|
|
2774
|
+
snapMinutes(minutes) {
|
|
2775
|
+
return Math.max(0, Math.min(24 * 60, Math.round(minutes / 30) * 30));
|
|
2776
|
+
}
|
|
2777
|
+
applyEventDelta(source, type, deltaDays, deltaMinutes) {
|
|
2778
|
+
const normalized = this.normalizeEvent(source);
|
|
2779
|
+
let start = new Date(normalized.start);
|
|
2780
|
+
let end = new Date(normalized.end);
|
|
2781
|
+
if (type === 'move') {
|
|
2782
|
+
start = this.addMinutes(this.addDays(start, deltaDays), deltaMinutes);
|
|
2783
|
+
end = this.addMinutes(this.addDays(end, deltaDays), deltaMinutes);
|
|
2784
|
+
}
|
|
2785
|
+
else if (type === 'resize-start') {
|
|
2786
|
+
start = this.addMinutes(this.addDays(start, deltaDays), deltaMinutes);
|
|
2787
|
+
if (start.getTime() > end.getTime() - MIN_EVENT_MINUTES * 60_000) {
|
|
2788
|
+
start = new Date(end.getTime() - MIN_EVENT_MINUTES * 60_000);
|
|
2789
|
+
}
|
|
2790
|
+
}
|
|
2791
|
+
else {
|
|
2792
|
+
end = this.addMinutes(this.addDays(end, deltaDays), deltaMinutes);
|
|
2793
|
+
if (end.getTime() < start.getTime() + MIN_EVENT_MINUTES * 60_000) {
|
|
2794
|
+
end = new Date(start.getTime() + MIN_EVENT_MINUTES * 60_000);
|
|
2795
|
+
}
|
|
2796
|
+
}
|
|
2797
|
+
return { ...source, start, end };
|
|
2798
|
+
}
|
|
2799
|
+
addDays(date, days) {
|
|
2800
|
+
const d = new Date(date);
|
|
2801
|
+
d.setDate(d.getDate() + days);
|
|
2802
|
+
return d;
|
|
2803
|
+
}
|
|
2804
|
+
addMinutes(date, minutes) {
|
|
2805
|
+
return new Date(date.getTime() + minutes * 60_000);
|
|
2806
|
+
}
|
|
2807
|
+
isWithinBounds(event) {
|
|
2808
|
+
const n = this.normalizeEvent(event);
|
|
2809
|
+
if (this.minDate && compareDate(n.start, this.minDate) < 0)
|
|
2810
|
+
return false;
|
|
2811
|
+
if (this.maxDate && compareDate(n.end, this.maxDate) > 0)
|
|
2812
|
+
return false;
|
|
2813
|
+
return true;
|
|
2814
|
+
}
|
|
2815
|
+
sameEvent(a, b) {
|
|
2816
|
+
return a.id != null && b.id != null ? a.id === b.id : a === b;
|
|
2817
|
+
}
|
|
2818
|
+
sameEventValue(a, b) {
|
|
2819
|
+
const aa = this.normalizeEvent(a);
|
|
2820
|
+
const bb = this.normalizeEvent(b);
|
|
2821
|
+
return aa.start.getTime() === bb.start.getTime() && aa.end.getTime() === bb.end.getTime();
|
|
2822
|
+
}
|
|
2823
|
+
startOfDay(date) {
|
|
2824
|
+
const d = new Date(date);
|
|
2825
|
+
d.setHours(0, 0, 0, 0);
|
|
2826
|
+
return d;
|
|
2827
|
+
}
|
|
2828
|
+
endOfDay(date) {
|
|
2829
|
+
const d = new Date(date);
|
|
2830
|
+
d.setHours(23, 59, 59, 999);
|
|
2831
|
+
return d;
|
|
2262
2832
|
}
|
|
2833
|
+
defaultHeight = 600;
|
|
2834
|
+
minHeight = this.defaultHeight;
|
|
2263
2835
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NgxCalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2264
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: NgxCalendarComponent, isStandalone: true, selector: "ngx-calendar", inputs: { setTheme: ["theme", "setTheme"], config: "config", locale: "locale", setMin: ["min", "setMin"], setMax: ["max", "setMax"], view: "view", events: "events" }, outputs: { dateChange: "dateChange", selectEvent: "selectEvent" }, host: { listeners: { "window:resize": "onResize($event)" }, properties: { "class.dark": "theme==\"dark\"" } }, providers: [DateAdapterRegistry], viewQueries: [{ propertyName: "calendarWrapper", first: true, predicate: ["calendarWrapper"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"wrapper\" #datepickerWrapper>\n <div class=\"header\">\n <div class=\"nxt-prv-buttons\">\n <button id=\"prev\" class=\"previous dtp-btn\" (click)=\"previous()\" title=\"Previous\">\n <ng-template\n [ngTemplateOutlet]=\"\n _config.previousButtonTemplate || defaultPreviousBTNTemplate\n \"></ng-template>\n </button>\n @if (_config.todayButton) {\n <button class=\"today dtp-btn\" (click)=\"gotoToday()\">\n {{ _config.todayButtonText }}\n </button>\n }\n <button id=\"next\" class=\"next dtp-btn\" (click)=\"next()\" title=\"Next\">\n <ng-template\n [ngTemplateOutlet]=\"_config.nextButtonTemplate || defaultNextBTNTemplate\"></ng-template>\n </button>\n </div>\n <div class=\"current-date\">\n <span>\n {{ currYear }}\n </span>\n <span>\n {{ displayMonth }}\n </span>\n </div>\n <div class=\"view-mode\">\n {{ view }}\n <button\n class=\"dayview dtp-btn\"\n (click)=\"changeView('day')\"\n [class.active]=\"view == 'day'\"\n title=\"Month View\">\n Month\n </button>\n <button\n class=\"dayview dtp-btn\"\n (click)=\"changeView('week')\"\n [class.active]=\"view == 'week'\"\n title=\"Week View\">\n Week\n </button>\n <button\n class=\"dayview dtp-btn\"\n (click)=\"changeView('day')\"\n [class.active]=\"view == 'day'\"\n title=\"Day View\">\n Day\n </button>\n <button\n class=\"dayview dtp-btn\"\n (click)=\"changeView('event')\"\n [class.active]=\"view == 'event'\"\n title=\"Day View\">\n Event\n </button>\n </div>\n </div>\n <div class=\"calendar\" #calendarWrapper>\n @if (view === 'day') {\n <ul class=\"weeks\">\n @for (w of weeks; track $index) {\n <li>\n {{ w }}\n </li>\n }\n </ul>\n <ul class=\"days\" [style.minHeight.px]=\"minHeight\">\n @for (item of viewDays; track $index) {\n <li\n [class.de-active]=\"!item.active\"\n [class.today]=\"item.isToday\"\n [class.selected]=\"item.selected\"\n (click)=\"selectDay($event, item)\">\n <div>{{ item.day }}</div>\n @if (item.events) {\n <div class=\"ms-day-events\">\n @for (event of item.events; track $index) {\n <a\n tabindex=\"0\"\n class=\"ms-day-event\"\n [title]=\"event.title\"\n (click)=\"onclickEvent(item, event)\">\n {{ event.title }}\n </a>\n }\n </div>\n }\n </li>\n }\n </ul>\n } @else if (view == 'week' || view == 'month') {\n <table>\n <thead>\n <tr>\n <th></th>\n @for (w of weeks; track $index) {\n <th>{{ w }}</th>\n }\n </tr>\n </thead>\n <tbody>\n @for (item of viewWeeks; track $index; let i = $index) {\n <tr>\n <td [title]=\"item.displayTime\">{{ item.time % 1 == 0 ? item.time : '' }}</td>\n @for (w of item.weeks; track $index) {\n <td></td>\n }\n </tr>\n }\n </tbody>\n </table>\n } @else if (view == 'event') {\n not implemented\n }\n </div>\n</div>\n\n<ng-template #defaultPreviousBTNTemplate>\n <svg width=\"15px\" height=\"30px\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 320 512\">\n <path\n class=\"fa-secondary\"\n d=\"M224 480c-8.188 0-16.38-3.125-22.62-9.375l-192-192c-12.5-12.5-12.5-32.75 0-45.25l192-192c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25L77.25 256l169.4 169.4c12.5 12.5 12.5 32.75 0 45.25C240.4 476.9 232.2 480 224 480z\" />\n </svg>\n</ng-template>\n\n<ng-template #defaultNextBTNTemplate>\n <svg width=\"15px\" height=\"30px\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 320 512\">\n <path\n class=\"fa-secondary\"\n d=\"M96 480c-8.188 0-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L242.8 256L73.38 86.63c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l192 192c12.5 12.5 12.5 32.75 0 45.25l-192 192C112.4 476.9 104.2 480 96 480z\" />\n </svg>\n</ng-template>\n\n<ng-template #defaultCaretDownIcon>\n <svg width=\"10px\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 320 512\">\n <path\n class=\"fa-secondary\"\n d=\"M310.6 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z\" />\n </svg>\n</ng-template>\n", styles: [":host{--ngx-color-bg: #fff;--ngx-color-text: #000;--ngx-border-color: #c0c0c0}:host-context(.dark){--ngx-color-bg: #222;--ngx-color-text: #fff;--ngx-border-color: #c0c0c0}.wrapper{background-color:var(--ngx-color-bg);color:var(--ngx-color-text);border-radius:5px}.wrapper .dtp-btn{background:none;border:none;color:inherit;border-radius:3px;padding:3px 15px;box-shadow:0 0 4px #0003;transition:all .3s;display:inline-flex;align-items:center}.wrapper .dtp-btn:not([disabled]):hover{cursor:pointer;background:#87879e}.wrapper .dtp-btn.active{background:#87879e}.wrapper .dtp-btn svg{fill:var(--ngx-color-text)}.wrapper .header{display:flex;align-items:center;justify-content:space-between;padding:10px 10px 0}.wrapper .header .current-date{text-align:center;flex:auto}.wrapper .nxt-prv-buttons{display:flex;align-items:center}.wrapper .nxt-prv-buttons .dtp-btn{border-radius:0}.wrapper .nxt-prv-buttons .dtp-btn:first-child{border-radius:5px 0 0 5px}.wrapper .nxt-prv-buttons .dtp-btn:last-child{border-radius:0 5px 5px 0}.calendar{padding:10px}.calendar ul{display:flex;flex-wrap:wrap;list-style:none;padding:0;margin:0;border:1px var(--ngx-border-color) solid;border-bottom:none}.calendar .days{margin-bottom:20px}.calendar .days li{width:14.2857142857%;text-align:end;max-height:300px;overflow:auto}.calendar .months{margin-bottom:20px}.calendar .months li{height:40px;width:33%}.calendar .years{margin-bottom:20px}.calendar .years li{height:40px;width:25%}.calendar li{position:relative;border-right:1px var(--ngx-border-color) solid;border-bottom:1px var(--ngx-border-color) solid;padding:4px}.calendar li.de-active{color:#cbcbcb}.calendar li.selected{border:1px #1216fa solid}.calendar li.today{background-color:#ff9d0130}.calendar .weeks li{cursor:default;width:14.2857142857%;text-align:center;font-weight:700}.calendar .weeks li:hover{background:none}.ms-day-events .ms-day-event{color:#3f51b5;background:var(--ngx-color-bg);border:1px rgba(63,81,181,.1215686275) solid;border-radius:4px;min-height:25px;padding:4px;margin:4px 0;text-decoration:none;display:block}::ng-deep html[dir=rtl] .wrapper .nxt-prv-buttons .dtp-btn:first-child,::ng-deep body[dir=rtl] .wrapper .nxt-prv-buttons .dtp-btn:first-child{border-radius:0 5px 5px 0!important}::ng-deep html[dir=rtl] .wrapper .nxt-prv-buttons .dtp-btn:last-child,::ng-deep body[dir=rtl] .wrapper .nxt-prv-buttons .dtp-btn:last-child{border-radius:5px 0 0 5px!important}::ng-deep html[dir=rtl] .wrapper .wrapper .dtp-btn.next,::ng-deep html[dir=rtl] .wrapper .wrapper .dtp-btn.previous,::ng-deep body[dir=rtl] .wrapper .wrapper .dtp-btn.next,::ng-deep body[dir=rtl] .wrapper .wrapper .dtp-btn.previous{transform:rotate(180deg)}table{width:100%;border-collapse:collapse}table td,table th{border:1px rgb(158,158,158) solid;padding:5px;height:1.5em}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
|
|
2836
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: NgxCalendarComponent, isStandalone: true, selector: "ngx-calendar", inputs: { localize: { classPropertyName: "localize", publicName: "localize", isSignal: true, isRequired: false, transformFunction: null }, config: { classPropertyName: "config", publicName: "config", isSignal: false, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: false, isRequired: false, transformFunction: null }, setMin: { classPropertyName: "setMin", publicName: "min", isSignal: false, isRequired: false, transformFunction: null }, setMax: { classPropertyName: "setMax", publicName: "max", isSignal: false, isRequired: false, transformFunction: null }, view: { classPropertyName: "view", publicName: "view", isSignal: false, isRequired: false, transformFunction: null }, events: { classPropertyName: "events", publicName: "events", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { dateChange: "dateChange", selectEvent: "selectEvent", eventChange: "eventChange", eventsChange: "eventsChange" }, host: { listeners: { "window:resize": "onResize()", "document:pointermove": "onDocumentPointerMove($event)", "document:pointerup": "onDocumentPointerUp($event)", "document:pointercancel": "onDocumentPointerCancel($event)" } }, providers: [DateAdapterRegistry], viewQueries: [{ propertyName: "calendarWrapper", first: true, predicate: ["calendarWrapper"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"wrapper\" [class.is-interacting]=\"!!interaction\">\n <div class=\"header\">\n <div class=\"nxt-prv-buttons\">\n <button type=\"button\" class=\"previous dtp-btn\" (click)=\"previous()\" title=\"Previous\">\n <ng-template\n [ngTemplateOutlet]=\"\n _config.previousButtonTemplate || defaultPreviousBTNTemplate\n \"></ng-template>\n </button>\n @if (_config.todayButton) {\n <button type=\"button\" class=\"today dtp-btn\" (click)=\"gotoToday()\">\n {{ localize().today }}\n </button>\n }\n <button type=\"button\" class=\"next dtp-btn\" (click)=\"next()\" title=\"Next\">\n <ng-template\n [ngTemplateOutlet]=\"_config.nextButtonTemplate || defaultNextBTNTemplate\"></ng-template>\n </button>\n </div>\n\n <div class=\"current-date\" aria-live=\"polite\">{{ headerText }}</div>\n\n <div class=\"view-mode\">\n <button\n type=\"button\"\n class=\"dtp-btn\"\n (click)=\"changeView('month')\"\n [class.active]=\"view === 'month'\">\n {{ localize().month }}\n </button>\n <button\n type=\"button\"\n class=\"dtp-btn\"\n (click)=\"changeView('week')\"\n [class.active]=\"view === 'week'\">\n {{ localize().week }}\n </button>\n <button\n type=\"button\"\n class=\"dtp-btn\"\n (click)=\"changeView('day')\"\n [class.active]=\"view === 'day'\">\n {{ localize().day }}\n </button>\n <button\n type=\"button\"\n class=\"dtp-btn\"\n (click)=\"changeView('event')\"\n [class.active]=\"view === 'event'\">\n {{ localize().event }}\n </button>\n </div>\n </div>\n\n <div class=\"calendar\" #calendarWrapper>\n @switch (view) {\n @case ('month') {\n <ul class=\"weeks\">\n @for (w of weeks; track $index) {\n <li>{{ w }}</li>\n }\n </ul>\n\n <div class=\"month-grid\" [style.minHeight.px]=\"minHeight\">\n @for (row of monthEventRows; track $index; let rowIndex = $index) {\n <div class=\"month-row\">\n @for (\n item of viewDays.slice(rowIndex * 7, rowIndex * 7 + 7);\n track item.date?.getTime() ?? $index\n ) {\n <button\n type=\"button\"\n class=\"month-day\"\n [class.de-active]=\"!item.active\"\n [class.today]=\"item.isToday\"\n [class.selected]=\"item.selected\"\n (click)=\"selectDay($event, item)\">\n <span class=\"day-number\">{{ item.day }}</span>\n </button>\n }\n\n <div class=\"month-event-layer\" aria-live=\"polite\">\n @for (event of row; track event.id ?? event.start.getTime() ?? $index) {\n <button\n type=\"button\"\n class=\"month-event\"\n [class.continues-before]=\"event.continuesBefore\"\n [class.continues-after]=\"event.continuesAfter\"\n [class.event-start]=\"event.isStart\"\n [class.event-end]=\"event.isEnd\"\n [class.is-dragging]=\"\n interaction?.source === event ||\n (interaction?.source?.id != null && interaction?.source?.id === event.id)\n \"\n [style.gridColumn]=\"event.startColumn + 1 + ' / ' + (event.endColumn + 2)\"\n [style.gridRow]=\"event.lane + 1\"\n [style.background]=\"event.backgroundColor || event.color || null\"\n [style.borderColor]=\"event.borderColor || event.color || null\"\n [style.color]=\"event.textColor || null\"\n [title]=\"event.title || ''\"\n (pointerdown)=\"startMonthEventInteraction($event, event)\"\n (click)=\"\n onclickEvent($event, { date: event.start, day: 0, active: true }, event)\n \">\n @if (event.isStart) {\n <span class=\"event-title\">{{ event.title || 'Untitled event' }}</span>\n } @else {\n <span class=\"event-title continuation-title\">{{ event.title || '' }}</span>\n }\n\n @if (event.isStart) {\n <span\n class=\"resize-handle resize-start\"\n title=\"Resize start\"\n (pointerdown)=\"\n startMonthEventInteraction($event, event, 'resize-start')\n \"></span>\n }\n @if (event.isEnd) {\n <span\n class=\"resize-handle resize-end\"\n title=\"Resize end\"\n (pointerdown)=\"\n startMonthEventInteraction($event, event, 'resize-end')\n \"></span>\n }\n </button>\n }\n </div>\n </div>\n }\n </div>\n }\n\n @case ('week') {\n <ng-container [ngTemplateOutlet]=\"timedCalendar\"></ng-container>\n }\n\n @case ('day') {\n <ng-container [ngTemplateOutlet]=\"timedCalendar\"></ng-container>\n }\n\n @case ('event') {\n <div class=\"event-list\">\n @if (eventViewItems.length) {\n @for (item of eventViewItems; track item.event.id ?? item.start.getTime()) {\n <button\n type=\"button\"\n class=\"event-list-item\"\n (click)=\"\n onclickEvent($event, { date: item.start, day: 0, active: true }, item.event)\n \">\n <span\n class=\"event-dot\"\n [style.background]=\"\n item.event.backgroundColor || item.event.color || null\n \"></span>\n <span class=\"event-copy\">\n <strong>{{ item.event.title || 'Untitled event' }}</strong>\n <small>\n {{ formatEventDate(item.start) }}\n @if (item.end.getTime() !== item.start.getTime()) {\n \u2013 {{ formatEventDate(item.end) }}\n }\n </small>\n </span>\n </button>\n }\n } @else {\n <div class=\"empty-events\">No events for this month.</div>\n }\n </div>\n }\n }\n </div>\n</div>\n\n<ng-template #timedCalendar>\n <div class=\"timed-calendar\">\n <div\n class=\"timed-header\"\n [style.gridTemplateColumns]=\"'64px repeat(' + weekDays.length + ', minmax(0, 1fr))'\">\n <div class=\"corner\"></div>\n @for (day of weekDays; track day.date.getTime()) {\n <button\n type=\"button\"\n class=\"day-header\"\n [class.today]=\"day.isToday\"\n (click)=\"selectDay($event, { date: day.date, day: 0, active: true })\">\n <span>{{ day.label }}</span>\n <strong>{{ day.dayNumber }}</strong>\n </button>\n }\n </div>\n\n <div\n class=\"all-day-row\"\n [style.gridTemplateColumns]=\"'64px repeat(' + weekDays.length + ', minmax(0, 1fr))'\">\n <div class=\"all-day-label\">All day</div>\n @for (day of weekDays; track day.date.getTime(); let i = $index) {\n <div class=\"all-day-cell\">\n @for (\n event of allDayByColumn[i];\n track event.id ?? event.title ?? event.start.getTime()\n ) {\n <button\n type=\"button\"\n class=\"timed-event all-day-event\"\n [class.continues-before]=\"event.continuesBefore\"\n [class.continues-after]=\"event.continuesAfter\"\n [style.background]=\"event.backgroundColor || event.color || null\"\n [style.borderColor]=\"event.borderColor || event.color || null\"\n [style.color]=\"event.textColor || null\"\n [title]=\"event.title || ''\"\n (pointerdown)=\"startTimedEventInteraction($event, event)\"\n (click)=\"onTimedEventClick($event, event, day.date)\">\n <span>{{ event.title || 'Untitled event' }}</span>\n @if (event.isStart) {\n <span\n class=\"resize-handle resize-start\"\n (pointerdown)=\"startTimedEventInteraction($event, event, 'resize-start')\"></span>\n }\n @if (event.isEnd) {\n <span\n class=\"resize-handle resize-end\"\n (pointerdown)=\"startTimedEventInteraction($event, event, 'resize-end')\"></span>\n }\n </button>\n }\n </div>\n }\n </div>\n\n <div\n class=\"time-grid\"\n [style.gridTemplateColumns]=\"'64px repeat(' + weekDays.length + ', minmax(0, 1fr))'\">\n <div class=\"time-axis\">\n @for (minutes of timeSlots; track minutes) {\n <div class=\"time-label\" [style.top.px]=\"(minutes / 60) * hourHeight\">\n @if (minutes % 60 === 0) {\n {{ formatTime(minutes) }}\n }\n </div>\n }\n </div>\n\n @for (day of weekDays; track day.date.getTime()) {\n <div class=\"day-column\">\n @for (minutes of timeSlots; track minutes) {\n <div class=\"time-slot\" [class.hour]=\"minutes % 60 === 0\"></div>\n }\n\n @for (event of day.events; track event.id ?? event.title ?? event.start.getTime()) {\n <button\n type=\"button\"\n class=\"timed-event\"\n [class.continues-before]=\"event.continuesBefore\"\n [class.continues-after]=\"event.continuesAfter\"\n [style.top.px]=\"event.top\"\n [style.height.px]=\"event.height\"\n [style.insetInlineStart.%]=\"event.column * (100 / event.columnCount)\"\n [style.width.%]=\"100 / event.columnCount - 1\"\n [style.background]=\"event.backgroundColor || event.color || null\"\n [style.borderColor]=\"event.borderColor || event.color || null\"\n [style.color]=\"event.textColor || null\"\n [title]=\"event.title || ''\"\n (pointerdown)=\"startTimedEventInteraction($event, event)\"\n (click)=\"onTimedEventClick($event, event, day.date)\">\n <strong>{{ event.title || 'Untitled event' }}</strong>\n @if (event.height >= 42) {\n <small>\n {{ formatTime(event.start.getHours() * 60 + event.start.getMinutes()) }}\n </small>\n }\n @if (event.isStart) {\n <span\n class=\"resize-handle resize-start\"\n (pointerdown)=\"startTimedEventInteraction($event, event, 'resize-start')\"></span>\n }\n @if (event.isEnd) {\n <span\n class=\"resize-handle resize-end\"\n (pointerdown)=\"startTimedEventInteraction($event, event, 'resize-end')\"></span>\n }\n </button>\n }\n </div>\n }\n </div>\n </div>\n</ng-template>\n\n<ng-template #defaultPreviousBTNTemplate>\n <svg width=\"15px\" height=\"30px\" viewBox=\"0 0 320 512\">\n <path\n fill=\"currentColor\"\n d=\"M224 480c-8.188 0-16.38-3.125-22.62-9.375l-192-192c-12.5-12.5-12.5-32.75 0-45.25l192-192c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25L77.25 256l169.4 169.4c12.5 12.5 12.5 32.75 0 45.25C240.4 476.9 232.2 480 224 480z\" />\n </svg>\n</ng-template>\n\n<ng-template #defaultNextBTNTemplate>\n <svg width=\"15px\" height=\"30px\" viewBox=\"0 0 320 512\">\n <path\n fill=\"currentColor\"\n d=\"M96 480c-8.188 0-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L242.8 256L73.38 86.63c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l192 192c12.5 12.5 12.5 32.75 0 45.25l-192 192C112.4 476.9 104.2 480 96 480z\" />\n </svg>\n</ng-template>\n", styles: [":host{--ngx-color-bg: light-dark(#fff, #171a24);--ngx-color-text: light-dark(#16181d, #f7f7f8);--ngx-border-color: light-dark(#e1e4ea, #303541);--ngx-muted: color-mix(in srgb, var(--ngx-color-text) 55%, transparent);--ngx-event-bg: light-dark(#eef0ff, #2f3150);--ngx-event-text: light-dark(#3547a4, #dce1ff);--ngx-today: #3f51b5}.wrapper{background:var(--ngx-color-bg);color:var(--ngx-color-text);border:1px solid var(--ngx-border-color);border-radius:10px;overflow:hidden}.wrapper .dtp-btn{background:none;border:none;color:inherit;border-radius:6px;padding:5px 12px;box-shadow:0 0 4px #0000001f;transition:background .16s ease,transform .16s ease;display:inline-flex;align-items:center;justify-content:center}.wrapper .dtp-btn:not([disabled]):hover{cursor:pointer;background:#7f7fa02e}.wrapper .dtp-btn.active{background:#7f7fa03d}.wrapper .dtp-btn svg{fill:currentColor}.wrapper .header{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px;border-bottom:1px solid var(--ngx-border-color)}.wrapper .header .current-date{text-align:center;flex:1;min-width:0;font-weight:700}.wrapper .nxt-prv-buttons,.wrapper .view-mode{display:flex;align-items:center;gap:4px}.calendar{padding:10px;min-width:0}.weeks{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));list-style:none;padding:0;margin:0 0 8px;border-inline-start:1px solid var(--ngx-border-color)}.weeks li{padding:7px 4px;text-align:center;color:var(--ngx-muted);font-size:11px;font-weight:700;border-inline-end:1px solid var(--ngx-border-color)}.month-grid{display:grid;grid-template-rows:repeat(6,minmax(92px,1fr));border-inline-start:1px solid var(--ngx-border-color);border-top:1px solid var(--ngx-border-color);position:relative}.month-row{position:relative;display:grid;grid-template-columns:repeat(7,minmax(0,1fr));min-height:92px;border-bottom:1px solid var(--ngx-border-color)}.month-day{position:relative;min-width:0;min-height:92px;overflow:hidden;padding:4px;border:0;border-inline-end:1px solid var(--ngx-border-color);background:transparent;color:inherit;font:inherit;text-align:start;cursor:pointer;transition:background .15s ease}.month-day:hover{background:#7f7fa00d}.month-day.de-active{opacity:.48}.month-day.selected{outline:2px solid rgba(63,81,181,.3);outline-offset:-2px}.month-day.today .day-number{background:#3f51b51a;color:var(--ngx-today);font-weight:800}.day-number{width:27px;height:27px;display:grid;place-items:center;margin-inline-start:auto;border-radius:50%;font-size:12px;font-weight:600}.month-event-layer{position:absolute;inset:0;display:grid;grid-template-columns:repeat(7,minmax(0,1fr));grid-template-rows:repeat(4,26px);pointer-events:none;padding-top:34px}.month-event{position:relative;z-index:3;min-width:0;height:22px;margin-inline:2px;padding:2px 7px;border:1px solid transparent;border-radius:5px;overflow:hidden;background:var(--ngx-event-bg);color:var(--ngx-event-text);font:inherit;font-size:11px;font-weight:600;line-height:17px;text-align:start;white-space:nowrap;text-overflow:ellipsis;pointer-events:auto;cursor:grab;touch-action:none;box-sizing:border-box}.month-event:active{cursor:grabbing}.month-event:hover{filter:brightness(.97);box-shadow:0 2px 7px #00000024}.month-event.is-dragging{opacity:.78;box-shadow:0 5px 14px #0003}.month-event.continues-before{border-start-start-radius:2px;border-end-start-radius:2px;margin-inline-start:0}.month-event.continues-after{border-start-end-radius:2px;border-end-end-radius:2px;margin-inline-end:0}.event-title{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.continuation-title{opacity:.85}.resize-handle{position:absolute;top:0;bottom:0;width:7px;z-index:5;cursor:ew-resize;touch-action:none}.resize-handle:after{content:\"\";position:absolute;top:5px;bottom:5px;inset-inline-start:3px;width:2px;border-radius:2px;background:currentColor;opacity:.45}.resize-start{inset-inline-start:0}.resize-end{inset-inline-end:0}.timed-calendar{min-width:0;border:1px solid var(--ngx-border-color);border-radius:8px;overflow:auto}.timed-header,.all-day-row,.time-grid{display:grid;min-width:620px}.timed-header{position:sticky;top:0;z-index:5;background:var(--ngx-color-bg);border-bottom:1px solid var(--ngx-border-color)}.corner{border-inline-end:1px solid var(--ngx-border-color)}.day-header{min-width:0;height:58px;padding:6px;border:0;border-inline-end:1px solid var(--ngx-border-color);background:transparent;color:inherit;cursor:pointer;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px}.day-header span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:11px;color:var(--ngx-muted)}.day-header strong{width:30px;height:30px;display:grid;place-items:center;border-radius:50%;font-size:14px}.day-header.today strong{background:var(--ngx-today);color:#fff}.day-header:hover{background:#7f7fa012}.all-day-row{min-height:34px;border-bottom:1px solid var(--ngx-border-color);background:color-mix(in srgb,var(--ngx-color-bg) 94%,currentColor)}.all-day-row .all-day-label{padding:8px 5px;color:var(--ngx-muted);font-size:10px;border-inline-end:1px solid var(--ngx-border-color);text-align:center}.all-day-row .all-day-cell{min-width:0;padding:4px;border-inline-end:1px solid var(--ngx-border-color);display:flex;flex-direction:column;gap:3px}.time-grid{position:relative;align-items:stretch;min-height:1536px}.time-axis{position:relative;border-inline-end:1px solid var(--ngx-border-color);background:var(--ngx-color-bg)}.time-label{position:absolute;inset-inline:0 5px;transform:translateY(-50%);text-align:end;color:var(--ngx-muted);font-size:10px;pointer-events:none}.day-column{position:relative;min-width:0;height:1536px;border-inline-end:1px solid var(--ngx-border-color);background:repeating-linear-gradient(to bottom,transparent 0,transparent 31px,var(--ngx-border-color) 32px,transparent 33px,transparent 63px,var(--ngx-border-color) 64px)}.time-slot{height:32px;pointer-events:none;border-bottom:1px dashed color-mix(in srgb,var(--ngx-border-color) 55%,transparent)}.time-slot.hour{border-bottom-style:solid;border-bottom-color:var(--ngx-border-color)}.timed-event{position:absolute;z-index:2;min-width:24px;padding:4px 7px;border:1px solid transparent;border-radius:5px;overflow:hidden;background:var(--ngx-event-bg);color:var(--ngx-event-text);font:inherit;font-size:11px;line-height:15px;text-align:start;cursor:grab;box-sizing:border-box;touch-action:none;transition:filter .12s ease,box-shadow .12s ease}.timed-event:hover{filter:brightness(.97);box-shadow:0 2px 7px #00000024;z-index:4}.timed-event strong,.timed-event small{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.timed-event small{opacity:.72;font-size:10px}.timed-event.continues-before{border-start-start-radius:2px;border-end-start-radius:2px}.timed-event.continues-after{border-start-end-radius:2px;border-end-end-radius:2px}.timed-event.all-day-event{cursor:grab;position:relative;inset:auto!important;width:100%!important;min-height:24px;height:24px;padding-block:2px}.event-list{display:flex;flex-direction:column;gap:6px}.event-list-item{display:flex;align-items:center;gap:10px;width:100%;padding:10px 12px;border:1px solid var(--ngx-border-color);border-radius:8px;background:transparent;color:inherit;text-align:start;cursor:pointer}.event-list-item:hover{background:#7f7fa014}.event-list-item .event-dot{width:8px;height:8px;flex:0 0 8px;border-radius:50%;background:var(--ngx-today)}.event-list-item .event-copy{min-width:0;display:flex;flex-direction:column;gap:2px}.event-list-item .event-copy strong,.event-list-item .event-copy small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.event-list-item .event-copy small{opacity:.58}.empty-events{padding:30px;text-align:center;opacity:.55}:host-context([dir=rtl]) .nxt-prv-buttons .previous svg{transform:rotate(180deg)}:host-context([dir=rtl]) .nxt-prv-buttons .next svg{transform:rotate(180deg)}@media(max-width:700px){.wrapper .header{flex-wrap:wrap}.wrapper .header .current-date{order:-1;flex-basis:100%}.view-mode{width:100%;justify-content:center}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2265
2837
|
}
|
|
2266
2838
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NgxCalendarComponent, decorators: [{
|
|
2267
2839
|
type: Component,
|
|
2268
|
-
args: [{ selector: 'ngx-calendar', imports: [CommonModule], providers: [DateAdapterRegistry], host: {
|
|
2269
|
-
|
|
2270
|
-
}, template: "<div class=\"wrapper\" #datepickerWrapper>\n <div class=\"header\">\n <div class=\"nxt-prv-buttons\">\n <button id=\"prev\" class=\"previous dtp-btn\" (click)=\"previous()\" title=\"Previous\">\n <ng-template\n [ngTemplateOutlet]=\"\n _config.previousButtonTemplate || defaultPreviousBTNTemplate\n \"></ng-template>\n </button>\n @if (_config.todayButton) {\n <button class=\"today dtp-btn\" (click)=\"gotoToday()\">\n {{ _config.todayButtonText }}\n </button>\n }\n <button id=\"next\" class=\"next dtp-btn\" (click)=\"next()\" title=\"Next\">\n <ng-template\n [ngTemplateOutlet]=\"_config.nextButtonTemplate || defaultNextBTNTemplate\"></ng-template>\n </button>\n </div>\n <div class=\"current-date\">\n <span>\n {{ currYear }}\n </span>\n <span>\n {{ displayMonth }}\n </span>\n </div>\n <div class=\"view-mode\">\n {{ view }}\n <button\n class=\"dayview dtp-btn\"\n (click)=\"changeView('day')\"\n [class.active]=\"view == 'day'\"\n title=\"Month View\">\n Month\n </button>\n <button\n class=\"dayview dtp-btn\"\n (click)=\"changeView('week')\"\n [class.active]=\"view == 'week'\"\n title=\"Week View\">\n Week\n </button>\n <button\n class=\"dayview dtp-btn\"\n (click)=\"changeView('day')\"\n [class.active]=\"view == 'day'\"\n title=\"Day View\">\n Day\n </button>\n <button\n class=\"dayview dtp-btn\"\n (click)=\"changeView('event')\"\n [class.active]=\"view == 'event'\"\n title=\"Day View\">\n Event\n </button>\n </div>\n </div>\n <div class=\"calendar\" #calendarWrapper>\n @if (view === 'day') {\n <ul class=\"weeks\">\n @for (w of weeks; track $index) {\n <li>\n {{ w }}\n </li>\n }\n </ul>\n <ul class=\"days\" [style.minHeight.px]=\"minHeight\">\n @for (item of viewDays; track $index) {\n <li\n [class.de-active]=\"!item.active\"\n [class.today]=\"item.isToday\"\n [class.selected]=\"item.selected\"\n (click)=\"selectDay($event, item)\">\n <div>{{ item.day }}</div>\n @if (item.events) {\n <div class=\"ms-day-events\">\n @for (event of item.events; track $index) {\n <a\n tabindex=\"0\"\n class=\"ms-day-event\"\n [title]=\"event.title\"\n (click)=\"onclickEvent(item, event)\">\n {{ event.title }}\n </a>\n }\n </div>\n }\n </li>\n }\n </ul>\n } @else if (view == 'week' || view == 'month') {\n <table>\n <thead>\n <tr>\n <th></th>\n @for (w of weeks; track $index) {\n <th>{{ w }}</th>\n }\n </tr>\n </thead>\n <tbody>\n @for (item of viewWeeks; track $index; let i = $index) {\n <tr>\n <td [title]=\"item.displayTime\">{{ item.time % 1 == 0 ? item.time : '' }}</td>\n @for (w of item.weeks; track $index) {\n <td></td>\n }\n </tr>\n }\n </tbody>\n </table>\n } @else if (view == 'event') {\n not implemented\n }\n </div>\n</div>\n\n<ng-template #defaultPreviousBTNTemplate>\n <svg width=\"15px\" height=\"30px\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 320 512\">\n <path\n class=\"fa-secondary\"\n d=\"M224 480c-8.188 0-16.38-3.125-22.62-9.375l-192-192c-12.5-12.5-12.5-32.75 0-45.25l192-192c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25L77.25 256l169.4 169.4c12.5 12.5 12.5 32.75 0 45.25C240.4 476.9 232.2 480 224 480z\" />\n </svg>\n</ng-template>\n\n<ng-template #defaultNextBTNTemplate>\n <svg width=\"15px\" height=\"30px\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 320 512\">\n <path\n class=\"fa-secondary\"\n d=\"M96 480c-8.188 0-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L242.8 256L73.38 86.63c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l192 192c12.5 12.5 12.5 32.75 0 45.25l-192 192C112.4 476.9 104.2 480 96 480z\" />\n </svg>\n</ng-template>\n\n<ng-template #defaultCaretDownIcon>\n <svg width=\"10px\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 320 512\">\n <path\n class=\"fa-secondary\"\n d=\"M310.6 246.6l-127.1 128C176.4 380.9 168.2 384 160 384s-16.38-3.125-22.63-9.375l-127.1-128C.2244 237.5-2.516 223.7 2.438 211.8S19.07 192 32 192h255.1c12.94 0 24.62 7.781 29.58 19.75S319.8 237.5 310.6 246.6z\" />\n </svg>\n</ng-template>\n", styles: [":host{--ngx-color-bg: #fff;--ngx-color-text: #000;--ngx-border-color: #c0c0c0}:host-context(.dark){--ngx-color-bg: #222;--ngx-color-text: #fff;--ngx-border-color: #c0c0c0}.wrapper{background-color:var(--ngx-color-bg);color:var(--ngx-color-text);border-radius:5px}.wrapper .dtp-btn{background:none;border:none;color:inherit;border-radius:3px;padding:3px 15px;box-shadow:0 0 4px #0003;transition:all .3s;display:inline-flex;align-items:center}.wrapper .dtp-btn:not([disabled]):hover{cursor:pointer;background:#87879e}.wrapper .dtp-btn.active{background:#87879e}.wrapper .dtp-btn svg{fill:var(--ngx-color-text)}.wrapper .header{display:flex;align-items:center;justify-content:space-between;padding:10px 10px 0}.wrapper .header .current-date{text-align:center;flex:auto}.wrapper .nxt-prv-buttons{display:flex;align-items:center}.wrapper .nxt-prv-buttons .dtp-btn{border-radius:0}.wrapper .nxt-prv-buttons .dtp-btn:first-child{border-radius:5px 0 0 5px}.wrapper .nxt-prv-buttons .dtp-btn:last-child{border-radius:0 5px 5px 0}.calendar{padding:10px}.calendar ul{display:flex;flex-wrap:wrap;list-style:none;padding:0;margin:0;border:1px var(--ngx-border-color) solid;border-bottom:none}.calendar .days{margin-bottom:20px}.calendar .days li{width:14.2857142857%;text-align:end;max-height:300px;overflow:auto}.calendar .months{margin-bottom:20px}.calendar .months li{height:40px;width:33%}.calendar .years{margin-bottom:20px}.calendar .years li{height:40px;width:25%}.calendar li{position:relative;border-right:1px var(--ngx-border-color) solid;border-bottom:1px var(--ngx-border-color) solid;padding:4px}.calendar li.de-active{color:#cbcbcb}.calendar li.selected{border:1px #1216fa solid}.calendar li.today{background-color:#ff9d0130}.calendar .weeks li{cursor:default;width:14.2857142857%;text-align:center;font-weight:700}.calendar .weeks li:hover{background:none}.ms-day-events .ms-day-event{color:#3f51b5;background:var(--ngx-color-bg);border:1px rgba(63,81,181,.1215686275) solid;border-radius:4px;min-height:25px;padding:4px;margin:4px 0;text-decoration:none;display:block}::ng-deep html[dir=rtl] .wrapper .nxt-prv-buttons .dtp-btn:first-child,::ng-deep body[dir=rtl] .wrapper .nxt-prv-buttons .dtp-btn:first-child{border-radius:0 5px 5px 0!important}::ng-deep html[dir=rtl] .wrapper .nxt-prv-buttons .dtp-btn:last-child,::ng-deep body[dir=rtl] .wrapper .nxt-prv-buttons .dtp-btn:last-child{border-radius:5px 0 0 5px!important}::ng-deep html[dir=rtl] .wrapper .wrapper .dtp-btn.next,::ng-deep html[dir=rtl] .wrapper .wrapper .dtp-btn.previous,::ng-deep body[dir=rtl] .wrapper .wrapper .dtp-btn.next,::ng-deep body[dir=rtl] .wrapper .wrapper .dtp-btn.previous{transform:rotate(180deg)}table{width:100%;border-collapse:collapse}table td,table th{border:1px rgb(158,158,158) solid;padding:5px;height:1.5em}\n"] }]
|
|
2271
|
-
}], ctorParameters: () => [], propDecorators: { setTheme: [{
|
|
2272
|
-
type: Input,
|
|
2273
|
-
args: ['theme']
|
|
2274
|
-
}], config: [{
|
|
2840
|
+
args: [{ selector: 'ngx-calendar', imports: [CommonModule], providers: [DateAdapterRegistry], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"wrapper\" [class.is-interacting]=\"!!interaction\">\n <div class=\"header\">\n <div class=\"nxt-prv-buttons\">\n <button type=\"button\" class=\"previous dtp-btn\" (click)=\"previous()\" title=\"Previous\">\n <ng-template\n [ngTemplateOutlet]=\"\n _config.previousButtonTemplate || defaultPreviousBTNTemplate\n \"></ng-template>\n </button>\n @if (_config.todayButton) {\n <button type=\"button\" class=\"today dtp-btn\" (click)=\"gotoToday()\">\n {{ localize().today }}\n </button>\n }\n <button type=\"button\" class=\"next dtp-btn\" (click)=\"next()\" title=\"Next\">\n <ng-template\n [ngTemplateOutlet]=\"_config.nextButtonTemplate || defaultNextBTNTemplate\"></ng-template>\n </button>\n </div>\n\n <div class=\"current-date\" aria-live=\"polite\">{{ headerText }}</div>\n\n <div class=\"view-mode\">\n <button\n type=\"button\"\n class=\"dtp-btn\"\n (click)=\"changeView('month')\"\n [class.active]=\"view === 'month'\">\n {{ localize().month }}\n </button>\n <button\n type=\"button\"\n class=\"dtp-btn\"\n (click)=\"changeView('week')\"\n [class.active]=\"view === 'week'\">\n {{ localize().week }}\n </button>\n <button\n type=\"button\"\n class=\"dtp-btn\"\n (click)=\"changeView('day')\"\n [class.active]=\"view === 'day'\">\n {{ localize().day }}\n </button>\n <button\n type=\"button\"\n class=\"dtp-btn\"\n (click)=\"changeView('event')\"\n [class.active]=\"view === 'event'\">\n {{ localize().event }}\n </button>\n </div>\n </div>\n\n <div class=\"calendar\" #calendarWrapper>\n @switch (view) {\n @case ('month') {\n <ul class=\"weeks\">\n @for (w of weeks; track $index) {\n <li>{{ w }}</li>\n }\n </ul>\n\n <div class=\"month-grid\" [style.minHeight.px]=\"minHeight\">\n @for (row of monthEventRows; track $index; let rowIndex = $index) {\n <div class=\"month-row\">\n @for (\n item of viewDays.slice(rowIndex * 7, rowIndex * 7 + 7);\n track item.date?.getTime() ?? $index\n ) {\n <button\n type=\"button\"\n class=\"month-day\"\n [class.de-active]=\"!item.active\"\n [class.today]=\"item.isToday\"\n [class.selected]=\"item.selected\"\n (click)=\"selectDay($event, item)\">\n <span class=\"day-number\">{{ item.day }}</span>\n </button>\n }\n\n <div class=\"month-event-layer\" aria-live=\"polite\">\n @for (event of row; track event.id ?? event.start.getTime() ?? $index) {\n <button\n type=\"button\"\n class=\"month-event\"\n [class.continues-before]=\"event.continuesBefore\"\n [class.continues-after]=\"event.continuesAfter\"\n [class.event-start]=\"event.isStart\"\n [class.event-end]=\"event.isEnd\"\n [class.is-dragging]=\"\n interaction?.source === event ||\n (interaction?.source?.id != null && interaction?.source?.id === event.id)\n \"\n [style.gridColumn]=\"event.startColumn + 1 + ' / ' + (event.endColumn + 2)\"\n [style.gridRow]=\"event.lane + 1\"\n [style.background]=\"event.backgroundColor || event.color || null\"\n [style.borderColor]=\"event.borderColor || event.color || null\"\n [style.color]=\"event.textColor || null\"\n [title]=\"event.title || ''\"\n (pointerdown)=\"startMonthEventInteraction($event, event)\"\n (click)=\"\n onclickEvent($event, { date: event.start, day: 0, active: true }, event)\n \">\n @if (event.isStart) {\n <span class=\"event-title\">{{ event.title || 'Untitled event' }}</span>\n } @else {\n <span class=\"event-title continuation-title\">{{ event.title || '' }}</span>\n }\n\n @if (event.isStart) {\n <span\n class=\"resize-handle resize-start\"\n title=\"Resize start\"\n (pointerdown)=\"\n startMonthEventInteraction($event, event, 'resize-start')\n \"></span>\n }\n @if (event.isEnd) {\n <span\n class=\"resize-handle resize-end\"\n title=\"Resize end\"\n (pointerdown)=\"\n startMonthEventInteraction($event, event, 'resize-end')\n \"></span>\n }\n </button>\n }\n </div>\n </div>\n }\n </div>\n }\n\n @case ('week') {\n <ng-container [ngTemplateOutlet]=\"timedCalendar\"></ng-container>\n }\n\n @case ('day') {\n <ng-container [ngTemplateOutlet]=\"timedCalendar\"></ng-container>\n }\n\n @case ('event') {\n <div class=\"event-list\">\n @if (eventViewItems.length) {\n @for (item of eventViewItems; track item.event.id ?? item.start.getTime()) {\n <button\n type=\"button\"\n class=\"event-list-item\"\n (click)=\"\n onclickEvent($event, { date: item.start, day: 0, active: true }, item.event)\n \">\n <span\n class=\"event-dot\"\n [style.background]=\"\n item.event.backgroundColor || item.event.color || null\n \"></span>\n <span class=\"event-copy\">\n <strong>{{ item.event.title || 'Untitled event' }}</strong>\n <small>\n {{ formatEventDate(item.start) }}\n @if (item.end.getTime() !== item.start.getTime()) {\n \u2013 {{ formatEventDate(item.end) }}\n }\n </small>\n </span>\n </button>\n }\n } @else {\n <div class=\"empty-events\">No events for this month.</div>\n }\n </div>\n }\n }\n </div>\n</div>\n\n<ng-template #timedCalendar>\n <div class=\"timed-calendar\">\n <div\n class=\"timed-header\"\n [style.gridTemplateColumns]=\"'64px repeat(' + weekDays.length + ', minmax(0, 1fr))'\">\n <div class=\"corner\"></div>\n @for (day of weekDays; track day.date.getTime()) {\n <button\n type=\"button\"\n class=\"day-header\"\n [class.today]=\"day.isToday\"\n (click)=\"selectDay($event, { date: day.date, day: 0, active: true })\">\n <span>{{ day.label }}</span>\n <strong>{{ day.dayNumber }}</strong>\n </button>\n }\n </div>\n\n <div\n class=\"all-day-row\"\n [style.gridTemplateColumns]=\"'64px repeat(' + weekDays.length + ', minmax(0, 1fr))'\">\n <div class=\"all-day-label\">All day</div>\n @for (day of weekDays; track day.date.getTime(); let i = $index) {\n <div class=\"all-day-cell\">\n @for (\n event of allDayByColumn[i];\n track event.id ?? event.title ?? event.start.getTime()\n ) {\n <button\n type=\"button\"\n class=\"timed-event all-day-event\"\n [class.continues-before]=\"event.continuesBefore\"\n [class.continues-after]=\"event.continuesAfter\"\n [style.background]=\"event.backgroundColor || event.color || null\"\n [style.borderColor]=\"event.borderColor || event.color || null\"\n [style.color]=\"event.textColor || null\"\n [title]=\"event.title || ''\"\n (pointerdown)=\"startTimedEventInteraction($event, event)\"\n (click)=\"onTimedEventClick($event, event, day.date)\">\n <span>{{ event.title || 'Untitled event' }}</span>\n @if (event.isStart) {\n <span\n class=\"resize-handle resize-start\"\n (pointerdown)=\"startTimedEventInteraction($event, event, 'resize-start')\"></span>\n }\n @if (event.isEnd) {\n <span\n class=\"resize-handle resize-end\"\n (pointerdown)=\"startTimedEventInteraction($event, event, 'resize-end')\"></span>\n }\n </button>\n }\n </div>\n }\n </div>\n\n <div\n class=\"time-grid\"\n [style.gridTemplateColumns]=\"'64px repeat(' + weekDays.length + ', minmax(0, 1fr))'\">\n <div class=\"time-axis\">\n @for (minutes of timeSlots; track minutes) {\n <div class=\"time-label\" [style.top.px]=\"(minutes / 60) * hourHeight\">\n @if (minutes % 60 === 0) {\n {{ formatTime(minutes) }}\n }\n </div>\n }\n </div>\n\n @for (day of weekDays; track day.date.getTime()) {\n <div class=\"day-column\">\n @for (minutes of timeSlots; track minutes) {\n <div class=\"time-slot\" [class.hour]=\"minutes % 60 === 0\"></div>\n }\n\n @for (event of day.events; track event.id ?? event.title ?? event.start.getTime()) {\n <button\n type=\"button\"\n class=\"timed-event\"\n [class.continues-before]=\"event.continuesBefore\"\n [class.continues-after]=\"event.continuesAfter\"\n [style.top.px]=\"event.top\"\n [style.height.px]=\"event.height\"\n [style.insetInlineStart.%]=\"event.column * (100 / event.columnCount)\"\n [style.width.%]=\"100 / event.columnCount - 1\"\n [style.background]=\"event.backgroundColor || event.color || null\"\n [style.borderColor]=\"event.borderColor || event.color || null\"\n [style.color]=\"event.textColor || null\"\n [title]=\"event.title || ''\"\n (pointerdown)=\"startTimedEventInteraction($event, event)\"\n (click)=\"onTimedEventClick($event, event, day.date)\">\n <strong>{{ event.title || 'Untitled event' }}</strong>\n @if (event.height >= 42) {\n <small>\n {{ formatTime(event.start.getHours() * 60 + event.start.getMinutes()) }}\n </small>\n }\n @if (event.isStart) {\n <span\n class=\"resize-handle resize-start\"\n (pointerdown)=\"startTimedEventInteraction($event, event, 'resize-start')\"></span>\n }\n @if (event.isEnd) {\n <span\n class=\"resize-handle resize-end\"\n (pointerdown)=\"startTimedEventInteraction($event, event, 'resize-end')\"></span>\n }\n </button>\n }\n </div>\n }\n </div>\n </div>\n</ng-template>\n\n<ng-template #defaultPreviousBTNTemplate>\n <svg width=\"15px\" height=\"30px\" viewBox=\"0 0 320 512\">\n <path\n fill=\"currentColor\"\n d=\"M224 480c-8.188 0-16.38-3.125-22.62-9.375l-192-192c-12.5-12.5-12.5-32.75 0-45.25l192-192c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25L77.25 256l169.4 169.4c12.5 12.5 12.5 32.75 0 45.25C240.4 476.9 232.2 480 224 480z\" />\n </svg>\n</ng-template>\n\n<ng-template #defaultNextBTNTemplate>\n <svg width=\"15px\" height=\"30px\" viewBox=\"0 0 320 512\">\n <path\n fill=\"currentColor\"\n d=\"M96 480c-8.188 0-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L242.8 256L73.38 86.63c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l192 192c12.5 12.5 12.5 32.75 0 45.25l-192 192C112.4 476.9 104.2 480 96 480z\" />\n </svg>\n</ng-template>\n", styles: [":host{--ngx-color-bg: light-dark(#fff, #171a24);--ngx-color-text: light-dark(#16181d, #f7f7f8);--ngx-border-color: light-dark(#e1e4ea, #303541);--ngx-muted: color-mix(in srgb, var(--ngx-color-text) 55%, transparent);--ngx-event-bg: light-dark(#eef0ff, #2f3150);--ngx-event-text: light-dark(#3547a4, #dce1ff);--ngx-today: #3f51b5}.wrapper{background:var(--ngx-color-bg);color:var(--ngx-color-text);border:1px solid var(--ngx-border-color);border-radius:10px;overflow:hidden}.wrapper .dtp-btn{background:none;border:none;color:inherit;border-radius:6px;padding:5px 12px;box-shadow:0 0 4px #0000001f;transition:background .16s ease,transform .16s ease;display:inline-flex;align-items:center;justify-content:center}.wrapper .dtp-btn:not([disabled]):hover{cursor:pointer;background:#7f7fa02e}.wrapper .dtp-btn.active{background:#7f7fa03d}.wrapper .dtp-btn svg{fill:currentColor}.wrapper .header{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px;border-bottom:1px solid var(--ngx-border-color)}.wrapper .header .current-date{text-align:center;flex:1;min-width:0;font-weight:700}.wrapper .nxt-prv-buttons,.wrapper .view-mode{display:flex;align-items:center;gap:4px}.calendar{padding:10px;min-width:0}.weeks{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));list-style:none;padding:0;margin:0 0 8px;border-inline-start:1px solid var(--ngx-border-color)}.weeks li{padding:7px 4px;text-align:center;color:var(--ngx-muted);font-size:11px;font-weight:700;border-inline-end:1px solid var(--ngx-border-color)}.month-grid{display:grid;grid-template-rows:repeat(6,minmax(92px,1fr));border-inline-start:1px solid var(--ngx-border-color);border-top:1px solid var(--ngx-border-color);position:relative}.month-row{position:relative;display:grid;grid-template-columns:repeat(7,minmax(0,1fr));min-height:92px;border-bottom:1px solid var(--ngx-border-color)}.month-day{position:relative;min-width:0;min-height:92px;overflow:hidden;padding:4px;border:0;border-inline-end:1px solid var(--ngx-border-color);background:transparent;color:inherit;font:inherit;text-align:start;cursor:pointer;transition:background .15s ease}.month-day:hover{background:#7f7fa00d}.month-day.de-active{opacity:.48}.month-day.selected{outline:2px solid rgba(63,81,181,.3);outline-offset:-2px}.month-day.today .day-number{background:#3f51b51a;color:var(--ngx-today);font-weight:800}.day-number{width:27px;height:27px;display:grid;place-items:center;margin-inline-start:auto;border-radius:50%;font-size:12px;font-weight:600}.month-event-layer{position:absolute;inset:0;display:grid;grid-template-columns:repeat(7,minmax(0,1fr));grid-template-rows:repeat(4,26px);pointer-events:none;padding-top:34px}.month-event{position:relative;z-index:3;min-width:0;height:22px;margin-inline:2px;padding:2px 7px;border:1px solid transparent;border-radius:5px;overflow:hidden;background:var(--ngx-event-bg);color:var(--ngx-event-text);font:inherit;font-size:11px;font-weight:600;line-height:17px;text-align:start;white-space:nowrap;text-overflow:ellipsis;pointer-events:auto;cursor:grab;touch-action:none;box-sizing:border-box}.month-event:active{cursor:grabbing}.month-event:hover{filter:brightness(.97);box-shadow:0 2px 7px #00000024}.month-event.is-dragging{opacity:.78;box-shadow:0 5px 14px #0003}.month-event.continues-before{border-start-start-radius:2px;border-end-start-radius:2px;margin-inline-start:0}.month-event.continues-after{border-start-end-radius:2px;border-end-end-radius:2px;margin-inline-end:0}.event-title{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.continuation-title{opacity:.85}.resize-handle{position:absolute;top:0;bottom:0;width:7px;z-index:5;cursor:ew-resize;touch-action:none}.resize-handle:after{content:\"\";position:absolute;top:5px;bottom:5px;inset-inline-start:3px;width:2px;border-radius:2px;background:currentColor;opacity:.45}.resize-start{inset-inline-start:0}.resize-end{inset-inline-end:0}.timed-calendar{min-width:0;border:1px solid var(--ngx-border-color);border-radius:8px;overflow:auto}.timed-header,.all-day-row,.time-grid{display:grid;min-width:620px}.timed-header{position:sticky;top:0;z-index:5;background:var(--ngx-color-bg);border-bottom:1px solid var(--ngx-border-color)}.corner{border-inline-end:1px solid var(--ngx-border-color)}.day-header{min-width:0;height:58px;padding:6px;border:0;border-inline-end:1px solid var(--ngx-border-color);background:transparent;color:inherit;cursor:pointer;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px}.day-header span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:11px;color:var(--ngx-muted)}.day-header strong{width:30px;height:30px;display:grid;place-items:center;border-radius:50%;font-size:14px}.day-header.today strong{background:var(--ngx-today);color:#fff}.day-header:hover{background:#7f7fa012}.all-day-row{min-height:34px;border-bottom:1px solid var(--ngx-border-color);background:color-mix(in srgb,var(--ngx-color-bg) 94%,currentColor)}.all-day-row .all-day-label{padding:8px 5px;color:var(--ngx-muted);font-size:10px;border-inline-end:1px solid var(--ngx-border-color);text-align:center}.all-day-row .all-day-cell{min-width:0;padding:4px;border-inline-end:1px solid var(--ngx-border-color);display:flex;flex-direction:column;gap:3px}.time-grid{position:relative;align-items:stretch;min-height:1536px}.time-axis{position:relative;border-inline-end:1px solid var(--ngx-border-color);background:var(--ngx-color-bg)}.time-label{position:absolute;inset-inline:0 5px;transform:translateY(-50%);text-align:end;color:var(--ngx-muted);font-size:10px;pointer-events:none}.day-column{position:relative;min-width:0;height:1536px;border-inline-end:1px solid var(--ngx-border-color);background:repeating-linear-gradient(to bottom,transparent 0,transparent 31px,var(--ngx-border-color) 32px,transparent 33px,transparent 63px,var(--ngx-border-color) 64px)}.time-slot{height:32px;pointer-events:none;border-bottom:1px dashed color-mix(in srgb,var(--ngx-border-color) 55%,transparent)}.time-slot.hour{border-bottom-style:solid;border-bottom-color:var(--ngx-border-color)}.timed-event{position:absolute;z-index:2;min-width:24px;padding:4px 7px;border:1px solid transparent;border-radius:5px;overflow:hidden;background:var(--ngx-event-bg);color:var(--ngx-event-text);font:inherit;font-size:11px;line-height:15px;text-align:start;cursor:grab;box-sizing:border-box;touch-action:none;transition:filter .12s ease,box-shadow .12s ease}.timed-event:hover{filter:brightness(.97);box-shadow:0 2px 7px #00000024;z-index:4}.timed-event strong,.timed-event small{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.timed-event small{opacity:.72;font-size:10px}.timed-event.continues-before{border-start-start-radius:2px;border-end-start-radius:2px}.timed-event.continues-after{border-start-end-radius:2px;border-end-end-radius:2px}.timed-event.all-day-event{cursor:grab;position:relative;inset:auto!important;width:100%!important;min-height:24px;height:24px;padding-block:2px}.event-list{display:flex;flex-direction:column;gap:6px}.event-list-item{display:flex;align-items:center;gap:10px;width:100%;padding:10px 12px;border:1px solid var(--ngx-border-color);border-radius:8px;background:transparent;color:inherit;text-align:start;cursor:pointer}.event-list-item:hover{background:#7f7fa014}.event-list-item .event-dot{width:8px;height:8px;flex:0 0 8px;border-radius:50%;background:var(--ngx-today)}.event-list-item .event-copy{min-width:0;display:flex;flex-direction:column;gap:2px}.event-list-item .event-copy strong,.event-list-item .event-copy small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.event-list-item .event-copy small{opacity:.58}.empty-events{padding:30px;text-align:center;opacity:.55}:host-context([dir=rtl]) .nxt-prv-buttons .previous svg{transform:rotate(180deg)}:host-context([dir=rtl]) .nxt-prv-buttons .next svg{transform:rotate(180deg)}@media(max-width:700px){.wrapper .header{flex-wrap:wrap}.wrapper .header .current-date{order:-1;flex-basis:100%}.view-mode{width:100%;justify-content:center}}\n"] }]
|
|
2841
|
+
}], ctorParameters: () => [], propDecorators: { localize: [{ type: i0.Input, args: [{ isSignal: true, alias: "localize", required: false }] }], config: [{
|
|
2275
2842
|
type: Input
|
|
2276
2843
|
}], locale: [{
|
|
2277
2844
|
type: Input
|
|
@@ -2289,9 +2856,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
2289
2856
|
type: Output
|
|
2290
2857
|
}], selectEvent: [{
|
|
2291
2858
|
type: Output
|
|
2859
|
+
}], eventChange: [{
|
|
2860
|
+
type: Output
|
|
2861
|
+
}], eventsChange: [{
|
|
2862
|
+
type: Output
|
|
2292
2863
|
}], calendarWrapper: [{ type: i0.ViewChild, args: ['calendarWrapper', { isSignal: true }] }], onResize: [{
|
|
2293
2864
|
type: HostListener,
|
|
2294
|
-
args: ['window:resize'
|
|
2865
|
+
args: ['window:resize']
|
|
2866
|
+
}], onDocumentPointerMove: [{
|
|
2867
|
+
type: HostListener,
|
|
2868
|
+
args: ['document:pointermove', ['$event']]
|
|
2869
|
+
}], onDocumentPointerUp: [{
|
|
2870
|
+
type: HostListener,
|
|
2871
|
+
args: ['document:pointerup', ['$event']]
|
|
2872
|
+
}], onDocumentPointerCancel: [{
|
|
2873
|
+
type: HostListener,
|
|
2874
|
+
args: ['document:pointercancel', ['$event']]
|
|
2295
2875
|
}] } });
|
|
2296
2876
|
|
|
2297
2877
|
function dedupeAdapters(adapters) {
|
|
@@ -2306,9 +2886,551 @@ function provideDateAdapters(...additional) {
|
|
|
2306
2886
|
}));
|
|
2307
2887
|
}
|
|
2308
2888
|
|
|
2889
|
+
function createDateRange(start = null, end = null) {
|
|
2890
|
+
return { start, end };
|
|
2891
|
+
}
|
|
2892
|
+
|
|
2893
|
+
class DateModel {
|
|
2894
|
+
date;
|
|
2895
|
+
active;
|
|
2896
|
+
isToday;
|
|
2897
|
+
selected;
|
|
2898
|
+
}
|
|
2899
|
+
class DateViewYear extends DateModel {
|
|
2900
|
+
year;
|
|
2901
|
+
}
|
|
2902
|
+
class DateViewMonth extends DateModel {
|
|
2903
|
+
month;
|
|
2904
|
+
displayMonth;
|
|
2905
|
+
}
|
|
2906
|
+
class DateViewDay extends DateModel {
|
|
2907
|
+
day;
|
|
2908
|
+
events;
|
|
2909
|
+
inRange;
|
|
2910
|
+
rangeStart;
|
|
2911
|
+
rangeEnd;
|
|
2912
|
+
inRangePreview;
|
|
2913
|
+
}
|
|
2914
|
+
class DateViewWeek extends DateModel {
|
|
2915
|
+
time;
|
|
2916
|
+
weeks = [];
|
|
2917
|
+
displayTime;
|
|
2918
|
+
}
|
|
2919
|
+
|
|
2920
|
+
function normalizeDateRange(value) {
|
|
2921
|
+
if (Array.isArray(value)) {
|
|
2922
|
+
return normalizeDateRange({ start: value[0], end: value[1] });
|
|
2923
|
+
}
|
|
2924
|
+
const start = deserialize(value?.start);
|
|
2925
|
+
const end = deserialize(value?.end);
|
|
2926
|
+
if (start && end && compareDate(start, end) > 0) {
|
|
2927
|
+
return { start: end, end: start };
|
|
2928
|
+
}
|
|
2929
|
+
return { start, end };
|
|
2930
|
+
}
|
|
2931
|
+
function isCompleteDateRange(range) {
|
|
2932
|
+
return !!range.start && !!range.end && isValid(range.start) && isValid(range.end);
|
|
2933
|
+
}
|
|
2934
|
+
function isDateInRange(date, range) {
|
|
2935
|
+
if (!range.start || !range.end)
|
|
2936
|
+
return false;
|
|
2937
|
+
return compareDate(date, range.start) >= 0 && compareDate(date, range.end) <= 0;
|
|
2938
|
+
}
|
|
2939
|
+
function isDateInPreviewRange(date, start, previewEnd) {
|
|
2940
|
+
if (!start || !previewEnd)
|
|
2941
|
+
return false;
|
|
2942
|
+
const from = compareDate(start, previewEnd) <= 0 ? start : previewEnd;
|
|
2943
|
+
const to = compareDate(start, previewEnd) <= 0 ? previewEnd : start;
|
|
2944
|
+
return compareDate(date, from) >= 0 && compareDate(date, to) <= 0;
|
|
2945
|
+
}
|
|
2946
|
+
|
|
2947
|
+
class NgxDateRangePickerComponent extends NgxDatePickerBase {
|
|
2948
|
+
defaultLocalization = inject(NGX_CALENDAR_LOCALIZATION);
|
|
2949
|
+
localize = input(this.defaultLocalization, /* @ts-ignore */
|
|
2950
|
+
...(ngDevMode ? [{ debugName: "localize" }] : /* istanbul ignore next */ []));
|
|
2951
|
+
config = new NgxDatePickerConfig();
|
|
2952
|
+
set locale(value) {
|
|
2953
|
+
this._locale = value || 'en';
|
|
2954
|
+
this.adapter = this.dateAdapterRegistry.resolve(this._locale);
|
|
2955
|
+
this.init();
|
|
2956
|
+
}
|
|
2957
|
+
set min(value) {
|
|
2958
|
+
const next = deserialize(value);
|
|
2959
|
+
if (!sameDate(next, this.minDate)) {
|
|
2960
|
+
this.minDate = next;
|
|
2961
|
+
this._validatorOnChange();
|
|
2962
|
+
this.renderِDatePicker(this.view);
|
|
2963
|
+
}
|
|
2964
|
+
}
|
|
2965
|
+
set max(value) {
|
|
2966
|
+
const next = deserialize(value);
|
|
2967
|
+
if (!sameDate(next, this.maxDate)) {
|
|
2968
|
+
this.maxDate = next;
|
|
2969
|
+
this._validatorOnChange();
|
|
2970
|
+
this.renderِDatePicker(this.view);
|
|
2971
|
+
}
|
|
2972
|
+
}
|
|
2973
|
+
view = 'day';
|
|
2974
|
+
rangeChange = new EventEmitter();
|
|
2975
|
+
change = new EventEmitter();
|
|
2976
|
+
range = { start: null, end: null };
|
|
2977
|
+
hoverDate = null;
|
|
2978
|
+
weekDays = [];
|
|
2979
|
+
calendarHeader = '';
|
|
2980
|
+
_onChange = (_value) => { };
|
|
2981
|
+
_onTouched = () => { };
|
|
2982
|
+
_validatorOnChange = () => { };
|
|
2983
|
+
isDisabled = false;
|
|
2984
|
+
ngOnInit() {
|
|
2985
|
+
this.init();
|
|
2986
|
+
}
|
|
2987
|
+
updateConfig(value) {
|
|
2988
|
+
this.config = { ...new NgxDatePickerConfig(), ...value };
|
|
2989
|
+
}
|
|
2990
|
+
writeValue(value) {
|
|
2991
|
+
this.range = normalizeDateRange(value);
|
|
2992
|
+
this.init();
|
|
2993
|
+
}
|
|
2994
|
+
registerOnChange(fn) {
|
|
2995
|
+
this._onChange = fn;
|
|
2996
|
+
}
|
|
2997
|
+
registerOnTouched(fn) {
|
|
2998
|
+
this._onTouched = fn;
|
|
2999
|
+
}
|
|
3000
|
+
registerOnValidatorChange(fn) {
|
|
3001
|
+
this._validatorOnChange = fn;
|
|
3002
|
+
}
|
|
3003
|
+
setDisabledState(disabled) {
|
|
3004
|
+
this.isDisabled = disabled;
|
|
3005
|
+
}
|
|
3006
|
+
validate(_control) {
|
|
3007
|
+
const { start, end } = this.range;
|
|
3008
|
+
if (start && !isValid(start))
|
|
3009
|
+
return { invalid: true };
|
|
3010
|
+
if (end && !isValid(end))
|
|
3011
|
+
return { invalid: true };
|
|
3012
|
+
if (start && this.minDate && compareDate(start, this.minDate) < 0) {
|
|
3013
|
+
return { min: this.minDate };
|
|
3014
|
+
}
|
|
3015
|
+
if (start && this.maxDate && compareDate(start, this.maxDate) > 0) {
|
|
3016
|
+
return { max: this.maxDate };
|
|
3017
|
+
}
|
|
3018
|
+
if (end && this.minDate && compareDate(end, this.minDate) < 0) {
|
|
3019
|
+
return { min: this.minDate };
|
|
3020
|
+
}
|
|
3021
|
+
if (end && this.maxDate && compareDate(end, this.maxDate) > 0) {
|
|
3022
|
+
return { max: this.maxDate };
|
|
3023
|
+
}
|
|
3024
|
+
if (start && end && compareDate(start, end) > 0) {
|
|
3025
|
+
return { range: true };
|
|
3026
|
+
}
|
|
3027
|
+
return null;
|
|
3028
|
+
}
|
|
3029
|
+
renderِDatePicker(view) {
|
|
3030
|
+
super.renderِDatePicker(view, undefined, [], () => {
|
|
3031
|
+
this.applyRangeState();
|
|
3032
|
+
const start = this.range.start;
|
|
3033
|
+
const end = this.range.end;
|
|
3034
|
+
const startText = start
|
|
3035
|
+
? this.adapter.formatDate(this.adapter.toLocale(start), 'EEEE, d MMMM, yyyy')
|
|
3036
|
+
: '';
|
|
3037
|
+
const endText = end
|
|
3038
|
+
? this.adapter.formatDate(this.adapter.toLocale(end), 'EEEE, d MMMM, yyyy')
|
|
3039
|
+
: '';
|
|
3040
|
+
this.calendarHeader = endText
|
|
3041
|
+
? `${startText} – ${endText}`
|
|
3042
|
+
: startText || 'Select date range';
|
|
3043
|
+
});
|
|
3044
|
+
}
|
|
3045
|
+
init() {
|
|
3046
|
+
this.months = this.adapter.longMonths;
|
|
3047
|
+
const shortDays = this.adapter.shortDays;
|
|
3048
|
+
const longDays = this.adapter.longDays;
|
|
3049
|
+
this.weekDays = shortDays.map((min, i) => ({ min, name: longDays[i] }));
|
|
3050
|
+
const anchor = this.range.end || this.range.start || this.adapter.getDate(this.adapter.today());
|
|
3051
|
+
const locale = this.adapter.toLocale(anchor);
|
|
3052
|
+
this.currYear = locale.year;
|
|
3053
|
+
this.currMonth = locale.month ?? 0;
|
|
3054
|
+
this.renderِDatePicker(this.view);
|
|
3055
|
+
}
|
|
3056
|
+
changeView(view) {
|
|
3057
|
+
this.view = view;
|
|
3058
|
+
this.renderِDatePicker(view);
|
|
3059
|
+
}
|
|
3060
|
+
gotoToday() {
|
|
3061
|
+
const today = this.adapter.today();
|
|
3062
|
+
const date = today.date ?? this.adapter.getDate(today);
|
|
3063
|
+
this.currYear = today.year;
|
|
3064
|
+
this.currMonth = today.month ?? 0;
|
|
3065
|
+
// Keep an existing completed range; today is only a navigation shortcut.
|
|
3066
|
+
if (!this.range.start || this.range.end) {
|
|
3067
|
+
this.range = { start: date, end: null };
|
|
3068
|
+
this.emitValue();
|
|
3069
|
+
}
|
|
3070
|
+
this.changeView('day');
|
|
3071
|
+
}
|
|
3072
|
+
next() {
|
|
3073
|
+
if (this.view === 'year') {
|
|
3074
|
+
this.currYear += 20;
|
|
3075
|
+
}
|
|
3076
|
+
else if (this.view === 'month') {
|
|
3077
|
+
this.currYear++;
|
|
3078
|
+
}
|
|
3079
|
+
else {
|
|
3080
|
+
this.currMonth++;
|
|
3081
|
+
}
|
|
3082
|
+
if (this.currMonth < 0 || this.currMonth > 11) {
|
|
3083
|
+
let date = new Date(this.currYear, this.currMonth);
|
|
3084
|
+
this.currYear = date.getFullYear();
|
|
3085
|
+
this.currMonth = date.getMonth();
|
|
3086
|
+
}
|
|
3087
|
+
this.renderِDatePicker(this.view);
|
|
3088
|
+
}
|
|
3089
|
+
previous() {
|
|
3090
|
+
if (this.view === 'year') {
|
|
3091
|
+
this.currYear -= 20;
|
|
3092
|
+
}
|
|
3093
|
+
else if (this.view === 'month') {
|
|
3094
|
+
this.currYear--;
|
|
3095
|
+
}
|
|
3096
|
+
else {
|
|
3097
|
+
this.currMonth--;
|
|
3098
|
+
}
|
|
3099
|
+
if (this.currMonth < 0 || this.currMonth > 11) {
|
|
3100
|
+
let date = new Date(this.currYear, this.currMonth);
|
|
3101
|
+
this.currYear = date.getFullYear();
|
|
3102
|
+
this.currMonth = date.getMonth();
|
|
3103
|
+
}
|
|
3104
|
+
this.renderِDatePicker(this.view);
|
|
3105
|
+
}
|
|
3106
|
+
selectDay(event, item) {
|
|
3107
|
+
event.stopPropagation();
|
|
3108
|
+
if (!item.active || !item.date || this.isDisabled)
|
|
3109
|
+
return;
|
|
3110
|
+
const date = item.date;
|
|
3111
|
+
if (!this.range.start || this.range.end) {
|
|
3112
|
+
this.range = { start: date, end: null };
|
|
3113
|
+
}
|
|
3114
|
+
else {
|
|
3115
|
+
this.range =
|
|
3116
|
+
compareDate(date, this.range.start) < 0
|
|
3117
|
+
? { start: date, end: this.range.start }
|
|
3118
|
+
: { start: this.range.start, end: date };
|
|
3119
|
+
this.hoverDate = null;
|
|
3120
|
+
}
|
|
3121
|
+
this.applyRangeState();
|
|
3122
|
+
this.emitValue();
|
|
3123
|
+
if (isCompleteDateRange(this.range)) {
|
|
3124
|
+
this._onTouched();
|
|
3125
|
+
}
|
|
3126
|
+
}
|
|
3127
|
+
selectMonth(event, item) {
|
|
3128
|
+
event.stopPropagation();
|
|
3129
|
+
if (item.active) {
|
|
3130
|
+
this.currMonth = item.month;
|
|
3131
|
+
this.changeView('day');
|
|
3132
|
+
}
|
|
3133
|
+
}
|
|
3134
|
+
selectYear(event, item) {
|
|
3135
|
+
event.stopPropagation();
|
|
3136
|
+
if (item.active) {
|
|
3137
|
+
this.currYear = item.year;
|
|
3138
|
+
this.changeView('month');
|
|
3139
|
+
}
|
|
3140
|
+
}
|
|
3141
|
+
onDayEnter(item) {
|
|
3142
|
+
if (this.range.start && !this.range.end && item.active) {
|
|
3143
|
+
this.hoverDate = item.date ?? null;
|
|
3144
|
+
this.applyRangeState();
|
|
3145
|
+
}
|
|
3146
|
+
}
|
|
3147
|
+
onDayLeave() {
|
|
3148
|
+
if (this.hoverDate) {
|
|
3149
|
+
this.hoverDate = null;
|
|
3150
|
+
this.applyRangeState();
|
|
3151
|
+
}
|
|
3152
|
+
}
|
|
3153
|
+
clear() {
|
|
3154
|
+
this.range = { start: null, end: null };
|
|
3155
|
+
this.hoverDate = null;
|
|
3156
|
+
this.applyRangeState();
|
|
3157
|
+
this.emitValue();
|
|
3158
|
+
this._onTouched();
|
|
3159
|
+
}
|
|
3160
|
+
applyRangeState() {
|
|
3161
|
+
for (const item of this.viewDays) {
|
|
3162
|
+
if (!item.date)
|
|
3163
|
+
continue;
|
|
3164
|
+
item.rangeStart = !!this.range.start && sameDate(item.date, this.range.start);
|
|
3165
|
+
item.rangeEnd = !!this.range.end && sameDate(item.date, this.range.end);
|
|
3166
|
+
item.inRange = isDateInRange(item.date, this.range);
|
|
3167
|
+
item.inRangePreview =
|
|
3168
|
+
!this.range.end && isDateInPreviewRange(item.date, this.range.start, this.hoverDate);
|
|
3169
|
+
item.selected = !!item.rangeStart || !!item.rangeEnd;
|
|
3170
|
+
}
|
|
3171
|
+
}
|
|
3172
|
+
emitValue() {
|
|
3173
|
+
const value = { ...this.range };
|
|
3174
|
+
this._onChange(value);
|
|
3175
|
+
this.rangeChange.emit(value);
|
|
3176
|
+
this.change.emit(value);
|
|
3177
|
+
}
|
|
3178
|
+
stopPagination(event) {
|
|
3179
|
+
event.stopPropagation();
|
|
3180
|
+
}
|
|
3181
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NgxDateRangePickerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
3182
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.4", type: NgxDateRangePickerComponent, isStandalone: true, selector: "ngx-date-range-picker", inputs: { localize: { classPropertyName: "localize", publicName: "localize", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: false, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: false, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: false, isRequired: false, transformFunction: null }, view: { classPropertyName: "view", publicName: "view", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { rangeChange: "rangeChange", change: "change" }, providers: [
|
|
3183
|
+
DateAdapterRegistry,
|
|
3184
|
+
{
|
|
3185
|
+
provide: NG_VALUE_ACCESSOR,
|
|
3186
|
+
useExisting: forwardRef(() => NgxDateRangePickerComponent),
|
|
3187
|
+
multi: true,
|
|
3188
|
+
},
|
|
3189
|
+
{
|
|
3190
|
+
provide: NG_VALIDATORS,
|
|
3191
|
+
useExisting: forwardRef(() => NgxDateRangePickerComponent),
|
|
3192
|
+
multi: true,
|
|
3193
|
+
},
|
|
3194
|
+
], usesInheritance: true, ngImport: i0, template: "<div class=\"wrapper\" (click)=\"stopPagination($event)\">\n <div class=\"header\">\n <div class=\"calendar-icon\" aria-hidden=\"true\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path d=\"M16 2V6M8 2V6\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" />\n <path\n d=\"M13 4H11C7.22876 4 5.34315 4 4.17157 5.17157C3 6.34315 3 8.22876 3 12V14C3 17.7712 3 19.6569 4.17157 20.8284C5 22 7.22876 22 11 22H13C16.7712 22 18.6569 22 19.8284 20.8284C21 17.7712 21 14V12C21 8.22876 19.8284 5.17157 19.8284 5.17157C4 4 13 4 13 4Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\" />\n <path d=\"M3 10H21\" stroke=\"currentColor\" stroke-width=\"1.5\" />\n </svg>\n </div>\n <div class=\"header-copy\">\n <div class=\"header-title\">Date range</div>\n <div class=\"header-value\">{{ calendarHeader }}</div>\n </div>\n </div>\n\n <div class=\"sub-header\">\n <button type=\"button\" class=\"nav-button\" id=\"prev\" (click)=\"previous()\" aria-label=\"Previous\">\n <ng-template\n [ngTemplateOutlet]=\"\n config.previousButtonTemplate || defaultPreviousBTNTemplate\n \"></ng-template>\n </button>\n\n <button type=\"button\" class=\"current-date\" (click)=\"changeView('month')\">\n <span>{{ displayMonth }}</span>\n <span>{{ currYear }}</span>\n </button>\n\n <button type=\"button\" class=\"nav-button\" id=\"next\" (click)=\"next()\" aria-label=\"Next\">\n <ng-template\n [ngTemplateOutlet]=\"config.nextButtonTemplate || defaultNextBTNTemplate\"></ng-template>\n </button>\n </div>\n\n <div class=\"calendar\">\n @if (view === 'day') {\n <ul class=\"weeks\">\n @for (w of weekDays; track $index) {\n <li [title]=\"w.name\">{{ w.min }}</li>\n }\n </ul>\n\n <ul class=\"days\">\n @for (item of viewDays; track $index) {\n <li\n [class.de-active]=\"!item.active\"\n [class.today]=\"item.isToday\"\n [class.in-range]=\"item.inRange\"\n [class.in-range-preview]=\"item.inRangePreview\"\n [class.range-start]=\"item.rangeStart\"\n [class.range-end]=\"item.rangeEnd\"\n [class.range-single]=\"item.rangeStart && item.rangeEnd\"\n (mouseenter)=\"onDayEnter(item)\"\n (mouseleave)=\"onDayLeave()\"\n (click)=\"selectDay($event, item)\"\n [attr.aria-selected]=\"\n item.rangeStart || item.rangeEnd || item.inRange || item.inRangePreview\n \">\n <span class=\"day-number\">{{ item.day }}</span>\n </li>\n }\n </ul>\n } @else if (view === 'month') {\n <ul class=\"months\">\n @for (item of viewMonths; track $index; let i = $index) {\n <li\n [class.de-active]=\"!item.active\"\n [class.today]=\"item.isToday\"\n [class.selected]=\"item.selected\"\n (click)=\"selectMonth($event, item)\">\n {{ i + 1 }}.{{ item.displayMonth }}\n </li>\n }\n </ul>\n } @else {\n <ul class=\"years\">\n @for (item of viewYears; track $index) {\n <li\n [class.de-active]=\"!item.active\"\n [class.today]=\"item.isToday\"\n [class.selected]=\"item.selected\"\n (click)=\"selectYear($event, item)\">\n {{ item.year }}\n </li>\n }\n </ul>\n }\n\n <div class=\"calendar-footer\">\n @if (config.clearButton) {\n <button type=\"button\" (click)=\"clear()\">{{ localize().clear }}</button>\n }\n @if (config.todayButton) {\n <button type=\"button\" (click)=\"gotoToday()\">{{ localize().today }}</button>\n }\n </div>\n </div>\n</div>\n\n<ng-template #defaultPreviousBTNTemplate>\n <svg width=\"14\" height=\"28\" viewBox=\"0 0 320 512\">\n <path\n fill=\"currentColor\"\n d=\"M224 480c-8.188 0-16.38-3.125-22.62-9.375l-192-192c-12.5-12.5-12.5-32.75 0-45.25l192-192c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25L77.25 256l169.4 169.4c12.5 12.5 12.5 32.75 0 45.25C240.4 476.9 232.2 480 224 480z\" />\n </svg>\n</ng-template>\n\n<ng-template #defaultNextBTNTemplate>\n <svg width=\"14\" height=\"28\" viewBox=\"0 0 320 512\">\n <path\n fill=\"currentColor\"\n d=\"M96 480c-8.188 0-16.38-3.125-22.62-9.375L73.38 86.63c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l192 192c12.5 12.5 12.5 32.75 0 45.25l-192 192C112.4 476.9 104.2 480 96 480z\" />\n </svg>\n</ng-template>\n", styles: [":host{--ngx-range-bg: light-dark(#ffffff, #10162b);--ngx-range-text: light-dark(#171717, #f4f4f5);--ngx-range-muted: light-dark(#8a8f98, #72798a);--ngx-range-border: light-dark(#e6e8ee, #272d40);--ngx-range-accent: light-dark(#6544e8, #8d6cff);--ngx-range-accent-soft: light-dark(#eeeaff, #2b2252);--ngx-range-hover: light-dark(#f4f2ff, #211b38)}.wrapper{width:336px;overflow:hidden;border:1px solid var(--ngx-range-border);border-radius:14px;background:var(--ngx-range-bg);color:var(--ngx-range-text);box-shadow:0 18px 55px #0000002e;font-size:13px}.header{display:flex;gap:12px;padding:15px 16px;background:linear-gradient(135deg,#6747e9,#8b64f5);color:#fff}.header .calendar-icon{width:42px;height:42px;display:grid;place-items:center;border-radius:12px;background:#ffffff29}.header .header-copy{min-width:0;flex:1}.header .header-title{opacity:.75;font-size:11px;text-transform:uppercase;letter-spacing:.08em}.header .header-value{margin-top:3px;font-size:14px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sub-header{display:grid;grid-template-columns:40px 1fr 40px;align-items:center;padding:8px 10px;border-bottom:1px solid var(--ngx-range-border)}.sub-header button{color:inherit;border:0;background:transparent;cursor:pointer}.sub-header .nav-button{width:36px;height:36px;display:grid;place-items:center;border-radius:9px}.sub-header .nav-button:hover{background:var(--ngx-range-hover)}.sub-header .current-date{display:flex;justify-content:center;gap:6px;font-weight:700;font-size:14px}.calendar{padding:10px 12px 12px}.calendar ul{display:flex;flex-wrap:wrap;list-style:none;padding:0;margin:0}.calendar .weeks li,.calendar .days li{width:14.2857142857%}.calendar .weeks{margin-bottom:4px}.calendar .weeks li{height:30px;display:grid;place-items:center;color:var(--ngx-range-muted);font-size:11px;font-weight:700}.calendar .days li{position:relative;height:40px;display:grid;place-items:center;cursor:pointer;-webkit-user-select:none;user-select:none}.calendar .days li:before{content:\"\";position:absolute;inset:4px 0;background:transparent;z-index:0}.calendar .days li .day-number{position:relative;z-index:2;width:32px;height:32px;display:grid;place-items:center;border-radius:50%;transition:transform .12s ease,background .12s ease}.calendar .days li:not(.de-active):hover .day-number{background:var(--ngx-range-hover)}.calendar .days li.de-active{color:var(--ngx-range-muted);opacity:.45;cursor:default}.calendar .days li.in-range:before,.calendar .days li.in-range-preview:before{background:var(--ngx-range-accent-soft)}.calendar .days li.range-start:before{border-radius:20px 0 0 20px}.calendar .days li.range-end:before{border-radius:0 20px 20px 0}.calendar .days li.range-start.range-end:before{border-radius:20px}.calendar .days li.range-start .day-number,.calendar .days li.range-end .day-number{background:var(--ngx-range-accent);color:#fff;font-weight:700;box-shadow:0 3px 10px #6544e847}.calendar .days li.range-single .day-number{box-shadow:none}.calendar .days li.today:not(.range-start):not(.range-end) .day-number{outline:1.5px solid var(--ngx-range-accent);outline-offset:-1px}.calendar .days li.in-range:not(.range-start):not(.range-end) .day-number{color:var(--ngx-range-text)}.calendar .months li,.calendar .years li{height:46px;width:33.333%;display:grid;place-items:center;border-radius:10px;cursor:pointer}.calendar .months li:hover,.calendar .years li:hover{background:var(--ngx-range-hover)}.calendar .months li.selected,.calendar .years li.selected{background:var(--ngx-range-accent);color:#fff}.calendar .months li.de-active,.calendar .years li.de-active{opacity:.4}.calendar .years li{width:25%}.calendar .calendar-footer{display:flex;justify-content:space-between;gap:8px;margin-top:10px;padding-top:10px;border-top:1px solid var(--ngx-range-border)}.calendar .calendar-footer button{min-height:34px;padding:0 13px;border:0;border-radius:8px;background:transparent;color:inherit;cursor:pointer;font-weight:600}.calendar .calendar-footer button:hover{background:var(--ngx-range-hover)}:host-context([dir=rtl]) .days li.range-start:before{border-radius:0 20px 20px 0}:host-context([dir=rtl]) .days li.range-end:before{border-radius:20px 0 0 20px}:host-context([dir=rtl]) .days li.range-start.range-end:before{border-radius:20px}:host-context([dir=rtl]) #prev,:host-context([dir=rtl]) #next{transform:rotate(180deg)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
|
|
3195
|
+
}
|
|
3196
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NgxDateRangePickerComponent, decorators: [{
|
|
3197
|
+
type: Component,
|
|
3198
|
+
args: [{ selector: 'ngx-date-range-picker', standalone: true, imports: [CommonModule], providers: [
|
|
3199
|
+
DateAdapterRegistry,
|
|
3200
|
+
{
|
|
3201
|
+
provide: NG_VALUE_ACCESSOR,
|
|
3202
|
+
useExisting: forwardRef(() => NgxDateRangePickerComponent),
|
|
3203
|
+
multi: true,
|
|
3204
|
+
},
|
|
3205
|
+
{
|
|
3206
|
+
provide: NG_VALIDATORS,
|
|
3207
|
+
useExisting: forwardRef(() => NgxDateRangePickerComponent),
|
|
3208
|
+
multi: true,
|
|
3209
|
+
},
|
|
3210
|
+
], template: "<div class=\"wrapper\" (click)=\"stopPagination($event)\">\n <div class=\"header\">\n <div class=\"calendar-icon\" aria-hidden=\"true\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path d=\"M16 2V6M8 2V6\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" />\n <path\n d=\"M13 4H11C7.22876 4 5.34315 4 4.17157 5.17157C3 6.34315 3 8.22876 3 12V14C3 17.7712 3 19.6569 4.17157 20.8284C5 22 7.22876 22 11 22H13C16.7712 22 18.6569 22 19.8284 20.8284C21 17.7712 21 14V12C21 8.22876 19.8284 5.17157 19.8284 5.17157C4 4 13 4 13 4Z\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\" />\n <path d=\"M3 10H21\" stroke=\"currentColor\" stroke-width=\"1.5\" />\n </svg>\n </div>\n <div class=\"header-copy\">\n <div class=\"header-title\">Date range</div>\n <div class=\"header-value\">{{ calendarHeader }}</div>\n </div>\n </div>\n\n <div class=\"sub-header\">\n <button type=\"button\" class=\"nav-button\" id=\"prev\" (click)=\"previous()\" aria-label=\"Previous\">\n <ng-template\n [ngTemplateOutlet]=\"\n config.previousButtonTemplate || defaultPreviousBTNTemplate\n \"></ng-template>\n </button>\n\n <button type=\"button\" class=\"current-date\" (click)=\"changeView('month')\">\n <span>{{ displayMonth }}</span>\n <span>{{ currYear }}</span>\n </button>\n\n <button type=\"button\" class=\"nav-button\" id=\"next\" (click)=\"next()\" aria-label=\"Next\">\n <ng-template\n [ngTemplateOutlet]=\"config.nextButtonTemplate || defaultNextBTNTemplate\"></ng-template>\n </button>\n </div>\n\n <div class=\"calendar\">\n @if (view === 'day') {\n <ul class=\"weeks\">\n @for (w of weekDays; track $index) {\n <li [title]=\"w.name\">{{ w.min }}</li>\n }\n </ul>\n\n <ul class=\"days\">\n @for (item of viewDays; track $index) {\n <li\n [class.de-active]=\"!item.active\"\n [class.today]=\"item.isToday\"\n [class.in-range]=\"item.inRange\"\n [class.in-range-preview]=\"item.inRangePreview\"\n [class.range-start]=\"item.rangeStart\"\n [class.range-end]=\"item.rangeEnd\"\n [class.range-single]=\"item.rangeStart && item.rangeEnd\"\n (mouseenter)=\"onDayEnter(item)\"\n (mouseleave)=\"onDayLeave()\"\n (click)=\"selectDay($event, item)\"\n [attr.aria-selected]=\"\n item.rangeStart || item.rangeEnd || item.inRange || item.inRangePreview\n \">\n <span class=\"day-number\">{{ item.day }}</span>\n </li>\n }\n </ul>\n } @else if (view === 'month') {\n <ul class=\"months\">\n @for (item of viewMonths; track $index; let i = $index) {\n <li\n [class.de-active]=\"!item.active\"\n [class.today]=\"item.isToday\"\n [class.selected]=\"item.selected\"\n (click)=\"selectMonth($event, item)\">\n {{ i + 1 }}.{{ item.displayMonth }}\n </li>\n }\n </ul>\n } @else {\n <ul class=\"years\">\n @for (item of viewYears; track $index) {\n <li\n [class.de-active]=\"!item.active\"\n [class.today]=\"item.isToday\"\n [class.selected]=\"item.selected\"\n (click)=\"selectYear($event, item)\">\n {{ item.year }}\n </li>\n }\n </ul>\n }\n\n <div class=\"calendar-footer\">\n @if (config.clearButton) {\n <button type=\"button\" (click)=\"clear()\">{{ localize().clear }}</button>\n }\n @if (config.todayButton) {\n <button type=\"button\" (click)=\"gotoToday()\">{{ localize().today }}</button>\n }\n </div>\n </div>\n</div>\n\n<ng-template #defaultPreviousBTNTemplate>\n <svg width=\"14\" height=\"28\" viewBox=\"0 0 320 512\">\n <path\n fill=\"currentColor\"\n d=\"M224 480c-8.188 0-16.38-3.125-22.62-9.375l-192-192c-12.5-12.5-12.5-32.75 0-45.25l192-192c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25L77.25 256l169.4 169.4c12.5 12.5 12.5 32.75 0 45.25C240.4 476.9 232.2 480 224 480z\" />\n </svg>\n</ng-template>\n\n<ng-template #defaultNextBTNTemplate>\n <svg width=\"14\" height=\"28\" viewBox=\"0 0 320 512\">\n <path\n fill=\"currentColor\"\n d=\"M96 480c-8.188 0-16.38-3.125-22.62-9.375L73.38 86.63c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l192 192c12.5 12.5 12.5 32.75 0 45.25l-192 192C112.4 476.9 104.2 480 96 480z\" />\n </svg>\n</ng-template>\n", styles: [":host{--ngx-range-bg: light-dark(#ffffff, #10162b);--ngx-range-text: light-dark(#171717, #f4f4f5);--ngx-range-muted: light-dark(#8a8f98, #72798a);--ngx-range-border: light-dark(#e6e8ee, #272d40);--ngx-range-accent: light-dark(#6544e8, #8d6cff);--ngx-range-accent-soft: light-dark(#eeeaff, #2b2252);--ngx-range-hover: light-dark(#f4f2ff, #211b38)}.wrapper{width:336px;overflow:hidden;border:1px solid var(--ngx-range-border);border-radius:14px;background:var(--ngx-range-bg);color:var(--ngx-range-text);box-shadow:0 18px 55px #0000002e;font-size:13px}.header{display:flex;gap:12px;padding:15px 16px;background:linear-gradient(135deg,#6747e9,#8b64f5);color:#fff}.header .calendar-icon{width:42px;height:42px;display:grid;place-items:center;border-radius:12px;background:#ffffff29}.header .header-copy{min-width:0;flex:1}.header .header-title{opacity:.75;font-size:11px;text-transform:uppercase;letter-spacing:.08em}.header .header-value{margin-top:3px;font-size:14px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sub-header{display:grid;grid-template-columns:40px 1fr 40px;align-items:center;padding:8px 10px;border-bottom:1px solid var(--ngx-range-border)}.sub-header button{color:inherit;border:0;background:transparent;cursor:pointer}.sub-header .nav-button{width:36px;height:36px;display:grid;place-items:center;border-radius:9px}.sub-header .nav-button:hover{background:var(--ngx-range-hover)}.sub-header .current-date{display:flex;justify-content:center;gap:6px;font-weight:700;font-size:14px}.calendar{padding:10px 12px 12px}.calendar ul{display:flex;flex-wrap:wrap;list-style:none;padding:0;margin:0}.calendar .weeks li,.calendar .days li{width:14.2857142857%}.calendar .weeks{margin-bottom:4px}.calendar .weeks li{height:30px;display:grid;place-items:center;color:var(--ngx-range-muted);font-size:11px;font-weight:700}.calendar .days li{position:relative;height:40px;display:grid;place-items:center;cursor:pointer;-webkit-user-select:none;user-select:none}.calendar .days li:before{content:\"\";position:absolute;inset:4px 0;background:transparent;z-index:0}.calendar .days li .day-number{position:relative;z-index:2;width:32px;height:32px;display:grid;place-items:center;border-radius:50%;transition:transform .12s ease,background .12s ease}.calendar .days li:not(.de-active):hover .day-number{background:var(--ngx-range-hover)}.calendar .days li.de-active{color:var(--ngx-range-muted);opacity:.45;cursor:default}.calendar .days li.in-range:before,.calendar .days li.in-range-preview:before{background:var(--ngx-range-accent-soft)}.calendar .days li.range-start:before{border-radius:20px 0 0 20px}.calendar .days li.range-end:before{border-radius:0 20px 20px 0}.calendar .days li.range-start.range-end:before{border-radius:20px}.calendar .days li.range-start .day-number,.calendar .days li.range-end .day-number{background:var(--ngx-range-accent);color:#fff;font-weight:700;box-shadow:0 3px 10px #6544e847}.calendar .days li.range-single .day-number{box-shadow:none}.calendar .days li.today:not(.range-start):not(.range-end) .day-number{outline:1.5px solid var(--ngx-range-accent);outline-offset:-1px}.calendar .days li.in-range:not(.range-start):not(.range-end) .day-number{color:var(--ngx-range-text)}.calendar .months li,.calendar .years li{height:46px;width:33.333%;display:grid;place-items:center;border-radius:10px;cursor:pointer}.calendar .months li:hover,.calendar .years li:hover{background:var(--ngx-range-hover)}.calendar .months li.selected,.calendar .years li.selected{background:var(--ngx-range-accent);color:#fff}.calendar .months li.de-active,.calendar .years li.de-active{opacity:.4}.calendar .years li{width:25%}.calendar .calendar-footer{display:flex;justify-content:space-between;gap:8px;margin-top:10px;padding-top:10px;border-top:1px solid var(--ngx-range-border)}.calendar .calendar-footer button{min-height:34px;padding:0 13px;border:0;border-radius:8px;background:transparent;color:inherit;cursor:pointer;font-weight:600}.calendar .calendar-footer button:hover{background:var(--ngx-range-hover)}:host-context([dir=rtl]) .days li.range-start:before{border-radius:0 20px 20px 0}:host-context([dir=rtl]) .days li.range-end:before{border-radius:20px 0 0 20px}:host-context([dir=rtl]) .days li.range-start.range-end:before{border-radius:20px}:host-context([dir=rtl]) #prev,:host-context([dir=rtl]) #next{transform:rotate(180deg)}\n"] }]
|
|
3211
|
+
}], propDecorators: { localize: [{ type: i0.Input, args: [{ isSignal: true, alias: "localize", required: false }] }], locale: [{
|
|
3212
|
+
type: Input
|
|
3213
|
+
}], min: [{
|
|
3214
|
+
type: Input
|
|
3215
|
+
}], max: [{
|
|
3216
|
+
type: Input
|
|
3217
|
+
}], view: [{
|
|
3218
|
+
type: Input
|
|
3219
|
+
}], rangeChange: [{
|
|
3220
|
+
type: Output
|
|
3221
|
+
}], change: [{
|
|
3222
|
+
type: Output
|
|
3223
|
+
}] } });
|
|
3224
|
+
|
|
3225
|
+
class NgxInputDateRangePicker {
|
|
3226
|
+
el;
|
|
3227
|
+
dateAdapterRegistry = inject(DateAdapterRegistry);
|
|
3228
|
+
overlayService = inject(OverlayService);
|
|
3229
|
+
viewContainerRef = inject(ViewContainerRef);
|
|
3230
|
+
renderer = inject(Renderer2);
|
|
3231
|
+
openOnClick = true;
|
|
3232
|
+
displayFormat = 'yyyy/MM/dd';
|
|
3233
|
+
rangeSeparator = ' – ';
|
|
3234
|
+
_locale = 'en';
|
|
3235
|
+
set locale(value) {
|
|
3236
|
+
this._locale = value || 'en';
|
|
3237
|
+
this.adapter = this.dateAdapterRegistry.resolve(this._locale);
|
|
3238
|
+
this.formatValue();
|
|
3239
|
+
}
|
|
3240
|
+
get locale() {
|
|
3241
|
+
return this._locale;
|
|
3242
|
+
}
|
|
3243
|
+
set setMin(value) {
|
|
3244
|
+
this.min = deserialize(value);
|
|
3245
|
+
this._validatorOnChange();
|
|
3246
|
+
}
|
|
3247
|
+
set setMax(value) {
|
|
3248
|
+
this.max = deserialize(value);
|
|
3249
|
+
this._validatorOnChange();
|
|
3250
|
+
}
|
|
3251
|
+
config = new NgxDatePickerConfig();
|
|
3252
|
+
change = new EventEmitter();
|
|
3253
|
+
min = null;
|
|
3254
|
+
max = null;
|
|
3255
|
+
value = { start: null, end: null };
|
|
3256
|
+
pickerRef;
|
|
3257
|
+
isDisabled = false;
|
|
3258
|
+
adapter;
|
|
3259
|
+
_onChange = (_value) => { };
|
|
3260
|
+
_onTouched = () => { };
|
|
3261
|
+
_validatorOnChange = () => { };
|
|
3262
|
+
constructor(el) {
|
|
3263
|
+
this.el = el;
|
|
3264
|
+
this.adapter = this.dateAdapterRegistry.resolve(this.locale);
|
|
3265
|
+
}
|
|
3266
|
+
ngOnChanges() {
|
|
3267
|
+
this.adapter = this.dateAdapterRegistry.resolve(this.locale);
|
|
3268
|
+
this.formatValue();
|
|
3269
|
+
}
|
|
3270
|
+
onClick(event) {
|
|
3271
|
+
if (!this.openOnClick || this.isDisabled)
|
|
3272
|
+
return;
|
|
3273
|
+
event.preventDefault();
|
|
3274
|
+
event.stopPropagation();
|
|
3275
|
+
this.toggle();
|
|
3276
|
+
}
|
|
3277
|
+
onBlur() {
|
|
3278
|
+
this._onTouched();
|
|
3279
|
+
}
|
|
3280
|
+
writeValue(value) {
|
|
3281
|
+
this.value = normalizeDateRange(value);
|
|
3282
|
+
this.formatValue();
|
|
3283
|
+
}
|
|
3284
|
+
registerOnChange(fn) {
|
|
3285
|
+
this._onChange = fn;
|
|
3286
|
+
}
|
|
3287
|
+
registerOnTouched(fn) {
|
|
3288
|
+
this._onTouched = fn;
|
|
3289
|
+
}
|
|
3290
|
+
registerOnValidatorChange(fn) {
|
|
3291
|
+
this._validatorOnChange = fn;
|
|
3292
|
+
}
|
|
3293
|
+
setDisabledState(disabled) {
|
|
3294
|
+
this.isDisabled = disabled;
|
|
3295
|
+
this.renderer.setProperty(this.el.nativeElement, 'disabled', disabled);
|
|
3296
|
+
}
|
|
3297
|
+
toggle() {
|
|
3298
|
+
if (this.isDisabled)
|
|
3299
|
+
return;
|
|
3300
|
+
if (this.pickerRef) {
|
|
3301
|
+
this.destroyDatePicker();
|
|
3302
|
+
return;
|
|
3303
|
+
}
|
|
3304
|
+
this.adapter = this.dateAdapterRegistry.resolve(this.locale);
|
|
3305
|
+
this.pickerRef = this.overlayService.open({
|
|
3306
|
+
anchor: this.el.nativeElement,
|
|
3307
|
+
component: NgxDateRangePickerComponent,
|
|
3308
|
+
viewContainerRef: this.viewContainerRef,
|
|
3309
|
+
alignment: 'center',
|
|
3310
|
+
placement: 'bottom',
|
|
3311
|
+
margin: 4,
|
|
3312
|
+
configure: (instance) => {
|
|
3313
|
+
instance.locale = this.locale;
|
|
3314
|
+
instance.min = this.min;
|
|
3315
|
+
instance.max = this.max;
|
|
3316
|
+
instance.updateConfig(this.config);
|
|
3317
|
+
instance.writeValue(this.value);
|
|
3318
|
+
instance.rangeChange.subscribe((value) => {
|
|
3319
|
+
this.value = normalizeDateRange(value);
|
|
3320
|
+
this.formatValue();
|
|
3321
|
+
this._onChange(this.value);
|
|
3322
|
+
this.change.emit(this.value);
|
|
3323
|
+
if (this.value.start && this.value.end) {
|
|
3324
|
+
this._onTouched();
|
|
3325
|
+
this.destroyDatePicker();
|
|
3326
|
+
}
|
|
3327
|
+
});
|
|
3328
|
+
},
|
|
3329
|
+
onClosed: () => {
|
|
3330
|
+
this.pickerRef = undefined;
|
|
3331
|
+
},
|
|
3332
|
+
});
|
|
3333
|
+
}
|
|
3334
|
+
validate(_control) {
|
|
3335
|
+
const { start, end } = this.value;
|
|
3336
|
+
if (start && this.min && compareDate(start, this.min) < 0) {
|
|
3337
|
+
return { min: this.min };
|
|
3338
|
+
}
|
|
3339
|
+
if (end && this.max && compareDate(end, this.max) > 0) {
|
|
3340
|
+
return { max: this.max };
|
|
3341
|
+
}
|
|
3342
|
+
if (start && end && compareDate(start, end) > 0) {
|
|
3343
|
+
return { range: true };
|
|
3344
|
+
}
|
|
3345
|
+
return null;
|
|
3346
|
+
}
|
|
3347
|
+
formatValue() {
|
|
3348
|
+
const start = this.value.start;
|
|
3349
|
+
const end = this.value.end;
|
|
3350
|
+
const format = (value) => {
|
|
3351
|
+
if (!value)
|
|
3352
|
+
return '';
|
|
3353
|
+
const locale = this.adapter.toLocale(value);
|
|
3354
|
+
return this.adapter.formatDate(locale, this.displayFormat) ?? '';
|
|
3355
|
+
};
|
|
3356
|
+
const startText = format(start);
|
|
3357
|
+
const endText = format(end);
|
|
3358
|
+
const value = startText && endText
|
|
3359
|
+
? `${startText}${this.rangeSeparator}${endText}`
|
|
3360
|
+
: startText;
|
|
3361
|
+
this.renderer.setProperty(this.el.nativeElement, 'value', value);
|
|
3362
|
+
}
|
|
3363
|
+
destroyDatePicker() {
|
|
3364
|
+
this.pickerRef?.close();
|
|
3365
|
+
this.pickerRef = undefined;
|
|
3366
|
+
}
|
|
3367
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NgxInputDateRangePicker, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
3368
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.4", type: NgxInputDateRangePicker, isStandalone: true, selector: "input[ngxInputDateRangePicker]", inputs: { openOnClick: "openOnClick", displayFormat: "displayFormat", rangeSeparator: "rangeSeparator", locale: "locale", setMin: ["min", "setMin"], setMax: ["max", "setMax"], config: "config" }, outputs: { change: "change" }, host: { listeners: { "click": "onClick($event)", "blur": "onBlur()" }, properties: { "attr.readOnly": "true" }, classAttribute: "ngx-datepicker-input" }, providers: [
|
|
3369
|
+
DateAdapterRegistry,
|
|
3370
|
+
{
|
|
3371
|
+
provide: NG_VALUE_ACCESSOR,
|
|
3372
|
+
useExisting: forwardRef(() => NgxInputDateRangePicker),
|
|
3373
|
+
multi: true,
|
|
3374
|
+
},
|
|
3375
|
+
{
|
|
3376
|
+
provide: NG_VALIDATORS,
|
|
3377
|
+
useExisting: forwardRef(() => NgxInputDateRangePicker),
|
|
3378
|
+
multi: true,
|
|
3379
|
+
},
|
|
3380
|
+
], exportAs: ["ngxInputDateRangePicker"], usesOnChanges: true, ngImport: i0 });
|
|
3381
|
+
}
|
|
3382
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: NgxInputDateRangePicker, decorators: [{
|
|
3383
|
+
type: Directive,
|
|
3384
|
+
args: [{
|
|
3385
|
+
selector: 'input[ngxInputDateRangePicker]',
|
|
3386
|
+
exportAs: 'ngxInputDateRangePicker',
|
|
3387
|
+
host: {
|
|
3388
|
+
class: 'ngx-datepicker-input',
|
|
3389
|
+
'[attr.readOnly]': 'true',
|
|
3390
|
+
},
|
|
3391
|
+
providers: [
|
|
3392
|
+
DateAdapterRegistry,
|
|
3393
|
+
{
|
|
3394
|
+
provide: NG_VALUE_ACCESSOR,
|
|
3395
|
+
useExisting: forwardRef(() => NgxInputDateRangePicker),
|
|
3396
|
+
multi: true,
|
|
3397
|
+
},
|
|
3398
|
+
{
|
|
3399
|
+
provide: NG_VALIDATORS,
|
|
3400
|
+
useExisting: forwardRef(() => NgxInputDateRangePicker),
|
|
3401
|
+
multi: true,
|
|
3402
|
+
},
|
|
3403
|
+
],
|
|
3404
|
+
}]
|
|
3405
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { openOnClick: [{
|
|
3406
|
+
type: Input
|
|
3407
|
+
}], displayFormat: [{
|
|
3408
|
+
type: Input
|
|
3409
|
+
}], rangeSeparator: [{
|
|
3410
|
+
type: Input
|
|
3411
|
+
}], locale: [{
|
|
3412
|
+
type: Input
|
|
3413
|
+
}], setMin: [{
|
|
3414
|
+
type: Input,
|
|
3415
|
+
args: ['min']
|
|
3416
|
+
}], setMax: [{
|
|
3417
|
+
type: Input,
|
|
3418
|
+
args: ['max']
|
|
3419
|
+
}], config: [{
|
|
3420
|
+
type: Input
|
|
3421
|
+
}], change: [{
|
|
3422
|
+
type: Output
|
|
3423
|
+
}], onClick: [{
|
|
3424
|
+
type: HostListener,
|
|
3425
|
+
args: ['click', ['$event']]
|
|
3426
|
+
}], onBlur: [{
|
|
3427
|
+
type: HostListener,
|
|
3428
|
+
args: ['blur']
|
|
3429
|
+
}] } });
|
|
3430
|
+
|
|
2309
3431
|
/**
|
|
2310
3432
|
* Generated bundle index. Do not edit.
|
|
2311
3433
|
*/
|
|
2312
3434
|
|
|
2313
|
-
export { DATE_ADAPTERS, DEFAULT_DATE_ADAPTERS, NgxCalendarComponent, NgxDatePickerConfig, NgxInputDatePicker, NgxInputDatePickerComponent, getLocals, provideDateAdapters };
|
|
3435
|
+
export { DATE_ADAPTERS, DEFAULT_DATE_ADAPTERS, DateModel, DateViewDay, DateViewMonth, DateViewWeek, DateViewYear, NgxCalendarComponent, NgxDatePickerConfig, NgxDateRangePickerComponent, NgxInputDatePicker, NgxInputDatePickerComponent, NgxInputDateRangePicker, createDateRange, getLocals, isCompleteDateRange, isDateInPreviewRange, isDateInRange, normalizeDateRange, provideDateAdapters };
|
|
2314
3436
|
//# sourceMappingURL=ngx-kit-date-picker.mjs.map
|