@dcsl/flex-ui 0.0.30 → 0.0.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/dcsl-flex-ui.mjs +219 -124
- package/fesm2022/dcsl-flex-ui.mjs.map +1 -1
- package/index.d.ts +41 -5
- package/package.json +1 -2
|
@@ -5,12 +5,9 @@ import { CommonModule } from '@angular/common';
|
|
|
5
5
|
import * as i2 from '@angular/forms';
|
|
6
6
|
import { FormsModule } from '@angular/forms';
|
|
7
7
|
import dayjs from 'dayjs';
|
|
8
|
-
import calendarSystems from '@calidy/dayjs-calendarsystems';
|
|
9
|
-
import PersianCalendarSystem from '@calidy/dayjs-calendarsystems/calendarSystems/PersianCalendarSystem';
|
|
10
|
-
import HijriCalendarSystem from '@calidy/dayjs-calendarsystems/calendarSystems/HijriCalendarSystem';
|
|
11
8
|
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
|
12
9
|
import utc from 'dayjs/plugin/utc';
|
|
13
|
-
import { hijriToGregorian } from '@tabby_ai/hijri-converter';
|
|
10
|
+
import { hijriToGregorian, gregorianToHijri } from '@tabby_ai/hijri-converter';
|
|
14
11
|
import { autoUpdate, computePosition, offset, flip, shift } from '@floating-ui/dom';
|
|
15
12
|
|
|
16
13
|
class FlexPanelComponent {
|
|
@@ -670,68 +667,64 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.1", ngImpor
|
|
|
670
667
|
}] } });
|
|
671
668
|
|
|
672
669
|
dayjs.extend(utc);
|
|
673
|
-
// Extend Day.js with calendar systems support
|
|
674
|
-
dayjs.extend(calendarSystems);
|
|
675
670
|
dayjs.extend(customParseFormat);
|
|
676
|
-
// Register the Persian calendar
|
|
677
|
-
dayjs.registerCalendarSystem('persian', new PersianCalendarSystem());
|
|
678
|
-
dayjs.registerCalendarSystem('islamic', new HijriCalendarSystem());
|
|
679
671
|
class DateServiceService {
|
|
680
672
|
constructor() {
|
|
681
673
|
}
|
|
674
|
+
//month will start from 1
|
|
675
|
+
convertToGregorian(date) {
|
|
676
|
+
var grego = hijriToGregorian({
|
|
677
|
+
day: date.day,
|
|
678
|
+
month: date.month,
|
|
679
|
+
year: date.year
|
|
680
|
+
});
|
|
681
|
+
return {
|
|
682
|
+
day: grego.day,
|
|
683
|
+
month: grego.month,
|
|
684
|
+
year: grego.year
|
|
685
|
+
};
|
|
686
|
+
}
|
|
687
|
+
//month will start from 1
|
|
688
|
+
convertToHijri(date) {
|
|
689
|
+
var hijri = gregorianToHijri({
|
|
690
|
+
day: date.day,
|
|
691
|
+
month: date.month,
|
|
692
|
+
year: date.year
|
|
693
|
+
});
|
|
694
|
+
return {
|
|
695
|
+
day: hijri.day,
|
|
696
|
+
month: hijri.month,
|
|
697
|
+
year: hijri.year
|
|
698
|
+
};
|
|
699
|
+
}
|
|
682
700
|
parse(dateString, calendar, format) {
|
|
683
701
|
//Step 1: User will input gregorian or islamic(hijri) date. for this we will use customParseFormat
|
|
684
702
|
//in the control we will specify the format using binding.
|
|
685
703
|
var parsedUtcDate = dayjs.utc(dateString, format, true);
|
|
686
|
-
console.log("Parsed string provided by User as Utc Iso: ", parsedUtcDate.toISOString());
|
|
687
704
|
if (!parsedUtcDate.isValid()) {
|
|
688
|
-
console.log("entered date string is invalid: ", dateString);
|
|
689
705
|
return null;
|
|
690
706
|
}
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
//here we are assuming the control want to handle islamic calender date, we will take it dynmically.
|
|
697
|
-
console.log("Prased Date in Gregorian String as per format ['DD-MM-YYYY']:", customDate.format('DD-MM-YYYY'));
|
|
698
|
-
// console.log("Prased Date in Gregorian String as per format ['DD-MM-YYYY']:", customDate.toISOString());
|
|
699
|
-
//here it will show gregorian calender, because even if we parse using islamic calender, it will convert the date
|
|
700
|
-
//and keep it to gregorian
|
|
701
|
-
//to show islamic date, we have to tell the dayjs to use islamic calender
|
|
702
|
-
var customDateString = customDate.format('YYYY-MM-DD');
|
|
703
|
-
const d2 = dayjs.utc(customDateString);
|
|
704
|
-
// console.log("utc", d2.toISOString());
|
|
705
|
-
return d2.toDate();
|
|
706
|
-
}
|
|
707
|
-
parse2(dateString, calendar, format) {
|
|
708
|
-
const d = dayjs.utc(dateString, format, true);
|
|
709
|
-
if (!d.isValid())
|
|
710
|
-
return null;
|
|
711
|
-
let gYear = d.year();
|
|
712
|
-
let gMonth = d.month();
|
|
713
|
-
let gDay = d.date();
|
|
714
|
-
if (calendar === "islamic") {
|
|
715
|
-
const hijri = { hijriYear: d.year(), hijriMonth: d.month(), hijriDay: d.date() };
|
|
716
|
-
const greg = hijriToGregorian({
|
|
717
|
-
year: hijri.hijriYear,
|
|
718
|
-
month: hijri.hijriMonth,
|
|
719
|
-
day: hijri.hijriDay
|
|
707
|
+
if (calendar == "islamic") {
|
|
708
|
+
var grego = hijriToGregorian({
|
|
709
|
+
day: parsedUtcDate.date(),
|
|
710
|
+
month: parsedUtcDate.month() + 1,
|
|
711
|
+
year: parsedUtcDate.year()
|
|
720
712
|
});
|
|
721
|
-
|
|
722
|
-
gMonth = greg.month;
|
|
723
|
-
gDay = greg.day;
|
|
713
|
+
parsedUtcDate = dayjs.utc(`${grego.year}-${grego.month}-${grego.day}`);
|
|
724
714
|
}
|
|
725
|
-
|
|
726
|
-
const fixed = dayjs.utc(new Date(gYear, gMonth, gDay));
|
|
727
|
-
return fixed.toDate();
|
|
715
|
+
return parsedUtcDate.toDate();
|
|
728
716
|
}
|
|
729
717
|
format(date, calendar, format) {
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
718
|
+
var day = dayjs.utc(`${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`);
|
|
719
|
+
if (calendar == "islamic") {
|
|
720
|
+
var hijri = gregorianToHijri({
|
|
721
|
+
day: date.getDate(),
|
|
722
|
+
month: date.getMonth() + 1,
|
|
723
|
+
year: date.getFullYear()
|
|
724
|
+
});
|
|
725
|
+
day = dayjs.utc(`${hijri.year}-${hijri.month}-${hijri.day}`);
|
|
726
|
+
}
|
|
727
|
+
return day.format(format);
|
|
735
728
|
}
|
|
736
729
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: DateServiceService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
737
730
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: DateServiceService, providedIn: 'root' });
|
|
@@ -914,6 +907,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.1", ngImpor
|
|
|
914
907
|
args: ['window:resize']
|
|
915
908
|
}] } });
|
|
916
909
|
|
|
910
|
+
const MinGregorianDate = new Date(1937, 0, 1).getTime();
|
|
911
|
+
const MaxGregorianDate = new Date(2076, 11, 31).getTime();
|
|
917
912
|
// ✅ Intl formatters
|
|
918
913
|
const hijriFmt = new Intl.DateTimeFormat('en-u-ca-islamic-umalqura-nu-latn', {
|
|
919
914
|
day: 'numeric',
|
|
@@ -941,12 +936,17 @@ const gregMonthNamesAr = [
|
|
|
941
936
|
const weekDaysEn = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
|
|
942
937
|
const weekDaysAr = ['ح', 'ن', 'ث', 'ر', 'خ', 'ج', 'س'];
|
|
943
938
|
function hijriFromGregorian(g) {
|
|
944
|
-
const parts = hijriFmt.formatToParts(g);
|
|
945
|
-
const map = {};
|
|
946
|
-
for (const p of parts)
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
939
|
+
// const parts = hijriFmt.formatToParts(g);
|
|
940
|
+
// const map: Record<string, string> = {};
|
|
941
|
+
// for (const p of parts) map[p.type] = p.value;
|
|
942
|
+
// const n = (k: string) => parseInt(map[k] ?? '0', 10);
|
|
943
|
+
// return { hy: n('year'), hm: n('month'), hd: n('day') };
|
|
944
|
+
var hijri = gregorianToHijri({
|
|
945
|
+
day: g.getDate(),
|
|
946
|
+
month: g.getMonth() + 1,
|
|
947
|
+
year: g.getFullYear()
|
|
948
|
+
});
|
|
949
|
+
return { hy: hijri.year, hm: hijri.month, hd: hijri.day };
|
|
950
950
|
}
|
|
951
951
|
function compareHijri(a, b) {
|
|
952
952
|
if (a.hy !== b.hy)
|
|
@@ -956,43 +956,60 @@ function compareHijri(a, b) {
|
|
|
956
956
|
return a.hd - b.hd;
|
|
957
957
|
}
|
|
958
958
|
function findGregorianForHijri(target) {
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
959
|
+
console.log(target);
|
|
960
|
+
console.log("findGregorianForHijri => ", target.hm, "M");
|
|
961
|
+
console.log(typeof target.hm);
|
|
962
|
+
console.log(typeof target.hy);
|
|
963
|
+
var month = parseInt(target.hm.toString());
|
|
964
|
+
//var year = parseInt(target.hy.toString());
|
|
965
|
+
// console.log(month);
|
|
966
|
+
var grego = hijriToGregorian({
|
|
967
|
+
day: 1,
|
|
968
|
+
month: month,
|
|
969
|
+
year: target.hy
|
|
970
|
+
});
|
|
971
|
+
console.log("findGregorianForHijri Greg => ", grego.month, "M");
|
|
972
|
+
return new Date(grego.year, grego.month - 1, grego.day);
|
|
973
|
+
// let lo = new Date(1937, 0, 1).getTime();
|
|
974
|
+
// let hi = new Date(2076, 11, 31).getTime();
|
|
975
|
+
// const dayMs = 86400000;
|
|
976
|
+
// while (lo <= hi) {
|
|
977
|
+
// const mid = Math.floor((lo + hi) / 2);
|
|
978
|
+
// const h = hijriFromGregorian(new Date(mid));
|
|
979
|
+
// compareHijri(h, target) < 0 ? (lo = mid + dayMs) : (hi = mid - dayMs);
|
|
980
|
+
// }
|
|
981
|
+
// let d = new Date(lo);
|
|
982
|
+
// while (true) {
|
|
983
|
+
// const h = hijriFromGregorian(d);
|
|
984
|
+
// const cmp = compareHijri(h, target);
|
|
985
|
+
// if (cmp === 0) {
|
|
986
|
+
// console.log(d);
|
|
987
|
+
// return d;
|
|
988
|
+
// }
|
|
989
|
+
// if (cmp > 0) throw new Error('Hijri date out of supported range');
|
|
990
|
+
// d = new Date(d.getTime() + dayMs);
|
|
991
|
+
// }
|
|
977
992
|
}
|
|
978
993
|
function stripTime(d) {
|
|
979
|
-
return new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
994
|
+
//return new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
995
|
+
return d;
|
|
980
996
|
}
|
|
997
|
+
|
|
981
998
|
class FlexDualCalendarComponent {
|
|
982
999
|
/** Two-way bound selected date (Gregorian) */
|
|
983
|
-
value;
|
|
984
|
-
valueChange = new EventEmitter();
|
|
1000
|
+
value = model(new Date(), ...(ngDevMode ? [{ debugName: "value" }] : []));
|
|
1001
|
+
// @Output() valueChange = new EventEmitter<Date>();
|
|
985
1002
|
/** Optional min/max (Gregorian) */
|
|
986
1003
|
minDate;
|
|
987
1004
|
maxDate;
|
|
988
1005
|
/** Month/weekday language */
|
|
989
1006
|
monthLang = 'en';
|
|
990
1007
|
/** Start mode, default Hijri */
|
|
991
|
-
startMode = 'gregory';
|
|
1008
|
+
//@Input() startMode: FlexCalendarSystem = 'gregory';
|
|
992
1009
|
// This will be injected by FloatingUiService
|
|
993
1010
|
close;
|
|
994
1011
|
/** Current mode (hijri | gregory) */
|
|
995
|
-
mode =
|
|
1012
|
+
mode = model('gregory', ...(ngDevMode ? [{ debugName: "mode" }] : []));
|
|
996
1013
|
/** Hijri view state */
|
|
997
1014
|
hy = signal(0, ...(ngDevMode ? [{ debugName: "hy" }] : []));
|
|
998
1015
|
hm = signal(0, ...(ngDevMode ? [{ debugName: "hm" }] : []));
|
|
@@ -1018,6 +1035,7 @@ class FlexDualCalendarComponent {
|
|
|
1018
1035
|
? this.hijriMonths[this.selectedMonth - 1]
|
|
1019
1036
|
: this.gregMonths[this.selectedMonth - 1];
|
|
1020
1037
|
}
|
|
1038
|
+
ignoreDropdownSync = false;
|
|
1021
1039
|
constructor() {
|
|
1022
1040
|
const today = new Date();
|
|
1023
1041
|
const h = hijriFromGregorian(today);
|
|
@@ -1026,7 +1044,7 @@ class FlexDualCalendarComponent {
|
|
|
1026
1044
|
this.gy.set(today.getFullYear());
|
|
1027
1045
|
this.gm.set(today.getMonth() + 1);
|
|
1028
1046
|
// initialize selectors with start mode
|
|
1029
|
-
this.mode.set(this.startMode);
|
|
1047
|
+
//this.mode.set(this.startMode);
|
|
1030
1048
|
if (this.mode() === 'islamic') {
|
|
1031
1049
|
this.selectedYear = this.hy();
|
|
1032
1050
|
this.selectedMonth = this.hm();
|
|
@@ -1035,14 +1053,13 @@ class FlexDualCalendarComponent {
|
|
|
1035
1053
|
this.selectedYear = this.gy();
|
|
1036
1054
|
this.selectedMonth = this.gm();
|
|
1037
1055
|
}
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
const g = stripTime(this.value);
|
|
1056
|
+
effect((() => {
|
|
1057
|
+
if (this.ignoreDropdownSync)
|
|
1058
|
+
return;
|
|
1059
|
+
const v = this.value();
|
|
1060
|
+
if (!v)
|
|
1061
|
+
return;
|
|
1062
|
+
const g = stripTime(this.value());
|
|
1046
1063
|
const h = hijriFromGregorian(g);
|
|
1047
1064
|
this.gy.set(g.getFullYear());
|
|
1048
1065
|
this.gm.set(g.getMonth() + 1);
|
|
@@ -1057,7 +1074,29 @@ class FlexDualCalendarComponent {
|
|
|
1057
1074
|
this.selectedYear = this.gy();
|
|
1058
1075
|
this.selectedMonth = this.gm();
|
|
1059
1076
|
}
|
|
1060
|
-
}
|
|
1077
|
+
}));
|
|
1078
|
+
}
|
|
1079
|
+
ngOnInit() {
|
|
1080
|
+
this.buildYearRange();
|
|
1081
|
+
}
|
|
1082
|
+
ngOnChanges(changes) {
|
|
1083
|
+
// If value changed from outside, update both calendars
|
|
1084
|
+
// if (changes['value'] && this.value() instanceof Date) {
|
|
1085
|
+
// const g = stripTime(this.value());
|
|
1086
|
+
// const h = hijriFromGregorian(g);
|
|
1087
|
+
// this.gy.set(g.getFullYear());
|
|
1088
|
+
// this.gm.set(g.getMonth() + 1);
|
|
1089
|
+
// this.hy.set(h.hy);
|
|
1090
|
+
// this.hm.set(h.hm);
|
|
1091
|
+
// // Update dropdowns based on current mode
|
|
1092
|
+
// if (this.mode() === 'islamic') {
|
|
1093
|
+
// this.selectedYear = this.hy();
|
|
1094
|
+
// this.selectedMonth = this.hm();
|
|
1095
|
+
// } else {
|
|
1096
|
+
// this.selectedYear = this.gy();
|
|
1097
|
+
// this.selectedMonth = this.gm();
|
|
1098
|
+
// }
|
|
1099
|
+
// }
|
|
1061
1100
|
// Rebuild year range if min/max changed
|
|
1062
1101
|
if (changes['minDate'] || changes['maxDate'] || changes['value']) {
|
|
1063
1102
|
this.buildYearRange();
|
|
@@ -1082,7 +1121,7 @@ class FlexDualCalendarComponent {
|
|
|
1082
1121
|
}
|
|
1083
1122
|
// 🔁 Mode switch (SYNCED view — keep same instant)
|
|
1084
1123
|
switchMode(value) {
|
|
1085
|
-
const pivot = this.value
|
|
1124
|
+
const pivot = this.value(); // use selected date or current view start
|
|
1086
1125
|
if (value === 'gregory') {
|
|
1087
1126
|
// To Gregorian mode
|
|
1088
1127
|
const g = stripTime(pivot);
|
|
@@ -1105,6 +1144,7 @@ class FlexDualCalendarComponent {
|
|
|
1105
1144
|
}
|
|
1106
1145
|
// called when dropdowns change
|
|
1107
1146
|
onMonthYearChange() {
|
|
1147
|
+
this.ignoreDropdownSync = true;
|
|
1108
1148
|
if (this.mode() === 'islamic') {
|
|
1109
1149
|
this.hy.set(this.selectedYear);
|
|
1110
1150
|
this.hm.set(this.selectedMonth);
|
|
@@ -1113,10 +1153,12 @@ class FlexDualCalendarComponent {
|
|
|
1113
1153
|
this.gy.set(this.selectedYear);
|
|
1114
1154
|
this.gm.set(this.selectedMonth);
|
|
1115
1155
|
}
|
|
1156
|
+
setTimeout(() => (this.ignoreDropdownSync = false));
|
|
1116
1157
|
}
|
|
1117
1158
|
// Start of visible month (Gregorian date)
|
|
1118
1159
|
firstOfMonth() {
|
|
1119
1160
|
if (this.mode() === 'islamic') {
|
|
1161
|
+
//console.log("firstOfMonth function: ", this.hm());
|
|
1120
1162
|
return findGregorianForHijri({ hy: this.hy(), hm: this.hm(), hd: 1 });
|
|
1121
1163
|
}
|
|
1122
1164
|
return new Date(this.gy(), this.gm() - 1, 1);
|
|
@@ -1133,6 +1175,7 @@ class FlexDualCalendarComponent {
|
|
|
1133
1175
|
const g = new Date(start);
|
|
1134
1176
|
g.setDate(start.getDate() + i);
|
|
1135
1177
|
const h = hijriFromGregorian(g);
|
|
1178
|
+
//console.log("month:", h.hm);
|
|
1136
1179
|
let disabled = false;
|
|
1137
1180
|
if (this.minDate && g < stripTime(this.minDate))
|
|
1138
1181
|
disabled = true;
|
|
@@ -1148,6 +1191,7 @@ class FlexDualCalendarComponent {
|
|
|
1148
1191
|
prevMonth() {
|
|
1149
1192
|
if (!this.canPrev())
|
|
1150
1193
|
return;
|
|
1194
|
+
this.ignoreDropdownSync = true;
|
|
1151
1195
|
if (this.mode() === 'islamic') {
|
|
1152
1196
|
let m = this.hm(), y = this.hy();
|
|
1153
1197
|
if (--m < 1) {
|
|
@@ -1170,10 +1214,12 @@ class FlexDualCalendarComponent {
|
|
|
1170
1214
|
this.selectedYear = y;
|
|
1171
1215
|
this.selectedMonth = m;
|
|
1172
1216
|
}
|
|
1217
|
+
setTimeout(() => (this.ignoreDropdownSync = false));
|
|
1173
1218
|
}
|
|
1174
1219
|
nextMonth() {
|
|
1175
1220
|
if (!this.canNext())
|
|
1176
1221
|
return;
|
|
1222
|
+
this.ignoreDropdownSync = true;
|
|
1177
1223
|
if (this.mode() === 'islamic') {
|
|
1178
1224
|
let m = this.hm(), y = this.hy();
|
|
1179
1225
|
if (++m > 12) {
|
|
@@ -1196,6 +1242,7 @@ class FlexDualCalendarComponent {
|
|
|
1196
1242
|
this.selectedYear = y;
|
|
1197
1243
|
this.selectedMonth = m;
|
|
1198
1244
|
}
|
|
1245
|
+
setTimeout(() => (this.ignoreDropdownSync = false));
|
|
1199
1246
|
}
|
|
1200
1247
|
canPrev() {
|
|
1201
1248
|
if (!this.minDate)
|
|
@@ -1223,22 +1270,27 @@ class FlexDualCalendarComponent {
|
|
|
1223
1270
|
&& g.getDate() === t.getDate();
|
|
1224
1271
|
}
|
|
1225
1272
|
isSelected(g) {
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1273
|
+
const v = this.value();
|
|
1274
|
+
if (!v)
|
|
1275
|
+
return false;
|
|
1276
|
+
return !!this.value() &&
|
|
1277
|
+
g.getFullYear() === v.getFullYear() &&
|
|
1278
|
+
g.getMonth() === v.getMonth() &&
|
|
1279
|
+
g.getDate() === v.getDate();
|
|
1230
1280
|
}
|
|
1231
1281
|
select(c) {
|
|
1232
1282
|
if (c.disabled)
|
|
1233
1283
|
return;
|
|
1234
|
-
|
|
1235
|
-
|
|
1284
|
+
var g = c.g;
|
|
1285
|
+
var st = stripTime(c.g);
|
|
1286
|
+
this.value.set(st);
|
|
1287
|
+
//this.valueChange.emit(this.value);
|
|
1236
1288
|
// keep both views in sync after selection
|
|
1237
|
-
const h = hijriFromGregorian(this.value);
|
|
1289
|
+
const h = hijriFromGregorian(this.value());
|
|
1238
1290
|
this.hy.set(h.hy);
|
|
1239
1291
|
this.hm.set(h.hm);
|
|
1240
|
-
this.gy.set(this.value.getFullYear());
|
|
1241
|
-
this.gm.set(this.value.getMonth() + 1);
|
|
1292
|
+
this.gy.set(this.value().getFullYear());
|
|
1293
|
+
this.gm.set(this.value().getMonth() + 1);
|
|
1242
1294
|
if (this.mode() === 'islamic') {
|
|
1243
1295
|
this.selectedYear = this.hy();
|
|
1244
1296
|
this.selectedMonth = this.hm();
|
|
@@ -1247,26 +1299,20 @@ class FlexDualCalendarComponent {
|
|
|
1247
1299
|
this.selectedYear = this.gy();
|
|
1248
1300
|
this.selectedMonth = this.gm();
|
|
1249
1301
|
}
|
|
1250
|
-
this.close(this.value);
|
|
1302
|
+
this.close(this.value());
|
|
1251
1303
|
}
|
|
1252
1304
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: FlexDualCalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1253
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.1", type: FlexDualCalendarComponent, isStandalone: true, selector: "flex-dual-calendar", inputs: { value: "value", minDate: "minDate", maxDate: "maxDate", monthLang: "monthLang",
|
|
1305
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.1", type: FlexDualCalendarComponent, isStandalone: true, selector: "flex-dual-calendar", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: false, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: false, isRequired: false, transformFunction: null }, monthLang: { classPropertyName: "monthLang", publicName: "monthLang", isSignal: false, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", mode: "modeChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"card\">\r\n <div class=\"card-header p-1\">\r\n <div class=\"d-flex gap-1\">\r\n\r\n <div>\r\n <button class=\"btn btn-sm w-100 \" (click)=\"prevMonth()\" [disabled]=\"!canPrev()\"><i\r\n class=\"bi bi-caret-left-fill\"></i></button>\r\n </div>\r\n <div class=\"flex-grow-1\">\r\n <select class=\"form-select form-select-sm\" [(ngModel)]=\"selectedMonth\"\r\n (ngModelChange)=\"onMonthYearChange()\">\r\n @if (mode() === 'islamic') {\r\n @for (m of hijriMonths; track $index) {\r\n <option [value]=\"$index + 1\">{{ hijriMonths[$index] }}-{{$index + 1}}</option>\r\n }\r\n } @else {\r\n @for (m of gregMonths; track $index) {\r\n <option [value]=\"$index + 1\">{{$index + 1}}-{{ gregMonths[$index] }}</option>\r\n }\r\n }\r\n </select>\r\n </div>\r\n <div> <select class=\"form-select form-select-sm\" [(ngModel)]=\"selectedYear\"\r\n (ngModelChange)=\"onMonthYearChange()\">\r\n @for (y of yearRange; track y) {\r\n <option [value]=\"y\">{{ y }}</option>\r\n }\r\n </select></div>\r\n <div>\r\n <button class=\"btn btn-sm w-100 \" (click)=\"nextMonth()\" [disabled]=\"!canNext()\"><i\r\n class=\"bi bi-caret-right-fill\"></i></button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card-body p-0\">\r\n <!-- Weekday labels -->\r\n <div class=\"grid\">\r\n @for (w of weekDays; track $index) {\r\n <div class=\"col fw-bold border pb-1\">{{ w }}</div>\r\n }\r\n </div>\r\n\r\n <!-- Calendar cells -->\r\n <div class=\"grid\">\r\n @for (c of cells(); track $index) {\r\n <div class=\"cell\">\r\n <button class=\"btn w-100 rounded-0\" [class.muted]=\"!c.inCurrentMonth\" [class.fw-bold]=\"isToday(c.g)\"\r\n [class.btn-info]=\"isSelected(c.g)\" [disabled]=\"c.disabled\" (click)=\"select(c)\">\r\n <!-- show Hijri day in Hijri mode, otherwise Gregorian -->\r\n @if(mode() === 'islamic'){\r\n {{ c.h.hd }}\r\n }\r\n @else{\r\n {{ c.g.getDate() }}\r\n }\r\n </button>\r\n </div>\r\n }\r\n\r\n </div>\r\n </div>\r\n <div class=\"card-footer px-0 py-1\">\r\n <div class=\"d-flex justify-content-center\">\r\n <div class=\"btn-group\" role=\"group\" aria-label=\"Basic example\">\r\n <button class=\"btn btn-sm btn-outline-secondary\" [class.btn-info]=\"mode() == 'gregory'\" type=\"button\"\r\n (click)=\"switchMode('gregory')\">\r\n Gregorian\r\n </button>\r\n <button class=\"btn btn-sm btn-outline-secondary\" [class.btn-info]=\"mode() == 'islamic'\" type=\"button\"\r\n (click)=\"switchMode('islamic')\">\r\n \u0647\u062C\u0631\u064A\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [".grid{display:grid;grid-template-columns:repeat(7,1fr)}.cell{border:1px solid #ddd}.cell>.muted{opacity:.5;color:#aaa}.cell>.today{background-color:#647998}.cell>.selected{background-color:#0d6efd;color:#fff}.cell>.btn:disabled{background-color:#f8f9fa;color:#aaa;cursor:not-allowed}.col{text-align:center}.btn{font-size:90%;--bs-btn-padding-x: .5rem;--bs-btn-padding-y: .25rem}.btn:hover{background-color:azure}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
|
|
1254
1306
|
}
|
|
1255
1307
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: FlexDualCalendarComponent, decorators: [{
|
|
1256
1308
|
type: Component,
|
|
1257
|
-
args: [{ selector: 'flex-dual-calendar', standalone: true, imports: [CommonModule, FormsModule], template: "<div class=\"card\">\r\n <div class=\"card-header p-1\">\r\n <div class=\"d-flex gap-1\">\r\n\r\n <div>\r\n <button class=\"btn btn-sm w-100 \" (click)=\"prevMonth()\" [disabled]=\"!canPrev()\"><i\r\n class=\"bi bi-caret-left-fill\"></i></button>\r\n </div>\r\n <div class=\"flex-grow-1\">\r\n <select class=\"form-select form-select-sm\" [(ngModel)]=\"selectedMonth\"
|
|
1258
|
-
}], ctorParameters: () => [], propDecorators: {
|
|
1259
|
-
type: Input
|
|
1260
|
-
}], valueChange: [{
|
|
1261
|
-
type: Output
|
|
1262
|
-
}], minDate: [{
|
|
1309
|
+
args: [{ selector: 'flex-dual-calendar', standalone: true, imports: [CommonModule, FormsModule], template: "<div class=\"card\">\r\n <div class=\"card-header p-1\">\r\n <div class=\"d-flex gap-1\">\r\n\r\n <div>\r\n <button class=\"btn btn-sm w-100 \" (click)=\"prevMonth()\" [disabled]=\"!canPrev()\"><i\r\n class=\"bi bi-caret-left-fill\"></i></button>\r\n </div>\r\n <div class=\"flex-grow-1\">\r\n <select class=\"form-select form-select-sm\" [(ngModel)]=\"selectedMonth\"\r\n (ngModelChange)=\"onMonthYearChange()\">\r\n @if (mode() === 'islamic') {\r\n @for (m of hijriMonths; track $index) {\r\n <option [value]=\"$index + 1\">{{ hijriMonths[$index] }}-{{$index + 1}}</option>\r\n }\r\n } @else {\r\n @for (m of gregMonths; track $index) {\r\n <option [value]=\"$index + 1\">{{$index + 1}}-{{ gregMonths[$index] }}</option>\r\n }\r\n }\r\n </select>\r\n </div>\r\n <div> <select class=\"form-select form-select-sm\" [(ngModel)]=\"selectedYear\"\r\n (ngModelChange)=\"onMonthYearChange()\">\r\n @for (y of yearRange; track y) {\r\n <option [value]=\"y\">{{ y }}</option>\r\n }\r\n </select></div>\r\n <div>\r\n <button class=\"btn btn-sm w-100 \" (click)=\"nextMonth()\" [disabled]=\"!canNext()\"><i\r\n class=\"bi bi-caret-right-fill\"></i></button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"card-body p-0\">\r\n <!-- Weekday labels -->\r\n <div class=\"grid\">\r\n @for (w of weekDays; track $index) {\r\n <div class=\"col fw-bold border pb-1\">{{ w }}</div>\r\n }\r\n </div>\r\n\r\n <!-- Calendar cells -->\r\n <div class=\"grid\">\r\n @for (c of cells(); track $index) {\r\n <div class=\"cell\">\r\n <button class=\"btn w-100 rounded-0\" [class.muted]=\"!c.inCurrentMonth\" [class.fw-bold]=\"isToday(c.g)\"\r\n [class.btn-info]=\"isSelected(c.g)\" [disabled]=\"c.disabled\" (click)=\"select(c)\">\r\n <!-- show Hijri day in Hijri mode, otherwise Gregorian -->\r\n @if(mode() === 'islamic'){\r\n {{ c.h.hd }}\r\n }\r\n @else{\r\n {{ c.g.getDate() }}\r\n }\r\n </button>\r\n </div>\r\n }\r\n\r\n </div>\r\n </div>\r\n <div class=\"card-footer px-0 py-1\">\r\n <div class=\"d-flex justify-content-center\">\r\n <div class=\"btn-group\" role=\"group\" aria-label=\"Basic example\">\r\n <button class=\"btn btn-sm btn-outline-secondary\" [class.btn-info]=\"mode() == 'gregory'\" type=\"button\"\r\n (click)=\"switchMode('gregory')\">\r\n Gregorian\r\n </button>\r\n <button class=\"btn btn-sm btn-outline-secondary\" [class.btn-info]=\"mode() == 'islamic'\" type=\"button\"\r\n (click)=\"switchMode('islamic')\">\r\n \u0647\u062C\u0631\u064A\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [".grid{display:grid;grid-template-columns:repeat(7,1fr)}.cell{border:1px solid #ddd}.cell>.muted{opacity:.5;color:#aaa}.cell>.today{background-color:#647998}.cell>.selected{background-color:#0d6efd;color:#fff}.cell>.btn:disabled{background-color:#f8f9fa;color:#aaa;cursor:not-allowed}.col{text-align:center}.btn{font-size:90%;--bs-btn-padding-x: .5rem;--bs-btn-padding-y: .25rem}.btn:hover{background-color:azure}\n"] }]
|
|
1310
|
+
}], ctorParameters: () => [], propDecorators: { minDate: [{
|
|
1263
1311
|
type: Input
|
|
1264
1312
|
}], maxDate: [{
|
|
1265
1313
|
type: Input
|
|
1266
1314
|
}], monthLang: [{
|
|
1267
1315
|
type: Input
|
|
1268
|
-
}], startMode: [{
|
|
1269
|
-
type: Input
|
|
1270
1316
|
}] } });
|
|
1271
1317
|
|
|
1272
1318
|
class DeviceDetectorService {
|
|
@@ -1406,7 +1452,6 @@ class FlexDualDatepickerComponent {
|
|
|
1406
1452
|
calendarDropdown;
|
|
1407
1453
|
inputDiv;
|
|
1408
1454
|
modalDiv;
|
|
1409
|
-
// @ViewChild("menu") popupDiv?: ElementRef;
|
|
1410
1455
|
value = model(...(ngDevMode ? [undefined, { debugName: "value" }] : []));
|
|
1411
1456
|
enabled = input(true, ...(ngDevMode ? [{ debugName: "enabled" }] : []));
|
|
1412
1457
|
cssClass = input(...(ngDevMode ? [undefined, { debugName: "cssClass" }] : []));
|
|
@@ -1415,8 +1460,8 @@ class FlexDualDatepickerComponent {
|
|
|
1415
1460
|
calendarSwitchPosition = input("title", ...(ngDevMode ? [{ debugName: "calendarSwitchPosition" }] : []));
|
|
1416
1461
|
//selectedDate is needed to keep the current data for process
|
|
1417
1462
|
selectedDate;
|
|
1418
|
-
calendar =
|
|
1419
|
-
_calendar = "gregory";
|
|
1463
|
+
calendar = model("gregory", ...(ngDevMode ? [{ debugName: "calendar" }] : []));
|
|
1464
|
+
// protected _calendar: FlexCalendarSystem = "gregory";
|
|
1420
1465
|
inputDate = "";
|
|
1421
1466
|
isMobile = false;
|
|
1422
1467
|
constructor(dateService, deviceDetector, floating) {
|
|
@@ -1425,13 +1470,15 @@ class FlexDualDatepickerComponent {
|
|
|
1425
1470
|
this.floating = floating;
|
|
1426
1471
|
this.isMobile = deviceDetector.isMobile();
|
|
1427
1472
|
effect(() => {
|
|
1428
|
-
this._calendar = this.calendar();
|
|
1473
|
+
//this._calendar = this.calendar();
|
|
1474
|
+
if (!this.selectedDate)
|
|
1475
|
+
return;
|
|
1429
1476
|
this.inputDate = this.formatDate(this.selectedDate);
|
|
1430
1477
|
});
|
|
1431
1478
|
effect(() => {
|
|
1432
1479
|
const iso = this.value();
|
|
1433
1480
|
if (iso) {
|
|
1434
|
-
const date = dayjs(iso);
|
|
1481
|
+
const date = dayjs.utc(iso);
|
|
1435
1482
|
if (date.isValid()) {
|
|
1436
1483
|
this.selectedDate = date.toDate();
|
|
1437
1484
|
this.inputDate = this.formatDate(this.selectedDate);
|
|
@@ -1443,11 +1490,13 @@ class FlexDualDatepickerComponent {
|
|
|
1443
1490
|
});
|
|
1444
1491
|
}
|
|
1445
1492
|
switchCalendar() {
|
|
1446
|
-
if (this.
|
|
1447
|
-
this._calendar = "islamic";
|
|
1493
|
+
if (this.calendar() == "gregory") {
|
|
1494
|
+
// this._calendar = "islamic";
|
|
1495
|
+
this.calendar.set("islamic");
|
|
1448
1496
|
}
|
|
1449
1497
|
else {
|
|
1450
|
-
this._calendar = "gregory";
|
|
1498
|
+
//this._calendar = "gregory";
|
|
1499
|
+
this.calendar.set("gregory");
|
|
1451
1500
|
}
|
|
1452
1501
|
this.inputDate = this.formatDate(this.selectedDate);
|
|
1453
1502
|
}
|
|
@@ -1476,7 +1525,7 @@ class FlexDualDatepickerComponent {
|
|
|
1476
1525
|
this.value.set(d);
|
|
1477
1526
|
}
|
|
1478
1527
|
formatDate(date) {
|
|
1479
|
-
return this.dateService.format(date, this.
|
|
1528
|
+
return this.dateService.format(date, this.calendar(), this.format());
|
|
1480
1529
|
}
|
|
1481
1530
|
parseInputDate(str) {
|
|
1482
1531
|
/*if the user clear the text in input box then we must accept as the user
|
|
@@ -1490,7 +1539,7 @@ class FlexDualDatepickerComponent {
|
|
|
1490
1539
|
so we will should not show null or empty value, instead we will
|
|
1491
1540
|
return current date or last selected date
|
|
1492
1541
|
*/
|
|
1493
|
-
var parsedDate = this.dateService.parse(str, this.
|
|
1542
|
+
var parsedDate = this.dateService.parse(str, this.calendar(), this.format());
|
|
1494
1543
|
if (parsedDate)
|
|
1495
1544
|
return parsedDate;
|
|
1496
1545
|
//if parseDate is null this means user entered wrong date, in this case we will return
|
|
@@ -1513,10 +1562,12 @@ class FlexDualDatepickerComponent {
|
|
|
1513
1562
|
async openCalendar() {
|
|
1514
1563
|
const button = this.calendarButton?.nativeElement;
|
|
1515
1564
|
const result = await this.floating.open(button, FlexDualCalendarComponent, {
|
|
1516
|
-
placement: 'bottom
|
|
1565
|
+
placement: 'bottom',
|
|
1517
1566
|
inputs: {
|
|
1518
1567
|
// You can pass any props here
|
|
1519
1568
|
initialDate: this.selectedDate,
|
|
1569
|
+
mode: this.calendar,
|
|
1570
|
+
value: this.value
|
|
1520
1571
|
},
|
|
1521
1572
|
});
|
|
1522
1573
|
if (result) {
|
|
@@ -1526,11 +1577,11 @@ class FlexDualDatepickerComponent {
|
|
|
1526
1577
|
}
|
|
1527
1578
|
isOpen = false;
|
|
1528
1579
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: FlexDualDatepickerComponent, deps: [{ token: DateServiceService }, { token: DeviceDetectorService }, { token: FloatingUiService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1529
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.1", type: FlexDualDatepickerComponent, isStandalone: true, selector: "flex-dual-datepicker", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, enabled: { classPropertyName: "enabled", publicName: "enabled", isSignal: true, isRequired: false, transformFunction: null }, cssClass: { classPropertyName: "cssClass", publicName: "cssClass", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, calendarSwitchPosition: { classPropertyName: "calendarSwitchPosition", publicName: "calendarSwitchPosition", isSignal: true, isRequired: false, transformFunction: null }, calendar: { classPropertyName: "calendar", publicName: "calendar", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, viewQueries: [{ propertyName: "calendarButton", first: true, predicate: ["calendarButton"], descendants: true }, { propertyName: "calendarDropdown", first: true, predicate: ["calendarDropdown"], descendants: true }, { propertyName: "inputDiv", first: true, predicate: ["inputDiv"], descendants: true }, { propertyName: "modalDiv", first: true, predicate: ["modalDiv"], descendants: true }], ngImport: i0, template: "@if(calendarSwitchPosition() == 'title'){\r\n<div class=\"d-flex align-items-center gap-1\">\r\n <label>{{ title() }}</label>\r\n <button type=\"button\" class=\"btn btn-sm btn-light\" style=\"cursor: pointer; padding-bottom: 1px; padding-top: 1px;\"\r\n (click)=\"switchCalendar()\">\r\n @if(
|
|
1580
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.1", type: FlexDualDatepickerComponent, isStandalone: true, selector: "flex-dual-datepicker", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, enabled: { classPropertyName: "enabled", publicName: "enabled", isSignal: true, isRequired: false, transformFunction: null }, cssClass: { classPropertyName: "cssClass", publicName: "cssClass", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, calendarSwitchPosition: { classPropertyName: "calendarSwitchPosition", publicName: "calendarSwitchPosition", isSignal: true, isRequired: false, transformFunction: null }, calendar: { classPropertyName: "calendar", publicName: "calendar", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", calendar: "calendarChange" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, viewQueries: [{ propertyName: "calendarButton", first: true, predicate: ["calendarButton"], descendants: true }, { propertyName: "calendarDropdown", first: true, predicate: ["calendarDropdown"], descendants: true }, { propertyName: "inputDiv", first: true, predicate: ["inputDiv"], descendants: true }, { propertyName: "modalDiv", first: true, predicate: ["modalDiv"], descendants: true }], ngImport: i0, template: "@if(calendarSwitchPosition() == 'title'){\r\n<div class=\"d-flex align-items-center gap-1\">\r\n <label>{{ title() }}</label>\r\n <button type=\"button\" class=\"btn btn-sm btn-light\" style=\"cursor: pointer; padding-bottom: 1px; padding-top: 1px;\"\r\n (click)=\"switchCalendar()\">\r\n @if(calendar() == 'gregory') {G}\r\n @else{H}\r\n </button>\r\n</div>\r\n}\r\n<div class=\"input-group flex-nowrap\" #inputDiv>\r\n @if(calendarSwitchPosition() == 'inline'){\r\n <span class=\"input-group-text\" style=\"cursor: pointer;\" (click)=\"switchCalendar()\"> @if(calendar() == 'gregory') {G}\r\n @else{H}</span>\r\n }\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"inputDate\" (blur)=\"onManualDateEntered()\"\r\n [disabled]=\"!enabled()\" [placeholder]=\"format()\" (keyup.enter)=\"onManualDateEntered()\">\r\n <button #calendarButton class=\"btn btn-outline-secondary\" (click)=\"openCalendar()\" [disabled]=\"!enabled()\">\r\n <i class=\"bi bi-calendar3\"></i>\r\n </button>\r\n</div>", styles: [".dropdown-menu{--bs-dropdown-padding-y: 0}.card-body{padding:0!important}.dropdown-panel{position:fixed;border-radius:4px;z-index:9999}.calendar-dropdown{width:max-content;position:absolute;top:0;left:0;visibility:hidden;z-index:\"1080\",}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
|
|
1530
1581
|
}
|
|
1531
1582
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: FlexDualDatepickerComponent, decorators: [{
|
|
1532
1583
|
type: Component,
|
|
1533
|
-
args: [{ selector: 'flex-dual-datepicker', imports: [CommonModule, FormsModule], template: "@if(calendarSwitchPosition() == 'title'){\r\n<div class=\"d-flex align-items-center gap-1\">\r\n <label>{{ title() }}</label>\r\n <button type=\"button\" class=\"btn btn-sm btn-light\" style=\"cursor: pointer; padding-bottom: 1px; padding-top: 1px;\"\r\n (click)=\"switchCalendar()\">\r\n @if(
|
|
1584
|
+
args: [{ selector: 'flex-dual-datepicker', imports: [CommonModule, FormsModule], template: "@if(calendarSwitchPosition() == 'title'){\r\n<div class=\"d-flex align-items-center gap-1\">\r\n <label>{{ title() }}</label>\r\n <button type=\"button\" class=\"btn btn-sm btn-light\" style=\"cursor: pointer; padding-bottom: 1px; padding-top: 1px;\"\r\n (click)=\"switchCalendar()\">\r\n @if(calendar() == 'gregory') {G}\r\n @else{H}\r\n </button>\r\n</div>\r\n}\r\n<div class=\"input-group flex-nowrap\" #inputDiv>\r\n @if(calendarSwitchPosition() == 'inline'){\r\n <span class=\"input-group-text\" style=\"cursor: pointer;\" (click)=\"switchCalendar()\"> @if(calendar() == 'gregory') {G}\r\n @else{H}</span>\r\n }\r\n <input type=\"text\" class=\"form-control\" [(ngModel)]=\"inputDate\" (blur)=\"onManualDateEntered()\"\r\n [disabled]=\"!enabled()\" [placeholder]=\"format()\" (keyup.enter)=\"onManualDateEntered()\">\r\n <button #calendarButton class=\"btn btn-outline-secondary\" (click)=\"openCalendar()\" [disabled]=\"!enabled()\">\r\n <i class=\"bi bi-calendar3\"></i>\r\n </button>\r\n</div>", styles: [".dropdown-menu{--bs-dropdown-padding-y: 0}.card-body{padding:0!important}.dropdown-panel{position:fixed;border-radius:4px;z-index:9999}.calendar-dropdown{width:max-content;position:absolute;top:0;left:0;visibility:hidden;z-index:\"1080\",}\n"] }]
|
|
1534
1585
|
}], ctorParameters: () => [{ type: DateServiceService }, { type: DeviceDetectorService }, { type: FloatingUiService }], propDecorators: { calendarButton: [{
|
|
1535
1586
|
type: ViewChild,
|
|
1536
1587
|
args: ['calendarButton']
|
|
@@ -1548,6 +1599,50 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.1", ngImpor
|
|
|
1548
1599
|
args: ['document:click', ['$event']]
|
|
1549
1600
|
}] } });
|
|
1550
1601
|
|
|
1602
|
+
class FlexTableComponent {
|
|
1603
|
+
columns = Array.from({ length: 50 }, (_, index) => `Item ${index + 1}`);
|
|
1604
|
+
items = Array.from({ length: 50 }, (_, index) => `Item ${index + 1}`);
|
|
1605
|
+
enablePaging = input(false, ...(ngDevMode ? [{ debugName: "enablePaging" }] : []));
|
|
1606
|
+
totalDataCount = input(0, ...(ngDevMode ? [{ debugName: "totalDataCount" }] : []));
|
|
1607
|
+
pageChange = output();
|
|
1608
|
+
currentPage = 1;
|
|
1609
|
+
pageSize = 50;
|
|
1610
|
+
selectedIndex = -1;
|
|
1611
|
+
gridColumns;
|
|
1612
|
+
tableHeader;
|
|
1613
|
+
dataSource = input([], ...(ngDevMode ? [{ debugName: "dataSource" }] : []));
|
|
1614
|
+
rowClicked = output();
|
|
1615
|
+
rowDblClicked = output();
|
|
1616
|
+
syncScroll(e) {
|
|
1617
|
+
const body = e.target;
|
|
1618
|
+
const header = this.tableHeader?.nativeElement; //document.querySelector('.grid-header');
|
|
1619
|
+
if (header)
|
|
1620
|
+
header.scrollLeft = body.scrollLeft;
|
|
1621
|
+
}
|
|
1622
|
+
onRowDblClick(index, data) {
|
|
1623
|
+
this.selectedIndex = index;
|
|
1624
|
+
// console.log(index);
|
|
1625
|
+
this.rowDblClicked.emit({ index: index, data: data });
|
|
1626
|
+
}
|
|
1627
|
+
onRowClick(index, data) {
|
|
1628
|
+
this.selectedIndex = index;
|
|
1629
|
+
// console.log(index);
|
|
1630
|
+
this.rowClicked.emit({ index: index, data: data });
|
|
1631
|
+
}
|
|
1632
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: FlexTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1633
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.1", type: FlexTableComponent, isStandalone: true, selector: "flex-table", inputs: { enablePaging: { classPropertyName: "enablePaging", publicName: "enablePaging", isSignal: true, isRequired: false, transformFunction: null }, totalDataCount: { classPropertyName: "totalDataCount", publicName: "totalDataCount", isSignal: true, isRequired: false, transformFunction: null }, dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageChange: "pageChange", rowClicked: "rowClicked", rowDblClicked: "rowDblClicked" }, queries: [{ propertyName: "gridColumns", first: true, predicate: FlexColumnsComponent, descendants: true }], viewQueries: [{ propertyName: "tableHeader", first: true, predicate: ["tableHeader"], descendants: true }], ngImport: i0, template: "<div class=\"table-layout\">\r\n <div style=\"overflow-x: hidden; padding-right: 15px;\" #tableHeader>\r\n <table class=\"table table-bordered mb-0 table-header\">\r\n <colgroup>\r\n @for (col of gridColumns?.columns; track $index) {\r\n <col [style.width.px]=\"col.width\" [style.maxWidth.px]=\"col.width\">\r\n }\r\n </colgroup>\r\n <thead>\r\n <tr>\r\n @for (col of gridColumns?.columns; track $index) {\r\n <th class=\"text-truncate\">\r\n @if (col.headerTemplate) {\r\n <ng-container [ngTemplateOutlet]=\"col.headerTemplate\"></ng-container>\r\n }\r\n @else {\r\n <!-- <ng-template #defaultHeader><span [textContent]=\"col.field\"></span></ng-template> -->\r\n <!-- <span [textContent]=\"col.field\"></span> -->\r\n {{ col.headerText() }}\r\n }\r\n </th>\r\n }\r\n\r\n <!-- <th style=\"width: 20px;\"></th> -->\r\n </tr>\r\n </thead>\r\n </table>\r\n </div>\r\n\r\n <div class=\"content-area\" (scroll)=\"syncScroll($event)\">\r\n <table class=\"table table-bordered\">\r\n <colgroup>\r\n @for (col of gridColumns?.columns; track $index) {\r\n <col [style.width.px]=\"col.width\" [style.maxWidth.px]=\"col.width\">\r\n }\r\n </colgroup>\r\n <tbody>\r\n @for (row of dataSource(); track $index; let i = $index) {\r\n <tr [class.table-active]=\"$index === selectedIndex\" (click)=\"onRowClick($index, row)\"\r\n (dblclick)=\"onRowDblClick($index, row)\">\r\n @for (col of gridColumns?.columns; track $index) {\r\n <td>\r\n @if (col.cellTemplate) {\r\n <ng-container [ngTemplateOutlet]=\"col.cellTemplate\" [ngTemplateOutletContext]=\"{ $implicit: row,\r\n rowIndex: (currentPage - 1) * pageSize + i,\r\n localIndex: i }\">\r\n </ng-container>\r\n } @else {\r\n <!-- {{ row[col.field] }} -->\r\n <span [textContent]=\"row[col.field]\"></span>\r\n }\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <div class=\"border-top\">\r\n <div class=\"d-flex align-items-center gap-1 p-1\">\r\n <div>Page No</div>\r\n <div>\r\n <select class=\"form-select form-sm\">\r\n <option>\r\n Page 1\r\n </option>\r\n </select>\r\n </div>\r\n <div>Page Size</div>\r\n <div>\r\n <select class=\"form-select\">\r\n <option>\r\n 800\r\n </option>\r\n <option>\r\n 400\r\n </option>\r\n </select>\r\n </div>\r\n <div>\r\n {{ \"total-count\" }}: {{ totalDataCount() }}\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [":host{display:block;height:100%;min-height:0;background:var(--bg);color:var(--text)}.table-layout{display:grid;grid-template-rows:auto 1fr auto;height:100%;min-height:0}.content-area{overflow-x:auto;overflow-y:auto;min-height:0;background:var(--scroll-bg)}table{border-collapse:collapse;white-space:nowrap;min-width:max-content}.table-header{--bs-table-bg: #f9f9f9}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
|
|
1634
|
+
}
|
|
1635
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.1", ngImport: i0, type: FlexTableComponent, decorators: [{
|
|
1636
|
+
type: Component,
|
|
1637
|
+
args: [{ selector: 'flex-table', imports: [CommonModule], template: "<div class=\"table-layout\">\r\n <div style=\"overflow-x: hidden; padding-right: 15px;\" #tableHeader>\r\n <table class=\"table table-bordered mb-0 table-header\">\r\n <colgroup>\r\n @for (col of gridColumns?.columns; track $index) {\r\n <col [style.width.px]=\"col.width\" [style.maxWidth.px]=\"col.width\">\r\n }\r\n </colgroup>\r\n <thead>\r\n <tr>\r\n @for (col of gridColumns?.columns; track $index) {\r\n <th class=\"text-truncate\">\r\n @if (col.headerTemplate) {\r\n <ng-container [ngTemplateOutlet]=\"col.headerTemplate\"></ng-container>\r\n }\r\n @else {\r\n <!-- <ng-template #defaultHeader><span [textContent]=\"col.field\"></span></ng-template> -->\r\n <!-- <span [textContent]=\"col.field\"></span> -->\r\n {{ col.headerText() }}\r\n }\r\n </th>\r\n }\r\n\r\n <!-- <th style=\"width: 20px;\"></th> -->\r\n </tr>\r\n </thead>\r\n </table>\r\n </div>\r\n\r\n <div class=\"content-area\" (scroll)=\"syncScroll($event)\">\r\n <table class=\"table table-bordered\">\r\n <colgroup>\r\n @for (col of gridColumns?.columns; track $index) {\r\n <col [style.width.px]=\"col.width\" [style.maxWidth.px]=\"col.width\">\r\n }\r\n </colgroup>\r\n <tbody>\r\n @for (row of dataSource(); track $index; let i = $index) {\r\n <tr [class.table-active]=\"$index === selectedIndex\" (click)=\"onRowClick($index, row)\"\r\n (dblclick)=\"onRowDblClick($index, row)\">\r\n @for (col of gridColumns?.columns; track $index) {\r\n <td>\r\n @if (col.cellTemplate) {\r\n <ng-container [ngTemplateOutlet]=\"col.cellTemplate\" [ngTemplateOutletContext]=\"{ $implicit: row,\r\n rowIndex: (currentPage - 1) * pageSize + i,\r\n localIndex: i }\">\r\n </ng-container>\r\n } @else {\r\n <!-- {{ row[col.field] }} -->\r\n <span [textContent]=\"row[col.field]\"></span>\r\n }\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <div class=\"border-top\">\r\n <div class=\"d-flex align-items-center gap-1 p-1\">\r\n <div>Page No</div>\r\n <div>\r\n <select class=\"form-select form-sm\">\r\n <option>\r\n Page 1\r\n </option>\r\n </select>\r\n </div>\r\n <div>Page Size</div>\r\n <div>\r\n <select class=\"form-select\">\r\n <option>\r\n 800\r\n </option>\r\n <option>\r\n 400\r\n </option>\r\n </select>\r\n </div>\r\n <div>\r\n {{ \"total-count\" }}: {{ totalDataCount() }}\r\n </div>\r\n </div>\r\n </div>\r\n</div>", styles: [":host{display:block;height:100%;min-height:0;background:var(--bg);color:var(--text)}.table-layout{display:grid;grid-template-rows:auto 1fr auto;height:100%;min-height:0}.content-area{overflow-x:auto;overflow-y:auto;min-height:0;background:var(--scroll-bg)}table{border-collapse:collapse;white-space:nowrap;min-width:max-content}.table-header{--bs-table-bg: #f9f9f9}\n"] }]
|
|
1638
|
+
}], propDecorators: { gridColumns: [{
|
|
1639
|
+
type: ContentChild,
|
|
1640
|
+
args: [FlexColumnsComponent]
|
|
1641
|
+
}], tableHeader: [{
|
|
1642
|
+
type: ViewChild,
|
|
1643
|
+
args: ["tableHeader"]
|
|
1644
|
+
}] } });
|
|
1645
|
+
|
|
1551
1646
|
/*
|
|
1552
1647
|
* Public API Surface of flex-ui-controls
|
|
1553
1648
|
*/
|
|
@@ -1556,5 +1651,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.1", ngImpor
|
|
|
1556
1651
|
* Generated bundle index. Do not edit.
|
|
1557
1652
|
*/
|
|
1558
1653
|
|
|
1559
|
-
export { ComboDatePickerComponent, FlexColumnComponent, FlexColumnsComponent, FlexContainerComponent, FlexDualDatepickerComponent, FlexGridComponent, FlexPaginationComponent, FlexPanelComponent, HijriDatepickerComponent };
|
|
1654
|
+
export { ComboDatePickerComponent, FlexColumnComponent, FlexColumnsComponent, FlexContainerComponent, FlexDualDatepickerComponent, FlexGridComponent, FlexPaginationComponent, FlexPanelComponent, FlexTableComponent, HijriDatepickerComponent };
|
|
1560
1655
|
//# sourceMappingURL=dcsl-flex-ui.mjs.map
|