angular-hijri-gregorian-date-time-picker 1.5.0 → 1.5.1

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, EventEmitter, Component, Input, Output, HostBinding, NgModule } from '@angular/core';
2
+ import { Injectable, EventEmitter, HostBinding, Output, Input, Component, NgModule } from '@angular/core';
3
3
  import * as i1 from '@angular/forms';
4
4
  import { FormsModule, ReactiveFormsModule } from '@angular/forms';
5
5
  import * as i3 from '@angular/common';
@@ -27378,377 +27378,377 @@ var dictionary = {
27378
27378
  }
27379
27379
  };
27380
27380
 
27381
- class DateUtilitiesService {
27382
- constructor() {
27383
- this.calendarData = dictionary; //prod
27384
- // this.calendarData = datesDictionary; //debug
27385
- }
27386
- parseDate(dateStr) {
27387
- if (!dateStr) {
27388
- return null;
27389
- }
27390
- const parts = dateStr?.split('/');
27391
- if (parts.length !== 3) {
27392
- return null;
27393
- }
27394
- const [day, month, year] = parts.map(Number);
27395
- if (isNaN(day) ||
27396
- isNaN(month) ||
27397
- isNaN(year) ||
27398
- day < 1 ||
27399
- day > 31 ||
27400
- month < 1 ||
27401
- month > 12 ||
27402
- year < 1) {
27403
- return null;
27404
- }
27405
- return new Date(year, month - 1, day);
27406
- }
27407
- formatDate(date) {
27408
- const day = String(date.getDate()).padStart(2, '0');
27409
- const month = String(date.getMonth() + 1).padStart(2, '0');
27410
- const year = date.getFullYear();
27411
- return `${day}/${month}/${year}`;
27412
- }
27413
- getDayShortHand(date) {
27414
- return date.toLocaleString('en-US', { weekday: 'short' });
27415
- }
27416
- generateDates(fD, lD, uC) {
27417
- const startDate = this.parseDate(fD?.gD);
27418
- const endDate = this.parseDate(lD?.gD);
27419
- const daysInMonth = [];
27420
- let currentGregorianDate = new Date(startDate);
27421
- let currentUmmAlQuraDay = parseInt(fD?.uD?.split('/')[0]);
27422
- let currentUmmAlQuraMonth = parseInt(fD?.uD?.split('/')[1]);
27423
- let currentUmmAlQuraYear = parseInt(fD?.uD?.split('/')[2]);
27424
- let daysInCurrentUmmAlQuraMonth = uC;
27425
- while (currentGregorianDate <= endDate) {
27426
- const ummAlQuraDate = `${currentUmmAlQuraDay
27427
- .toString()
27428
- .padStart(2, '0')}/${currentUmmAlQuraMonth
27429
- .toString()
27430
- .padStart(2, '0')}/${currentUmmAlQuraYear}`;
27431
- daysInMonth.push({
27432
- gD: this.formatDate(currentGregorianDate),
27433
- uD: ummAlQuraDate,
27434
- dN: this.getDayShortHand(currentGregorianDate),
27435
- uC: 0,
27436
- });
27437
- currentGregorianDate.setDate(currentGregorianDate.getDate() + 1);
27438
- currentUmmAlQuraDay += 1;
27439
- if (currentUmmAlQuraDay > daysInCurrentUmmAlQuraMonth) {
27440
- currentUmmAlQuraDay = 1;
27441
- currentUmmAlQuraMonth += 1;
27442
- if (currentUmmAlQuraMonth > 12) {
27443
- currentUmmAlQuraMonth = 1;
27444
- currentUmmAlQuraYear += 1;
27445
- }
27446
- const nextMonthData = this.calendarData[currentUmmAlQuraYear.toString()]?.[currentUmmAlQuraMonth.toString()];
27447
- daysInCurrentUmmAlQuraMonth = nextMonthData ? nextMonthData.fD.uC : 30;
27448
- }
27449
- }
27450
- return daysInMonth;
27451
- }
27452
- convertDate(dateStr, isGregorian) {
27453
- if (!dateStr)
27454
- return null;
27455
- if (isGregorian) {
27456
- // Preprocess Gregorian date
27457
- const gregorianDate = this.parseDate(dateStr);
27458
- if (!gregorianDate)
27459
- return null;
27460
- const formattedDate = this.formatDate(gregorianDate);
27461
- for (const yearKey in this.calendarData) {
27462
- for (const monthKey in this.calendarData[yearKey]) {
27463
- const monthData = this.calendarData[yearKey][monthKey];
27464
- if (this.isDateInMonthRange(formattedDate, monthData.fD?.gD, monthData.lD?.gD)) {
27465
- const daysInMonth = this.generateDates(monthData.fD, monthData.lD, monthData.fD?.uC);
27466
- const dayMatch = daysInMonth.find((d) => d.gD === formattedDate);
27467
- if (dayMatch)
27468
- return dayMatch;
27469
- }
27470
- }
27471
- }
27472
- }
27473
- else {
27474
- const [day, month, year] = dateStr.split('/').map(Number);
27475
- if (isNaN(day) || isNaN(month) || isNaN(year))
27476
- return null;
27477
- for (const yearKey in this.calendarData) {
27478
- for (const monthKey in this.calendarData[yearKey]) {
27479
- const monthData = this.calendarData[yearKey][monthKey];
27480
- if (this.isDateInMonthRange(`${day}/${month}/${year}`, monthData.fD?.uD, monthData.lD?.uD)) {
27481
- const daysInMonth = this.generateDates(monthData.fD, monthData.lD, monthData.fD?.uC);
27482
- const dayMatch = daysInMonth.find((d) => {
27483
- const [uDay, uMonth, uYear] = d?.uD?.split('/').map(Number);
27484
- return uDay === day && uMonth === month && uYear === year;
27485
- });
27486
- if (dayMatch)
27487
- return dayMatch;
27488
- }
27489
- }
27490
- }
27491
- }
27492
- return null;
27493
- }
27494
- isDateInMonthRange(dateToCheck, monthStartDate, monthEndDate) {
27495
- if (!monthStartDate || !monthEndDate)
27496
- return false;
27497
- const checkDate = this.parseDate(dateToCheck);
27498
- const startDate = this.parseDate(monthStartDate);
27499
- const endDate = this.parseDate(monthEndDate);
27500
- if (!checkDate || !startDate || !endDate)
27501
- return false;
27502
- return checkDate >= startDate && checkDate <= endDate;
27503
- }
27504
- getMonthData(inputDate, type) {
27505
- const [day, month, year] = inputDate?.split('/').map(Number);
27506
- let isGregorian;
27507
- if (type == 'greg') {
27508
- isGregorian = true;
27509
- }
27510
- else {
27511
- isGregorian = false;
27512
- }
27513
- if (isGregorian) {
27514
- return this.getGregorianMonthData(day, month, year);
27515
- }
27516
- else {
27517
- return this.getUmAlQurraMonthData(day, month, year);
27518
- }
27519
- }
27520
- getGregorianMonthData(day, month, year) {
27521
- const yearData = this.calendarData[year];
27522
- if (!yearData)
27523
- return null;
27524
- const monthData = yearData[month];
27525
- if (!monthData)
27526
- return null;
27527
- const monthArray = [];
27528
- const endDate = new Date(year, month, 0);
27529
- for (let d = 1; d <= endDate.getDate(); d++) {
27530
- const offset = d - 1;
27531
- monthArray.push({
27532
- gD: `${d.toString().padStart(2, '0')}/${month
27533
- .toString()
27534
- .padStart(2, '0')}/${year}`,
27535
- uD: this.calculateUmAlQurraDate(monthData.fD.uD, offset, monthData.fD.uC),
27536
- dN: this.getDayName(new Date(year, month - 1, d).getDay()),
27537
- uC: monthData.fD.uC,
27538
- });
27539
- }
27540
- return monthArray;
27541
- }
27542
- getUmAlQurraMonthData(day, month, year) {
27543
- for (const gregorianYear in this.calendarData) {
27544
- const yearData = this.calendarData[parseInt(gregorianYear)];
27545
- for (const monthIndex in yearData) {
27546
- const monthData = yearData[parseInt(monthIndex)];
27547
- const [fDay, fMonth, fYear] = monthData?.fD?.uD?.split('/').map(Number);
27548
- if (fYear === year && fMonth === month) {
27549
- const totalDays = monthData.fD.uC;
27550
- const monthArray = [];
27551
- const umAlQurraStartDate = `01/${month
27552
- .toString()
27553
- .padStart(2, '0')}/${year}`;
27554
- const dayDifference = fDay - 1;
27555
- const startGregorianDate = this.calculateGregorianDate(monthData.fD.gD, -dayDifference);
27556
- for (let i = 0; i < totalDays; i++) {
27557
- const uDate = this.calculateUmAlQurraDate(umAlQurraStartDate, i, totalDays);
27558
- const gDate = this.calculateGregorianDate(startGregorianDate, i);
27559
- const [gDay, gMonth, gYear] = gDate?.split('/').map(Number);
27560
- const dayName = this.getDayName(new Date(gYear, gMonth - 1, gDay).getDay());
27561
- monthArray.push({
27562
- gD: gDate,
27563
- uD: uDate,
27564
- dN: dayName,
27565
- uC: totalDays,
27566
- });
27567
- }
27568
- return monthArray;
27569
- }
27570
- }
27571
- }
27572
- return null;
27573
- }
27574
- calculateGregorianDate(startGDate, offset) {
27575
- const [day, month, year] = startGDate?.split('/').map(Number);
27576
- const newDate = new Date(year, month - 1, day + offset);
27577
- return `${newDate.getDate().toString().padStart(2, '0')}/${(newDate.getMonth() + 1)
27578
- .toString()
27579
- .padStart(2, '0')}/${newDate.getFullYear()}`;
27580
- }
27581
- calculateUmAlQurraDate(startUDate, offset, uC) {
27582
- const [day, month, year] = startUDate?.split('/').map(Number);
27583
- let newDay = day + offset;
27584
- let newMonth = month;
27585
- let newYear = year;
27586
- while (newDay > uC) {
27587
- newDay -= uC;
27588
- newMonth += 1;
27589
- }
27590
- while (newMonth > 12) {
27591
- newMonth = 1;
27592
- newYear += 1;
27593
- }
27594
- return `${newDay.toString().padStart(2, '0')}/${newMonth
27595
- .toString()
27596
- .padStart(2, '0')}/${newYear}`;
27597
- }
27598
- getDayName(dayIndex) {
27599
- const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
27600
- return days[dayIndex];
27601
- }
27602
- /// Check date is it in past or future
27603
- checkPastOrFuture(inputDate, targetDate) {
27604
- if (inputDate) {
27605
- const [day, month, year] = inputDate?.split('/').map(Number);
27606
- const dateToCheck = new Date(year, month - 1, day);
27607
- const today = targetDate;
27608
- today.setHours(0, 0, 0, 0);
27609
- if (dateToCheck > today) {
27610
- return 'Future';
27611
- }
27612
- else if (dateToCheck < today) {
27613
- return 'Past';
27614
- }
27615
- else {
27616
- return 'Today';
27617
- }
27618
- }
27619
- }
27620
- /// Convert english numbers to arabic equivalent
27621
- parseEnglish(englishNum) {
27622
- if (!englishNum)
27623
- return englishNum;
27624
- const numStr = String(englishNum);
27625
- const arabicNumbers = [
27626
- '\u0660',
27627
- '\u0661',
27628
- '\u0662',
27629
- '\u0663',
27630
- '\u0664',
27631
- '\u0665',
27632
- '\u0666',
27633
- '\u0667',
27634
- '\u0668',
27635
- '\u0669',
27636
- ];
27637
- return numStr.replace(/[0-9]/g, (digit) => {
27638
- return arabicNumbers[Number(digit)] || digit;
27639
- });
27640
- }
27641
- /// Convert arabic numbers to english equivalent
27642
- parseArabic(arabicNum) {
27643
- return arabicNum.replace(/[٠١٢٣٤٥٦٧٨٩]/g, function (d) {
27644
- return d.charCodeAt(0) - 1632;
27645
- });
27646
- }
27647
- ///
27648
- convertDateNumerals(date, targetLang) {
27649
- const arabicNumbers = ['٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'];
27650
- const englishNumbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
27651
- const toArabic = (value) => value
27652
- .split('')
27653
- .map((char) => (/\d/.test(char) ? arabicNumbers[+char] : char))
27654
- .join('');
27655
- const toEnglish = (value) => value
27656
- .split('')
27657
- .map((char) => {
27658
- const index = arabicNumbers.indexOf(char);
27659
- return index > -1 ? englishNumbers[index] : char;
27660
- })
27661
- .join('');
27662
- if (targetLang === 'ar') {
27663
- const [day, month, year] = date.split('/');
27664
- return `${toArabic(year)}/${toArabic(month)}/${toArabic(day)}`;
27665
- }
27666
- else {
27667
- const [year, month, day] = date.split('/');
27668
- return `${toEnglish(day)}/${toEnglish(month)}/${toEnglish(year)}`;
27669
- }
27670
- }
27671
- /**
27672
- * Normalize input date to DD/MM/YYYY string format (Gregorian)
27673
- * Accepts Date object or DD/MM/YYYY string
27674
- */
27675
- normalizeDateToString(date) {
27676
- if (!date)
27677
- return null;
27678
- if (date instanceof Date) {
27679
- return this.formatDate(date);
27680
- }
27681
- // Already a string - validate format
27682
- const parsed = this.parseDate(date);
27683
- return parsed ? this.formatDate(parsed) : null;
27684
- }
27685
- /**
27686
- * Compare two dates (Gregorian format DD/MM/YYYY)
27687
- * Returns: -1 if date1 < date2, 0 if equal, 1 if date1 > date2
27688
- */
27689
- compareDates(date1Str, date2Str) {
27690
- const d1 = this.parseDate(date1Str);
27691
- const d2 = this.parseDate(date2Str);
27692
- if (!d1 || !d2)
27693
- return 0;
27694
- if (d1 < d2)
27695
- return -1;
27696
- if (d1 > d2)
27697
- return 1;
27698
- return 0;
27699
- }
27700
- /**
27701
- * Compare two Hijri dates (UM format DD/MM/YYYY)
27702
- * Converts to Gregorian for comparison
27703
- */
27704
- compareHijriDates(hijri1, hijri2) {
27705
- const day1 = this.convertDate(hijri1, false);
27706
- const day2 = this.convertDate(hijri2, false);
27707
- if (!day1?.gD || !day2?.gD)
27708
- return 0;
27709
- return this.compareDates(day1.gD, day2.gD);
27710
- }
27711
- /**
27712
- * Check if a date is within the specified range (inclusive)
27713
- * All dates in Gregorian DD/MM/YYYY format
27714
- */
27715
- isDateInRange(dateStr, minDateStr, maxDateStr) {
27716
- if (!dateStr)
27717
- return false;
27718
- // If no constraints, date is valid
27719
- if (!minDateStr && !maxDateStr)
27720
- return true;
27721
- // Check minimum constraint
27722
- if (minDateStr && this.compareDates(dateStr, minDateStr) < 0) {
27723
- return false;
27724
- }
27725
- // Check maximum constraint
27726
- if (maxDateStr && this.compareDates(dateStr, maxDateStr) > 0) {
27727
- return false;
27728
- }
27729
- return true;
27730
- }
27731
- /**
27732
- * Check if a Hijri date is within the specified range
27733
- * Converts to Gregorian for comparison
27734
- */
27735
- isHijriDateInRange(hijriDateStr, minDateStr, maxDateStr) {
27736
- if (!hijriDateStr)
27737
- return false;
27738
- const dayInfo = this.convertDate(hijriDateStr, false);
27739
- if (!dayInfo?.gD)
27740
- return false;
27741
- return this.isDateInRange(dayInfo.gD, minDateStr, maxDateStr);
27742
- }
27743
- }
27744
- DateUtilitiesServicefac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DateUtilitiesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
27745
- DateUtilitiesService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DateUtilitiesService, providedIn: 'root' });
27746
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DateUtilitiesService, decorators: [{
27747
- type: Injectable,
27748
- args: [{
27749
- providedIn: 'root',
27750
- }]
27751
- }], ctorParameters: function () { return []; } });
27381
+ class DateUtilitiesService {
27382
+ constructor() {
27383
+ this.calendarData = dictionary; //prod
27384
+ // this.calendarData = datesDictionary; //debug
27385
+ }
27386
+ parseDate(dateStr) {
27387
+ if (!dateStr) {
27388
+ return null;
27389
+ }
27390
+ const parts = dateStr?.split('/');
27391
+ if (parts.length !== 3) {
27392
+ return null;
27393
+ }
27394
+ const [day, month, year] = parts.map(Number);
27395
+ if (isNaN(day) ||
27396
+ isNaN(month) ||
27397
+ isNaN(year) ||
27398
+ day < 1 ||
27399
+ day > 31 ||
27400
+ month < 1 ||
27401
+ month > 12 ||
27402
+ year < 1) {
27403
+ return null;
27404
+ }
27405
+ return new Date(year, month - 1, day);
27406
+ }
27407
+ formatDate(date) {
27408
+ const day = String(date.getDate()).padStart(2, '0');
27409
+ const month = String(date.getMonth() + 1).padStart(2, '0');
27410
+ const year = date.getFullYear();
27411
+ return `${day}/${month}/${year}`;
27412
+ }
27413
+ getDayShortHand(date) {
27414
+ return date.toLocaleString('en-US', { weekday: 'short' });
27415
+ }
27416
+ generateDates(fD, lD, uC) {
27417
+ const startDate = this.parseDate(fD?.gD);
27418
+ const endDate = this.parseDate(lD?.gD);
27419
+ const daysInMonth = [];
27420
+ let currentGregorianDate = new Date(startDate);
27421
+ let currentUmmAlQuraDay = parseInt(fD?.uD?.split('/')[0]);
27422
+ let currentUmmAlQuraMonth = parseInt(fD?.uD?.split('/')[1]);
27423
+ let currentUmmAlQuraYear = parseInt(fD?.uD?.split('/')[2]);
27424
+ let daysInCurrentUmmAlQuraMonth = uC;
27425
+ while (currentGregorianDate <= endDate) {
27426
+ const ummAlQuraDate = `${currentUmmAlQuraDay
27427
+ .toString()
27428
+ .padStart(2, '0')}/${currentUmmAlQuraMonth
27429
+ .toString()
27430
+ .padStart(2, '0')}/${currentUmmAlQuraYear}`;
27431
+ daysInMonth.push({
27432
+ gD: this.formatDate(currentGregorianDate),
27433
+ uD: ummAlQuraDate,
27434
+ dN: this.getDayShortHand(currentGregorianDate),
27435
+ uC: 0,
27436
+ });
27437
+ currentGregorianDate.setDate(currentGregorianDate.getDate() + 1);
27438
+ currentUmmAlQuraDay += 1;
27439
+ if (currentUmmAlQuraDay > daysInCurrentUmmAlQuraMonth) {
27440
+ currentUmmAlQuraDay = 1;
27441
+ currentUmmAlQuraMonth += 1;
27442
+ if (currentUmmAlQuraMonth > 12) {
27443
+ currentUmmAlQuraMonth = 1;
27444
+ currentUmmAlQuraYear += 1;
27445
+ }
27446
+ const nextMonthData = this.calendarData[currentUmmAlQuraYear.toString()]?.[currentUmmAlQuraMonth.toString()];
27447
+ daysInCurrentUmmAlQuraMonth = nextMonthData ? nextMonthData.fD.uC : 30;
27448
+ }
27449
+ }
27450
+ return daysInMonth;
27451
+ }
27452
+ convertDate(dateStr, isGregorian) {
27453
+ if (!dateStr)
27454
+ return null;
27455
+ if (isGregorian) {
27456
+ // Preprocess Gregorian date
27457
+ const gregorianDate = this.parseDate(dateStr);
27458
+ if (!gregorianDate)
27459
+ return null;
27460
+ const formattedDate = this.formatDate(gregorianDate);
27461
+ for (const yearKey in this.calendarData) {
27462
+ for (const monthKey in this.calendarData[yearKey]) {
27463
+ const monthData = this.calendarData[yearKey][monthKey];
27464
+ if (this.isDateInMonthRange(formattedDate, monthData.fD?.gD, monthData.lD?.gD)) {
27465
+ const daysInMonth = this.generateDates(monthData.fD, monthData.lD, monthData.fD?.uC);
27466
+ const dayMatch = daysInMonth.find((d) => d.gD === formattedDate);
27467
+ if (dayMatch)
27468
+ return dayMatch;
27469
+ }
27470
+ }
27471
+ }
27472
+ }
27473
+ else {
27474
+ const [day, month, year] = dateStr.split('/').map(Number);
27475
+ if (isNaN(day) || isNaN(month) || isNaN(year))
27476
+ return null;
27477
+ for (const yearKey in this.calendarData) {
27478
+ for (const monthKey in this.calendarData[yearKey]) {
27479
+ const monthData = this.calendarData[yearKey][monthKey];
27480
+ if (this.isDateInMonthRange(`${day}/${month}/${year}`, monthData.fD?.uD, monthData.lD?.uD)) {
27481
+ const daysInMonth = this.generateDates(monthData.fD, monthData.lD, monthData.fD?.uC);
27482
+ const dayMatch = daysInMonth.find((d) => {
27483
+ const [uDay, uMonth, uYear] = d?.uD?.split('/').map(Number);
27484
+ return uDay === day && uMonth === month && uYear === year;
27485
+ });
27486
+ if (dayMatch)
27487
+ return dayMatch;
27488
+ }
27489
+ }
27490
+ }
27491
+ }
27492
+ return null;
27493
+ }
27494
+ isDateInMonthRange(dateToCheck, monthStartDate, monthEndDate) {
27495
+ if (!monthStartDate || !monthEndDate)
27496
+ return false;
27497
+ const checkDate = this.parseDate(dateToCheck);
27498
+ const startDate = this.parseDate(monthStartDate);
27499
+ const endDate = this.parseDate(monthEndDate);
27500
+ if (!checkDate || !startDate || !endDate)
27501
+ return false;
27502
+ return checkDate >= startDate && checkDate <= endDate;
27503
+ }
27504
+ getMonthData(inputDate, type) {
27505
+ const [day, month, year] = inputDate?.split('/').map(Number);
27506
+ let isGregorian;
27507
+ if (type == 'greg') {
27508
+ isGregorian = true;
27509
+ }
27510
+ else {
27511
+ isGregorian = false;
27512
+ }
27513
+ if (isGregorian) {
27514
+ return this.getGregorianMonthData(day, month, year);
27515
+ }
27516
+ else {
27517
+ return this.getUmAlQurraMonthData(day, month, year);
27518
+ }
27519
+ }
27520
+ getGregorianMonthData(day, month, year) {
27521
+ const yearData = this.calendarData[year];
27522
+ if (!yearData)
27523
+ return null;
27524
+ const monthData = yearData[month];
27525
+ if (!monthData)
27526
+ return null;
27527
+ const monthArray = [];
27528
+ const endDate = new Date(year, month, 0);
27529
+ for (let d = 1; d <= endDate.getDate(); d++) {
27530
+ const offset = d - 1;
27531
+ monthArray.push({
27532
+ gD: `${d.toString().padStart(2, '0')}/${month
27533
+ .toString()
27534
+ .padStart(2, '0')}/${year}`,
27535
+ uD: this.calculateUmAlQurraDate(monthData.fD.uD, offset, monthData.fD.uC),
27536
+ dN: this.getDayName(new Date(year, month - 1, d).getDay()),
27537
+ uC: monthData.fD.uC,
27538
+ });
27539
+ }
27540
+ return monthArray;
27541
+ }
27542
+ getUmAlQurraMonthData(day, month, year) {
27543
+ for (const gregorianYear in this.calendarData) {
27544
+ const yearData = this.calendarData[parseInt(gregorianYear)];
27545
+ for (const monthIndex in yearData) {
27546
+ const monthData = yearData[parseInt(monthIndex)];
27547
+ const [fDay, fMonth, fYear] = monthData?.fD?.uD?.split('/').map(Number);
27548
+ if (fYear === year && fMonth === month) {
27549
+ const totalDays = monthData.fD.uC;
27550
+ const monthArray = [];
27551
+ const umAlQurraStartDate = `01/${month
27552
+ .toString()
27553
+ .padStart(2, '0')}/${year}`;
27554
+ const dayDifference = fDay - 1;
27555
+ const startGregorianDate = this.calculateGregorianDate(monthData.fD.gD, -dayDifference);
27556
+ for (let i = 0; i < totalDays; i++) {
27557
+ const uDate = this.calculateUmAlQurraDate(umAlQurraStartDate, i, totalDays);
27558
+ const gDate = this.calculateGregorianDate(startGregorianDate, i);
27559
+ const [gDay, gMonth, gYear] = gDate?.split('/').map(Number);
27560
+ const dayName = this.getDayName(new Date(gYear, gMonth - 1, gDay).getDay());
27561
+ monthArray.push({
27562
+ gD: gDate,
27563
+ uD: uDate,
27564
+ dN: dayName,
27565
+ uC: totalDays,
27566
+ });
27567
+ }
27568
+ return monthArray;
27569
+ }
27570
+ }
27571
+ }
27572
+ return null;
27573
+ }
27574
+ calculateGregorianDate(startGDate, offset) {
27575
+ const [day, month, year] = startGDate?.split('/').map(Number);
27576
+ const newDate = new Date(year, month - 1, day + offset);
27577
+ return `${newDate.getDate().toString().padStart(2, '0')}/${(newDate.getMonth() + 1)
27578
+ .toString()
27579
+ .padStart(2, '0')}/${newDate.getFullYear()}`;
27580
+ }
27581
+ calculateUmAlQurraDate(startUDate, offset, uC) {
27582
+ const [day, month, year] = startUDate?.split('/').map(Number);
27583
+ let newDay = day + offset;
27584
+ let newMonth = month;
27585
+ let newYear = year;
27586
+ while (newDay > uC) {
27587
+ newDay -= uC;
27588
+ newMonth += 1;
27589
+ }
27590
+ while (newMonth > 12) {
27591
+ newMonth = 1;
27592
+ newYear += 1;
27593
+ }
27594
+ return `${newDay.toString().padStart(2, '0')}/${newMonth
27595
+ .toString()
27596
+ .padStart(2, '0')}/${newYear}`;
27597
+ }
27598
+ getDayName(dayIndex) {
27599
+ const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
27600
+ return days[dayIndex];
27601
+ }
27602
+ /// Check date is it in past or future
27603
+ checkPastOrFuture(inputDate, targetDate) {
27604
+ if (inputDate) {
27605
+ const [day, month, year] = inputDate?.split('/').map(Number);
27606
+ const dateToCheck = new Date(year, month - 1, day);
27607
+ const today = targetDate;
27608
+ today.setHours(0, 0, 0, 0);
27609
+ if (dateToCheck > today) {
27610
+ return 'Future';
27611
+ }
27612
+ else if (dateToCheck < today) {
27613
+ return 'Past';
27614
+ }
27615
+ else {
27616
+ return 'Today';
27617
+ }
27618
+ }
27619
+ }
27620
+ /// Convert english numbers to arabic equivalent
27621
+ parseEnglish(englishNum) {
27622
+ if (!englishNum)
27623
+ return englishNum;
27624
+ const numStr = String(englishNum);
27625
+ const arabicNumbers = [
27626
+ '\u0660',
27627
+ '\u0661',
27628
+ '\u0662',
27629
+ '\u0663',
27630
+ '\u0664',
27631
+ '\u0665',
27632
+ '\u0666',
27633
+ '\u0667',
27634
+ '\u0668',
27635
+ '\u0669',
27636
+ ];
27637
+ return numStr.replace(/[0-9]/g, (digit) => {
27638
+ return arabicNumbers[Number(digit)] || digit;
27639
+ });
27640
+ }
27641
+ /// Convert arabic numbers to english equivalent
27642
+ parseArabic(arabicNum) {
27643
+ return arabicNum.replace(/[٠١٢٣٤٥٦٧٨٩]/g, function (d) {
27644
+ return d.charCodeAt(0) - 1632;
27645
+ });
27646
+ }
27647
+ ///
27648
+ convertDateNumerals(date, targetLang) {
27649
+ const arabicNumbers = ['٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩'];
27650
+ const englishNumbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
27651
+ const toArabic = (value) => value
27652
+ .split('')
27653
+ .map((char) => (/\d/.test(char) ? arabicNumbers[+char] : char))
27654
+ .join('');
27655
+ const toEnglish = (value) => value
27656
+ .split('')
27657
+ .map((char) => {
27658
+ const index = arabicNumbers.indexOf(char);
27659
+ return index > -1 ? englishNumbers[index] : char;
27660
+ })
27661
+ .join('');
27662
+ if (targetLang === 'ar') {
27663
+ const [day, month, year] = date.split('/');
27664
+ return `${toArabic(year)}/${toArabic(month)}/${toArabic(day)}`;
27665
+ }
27666
+ else {
27667
+ const [year, month, day] = date.split('/');
27668
+ return `${toEnglish(day)}/${toEnglish(month)}/${toEnglish(year)}`;
27669
+ }
27670
+ }
27671
+ /**
27672
+ * Normalize input date to DD/MM/YYYY string format (Gregorian)
27673
+ * Accepts Date object or DD/MM/YYYY string
27674
+ */
27675
+ normalizeDateToString(date) {
27676
+ if (!date)
27677
+ return null;
27678
+ if (date instanceof Date) {
27679
+ return this.formatDate(date);
27680
+ }
27681
+ // Already a string - validate format
27682
+ const parsed = this.parseDate(date);
27683
+ return parsed ? this.formatDate(parsed) : null;
27684
+ }
27685
+ /**
27686
+ * Compare two dates (Gregorian format DD/MM/YYYY)
27687
+ * Returns: -1 if date1 < date2, 0 if equal, 1 if date1 > date2
27688
+ */
27689
+ compareDates(date1Str, date2Str) {
27690
+ const d1 = this.parseDate(date1Str);
27691
+ const d2 = this.parseDate(date2Str);
27692
+ if (!d1 || !d2)
27693
+ return 0;
27694
+ if (d1 < d2)
27695
+ return -1;
27696
+ if (d1 > d2)
27697
+ return 1;
27698
+ return 0;
27699
+ }
27700
+ /**
27701
+ * Compare two Hijri dates (UM format DD/MM/YYYY)
27702
+ * Converts to Gregorian for comparison
27703
+ */
27704
+ compareHijriDates(hijri1, hijri2) {
27705
+ const day1 = this.convertDate(hijri1, false);
27706
+ const day2 = this.convertDate(hijri2, false);
27707
+ if (!day1?.gD || !day2?.gD)
27708
+ return 0;
27709
+ return this.compareDates(day1.gD, day2.gD);
27710
+ }
27711
+ /**
27712
+ * Check if a date is within the specified range (inclusive)
27713
+ * All dates in Gregorian DD/MM/YYYY format
27714
+ */
27715
+ isDateInRange(dateStr, minDateStr, maxDateStr) {
27716
+ if (!dateStr)
27717
+ return false;
27718
+ // If no constraints, date is valid
27719
+ if (!minDateStr && !maxDateStr)
27720
+ return true;
27721
+ // Check minimum constraint
27722
+ if (minDateStr && this.compareDates(dateStr, minDateStr) < 0) {
27723
+ return false;
27724
+ }
27725
+ // Check maximum constraint
27726
+ if (maxDateStr && this.compareDates(dateStr, maxDateStr) > 0) {
27727
+ return false;
27728
+ }
27729
+ return true;
27730
+ }
27731
+ /**
27732
+ * Check if a Hijri date is within the specified range
27733
+ * Converts to Gregorian for comparison
27734
+ */
27735
+ isHijriDateInRange(hijriDateStr, minDateStr, maxDateStr) {
27736
+ if (!hijriDateStr)
27737
+ return false;
27738
+ const dayInfo = this.convertDate(hijriDateStr, false);
27739
+ if (!dayInfo?.gD)
27740
+ return false;
27741
+ return this.isDateInRange(dayInfo.gD, minDateStr, maxDateStr);
27742
+ }
27743
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DateUtilitiesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
27744
+ static { thisprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DateUtilitiesService, providedIn: 'root' }); }
27745
+ }
27746
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DateUtilitiesService, decorators: [{
27747
+ type: Injectable,
27748
+ args: [{
27749
+ providedIn: 'root',
27750
+ }]
27751
+ }], ctorParameters: () => [] });
27752
27752
 
27753
27753
  var themes = [
27754
27754
  {
@@ -27908,1078 +27908,1078 @@ var themesConfig = /*#__PURE__*/Object.freeze({
27908
27908
  default: themes
27909
27909
  });
27910
27910
 
27911
- class HijriGregorianDatepickerComponent {
27912
- constructor(formBuilder, _dateUtilsService) {
27913
- this.formBuilder = formBuilder;
27914
- this._dateUtilsService = _dateUtilsService;
27915
- /// Inputs
27916
- this.markToday = true;
27917
- this.canChangeMode = true;
27918
- this.todaysDateSection = true;
27919
- this.futureValidation = true;
27920
- this.disableYearPicker = false;
27921
- this.disableMonthPicker = false;
27922
- this.disableDayPicker = false;
27923
- this.multiple = false;
27924
- this.isRequired = false;
27925
- this.showConfirmButton = true;
27926
- this.futureValidationMessage = false;
27927
- this.arabicLayout = false;
27928
- this.mode = 'greg';
27929
- this.dir = 'ltr';
27930
- this.locale = 'en';
27931
- this.submitTextButton = 'Confirm';
27932
- this.todaysDateText = "Today's Date";
27933
- this.ummAlQuraDateText = 'Hijri Date';
27934
- this.monthSelectLabel = 'Month';
27935
- this.yearSelectLabel = 'Year';
27936
- this.theme = '';
27937
- this.pastYearsLimit = 90;
27938
- this.futureYearsLimit = 0;
27939
- this.styles = {};
27940
- // New inputs for extended functionality
27941
- this.enableTime = false; // Enable time picker (hours & minutes)
27942
- // BACKWARD COMPATIBILITY: Default to false (24-hour format)
27943
- // When true, displays 12-hour format with AM/PM toggle
27944
- this.useMeridian = false; // Enable 12-hour format with AM/PM
27945
- // BACKWARD COMPATIBILITY: Default to 'single' (existing behavior)
27946
- // 'range' enables range selection mode (first click = start, second click = end)
27947
- this.selectionMode = 'single';
27948
- /// Outputs
27949
- this.onSubmit = new EventEmitter();
27950
- this.onDaySelect = new EventEmitter();
27951
- this.onMonthChange = new EventEmitter();
27952
- this.onYearChange = new EventEmitter();
27953
- /// Variables
27954
- this.ummAlQuraMonths = [
27955
- { labelAr: 'محرم', labelEn: 'Muharram', value: 1 },
27956
- { labelAr: 'صفر', labelEn: 'Safar', value: 2 },
27957
- { labelAr: 'ربيع الأول', labelEn: 'Rabi al-Awwal', value: 3 },
27958
- { labelAr: 'ربيع الثاني', labelEn: 'Rabi al-Thani', value: 4 },
27959
- { labelAr: 'جمادى الأولى', labelEn: 'Jumada al-Awwal', value: 5 },
27960
- { labelAr: 'جمادى الآخرة', labelEn: 'Jumada al-Thani', value: 6 },
27961
- { labelAr: 'رجب', labelEn: 'Rajab', value: 7 },
27962
- { labelAr: 'شعبان', labelEn: 'Shaban', value: 8 },
27963
- { labelAr: 'رمضان', labelEn: 'Ramadan', value: 9 },
27964
- { labelAr: 'شوال', labelEn: 'Shawwal', value: 10 },
27965
- { labelAr: 'ذو القعدة', labelEn: 'Dhu al-Qadah', value: 11 },
27966
- { labelAr: 'ذو الحجة', labelEn: 'Dhu al-Hijjah', value: 12 },
27967
- ];
27968
- this.gregMonths = [
27969
- { labelAr: 'يناير', labelEn: 'January', value: 1 },
27970
- { labelAr: 'فبراير', labelEn: 'February', value: 2 },
27971
- { labelAr: 'مارس', labelEn: 'March', value: 3 },
27972
- { labelAr: 'ابريل', labelEn: 'April', value: 4 },
27973
- { labelAr: 'مايو', labelEn: 'May', value: 5 },
27974
- { labelAr: 'يونيو', labelEn: 'June', value: 6 },
27975
- { labelAr: 'يوليو', labelEn: 'July', value: 7 },
27976
- { labelAr: 'اغسطس', labelEn: 'August', value: 8 },
27977
- { labelAr: 'سبتمبر', labelEn: 'September', value: 9 },
27978
- { labelAr: 'اكتوبر', labelEn: 'October', value: 10 },
27979
- { labelAr: 'نوفمبر', labelEn: 'November', value: 11 },
27980
- { labelAr: 'ديسمبر', labelEn: 'December', value: 12 },
27981
- ];
27982
- this.weekdaysEn = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
27983
- this.weekdaysAr = ['سبت', 'جمعة', 'خميس', 'أربعاء', 'ثلاثاء', 'اثنين', 'أحد'];
27984
- // weekdaysAr = ['س', 'ج', 'خ', 'أر', 'ث', 'إث', 'أح'];
27985
- this.todaysDate = {};
27986
- this.multipleSelectedDates = [];
27987
- this.themes = [];
27988
- // Time picker variables
27989
- // BACKWARD COMPATIBILITY: selectedTime defaults to 0:0 to preserve existing behavior when enableTime=false
27990
- // When enableTime=true, this will be initialized to current system time in ngOnInit
27991
- this.selectedTime = { hour: 0, minute: 0 };
27992
- // Track if time has been initialized to avoid re-initializing at midnight
27993
- this.timeInitialized = false;
27994
- // BACKWARD COMPATIBILITY: Meridian only used when useMeridian=true
27995
- // Tracks AM/PM state for 12-hour format
27996
- this.meridian = 'AM';
27997
- // Range selection state
27998
- // BACKWARD COMPATIBILITY: These are only used when selectionMode='range'
27999
- // They do not affect single or multiple selection modes
28000
- this.rangeStart = undefined;
28001
- this.rangeEnd = undefined;
28002
- }
28003
- ngOnInit() {
28004
- this.initTheme();
28005
- this.initializeForm();
28006
- this.getTodaysDateInfo();
28007
- this.initializeYearsAndMonths();
28008
- // Initialize time from current system time or initialDate
28009
- // BACKWARD COMPATIBILITY: This only runs when enableTime=true
28010
- if (this.enableTime) {
28011
- this.initializeTime();
28012
- }
28013
- }
28014
- ngAfterViewInit() {
28015
- // Double-check time initialization after view is ready
28016
- // This handles cases where enableTime might be set after ngOnInit
28017
- if (this.enableTime && !this.timeInitialized) {
28018
- this.initializeTime();
28019
- }
28020
- }
28021
- ngOnChanges(changes) {
28022
- if (!changes['mode'].isFirstChange()) {
28023
- this.changeCalendarMode();
28024
- }
28025
- }
28026
- initTheme() {
28027
- if (this.theme != '') {
28028
- this.themes = themesConfig;
28029
- for (const themeItem of this.themes['default']) {
28030
- if (themeItem.name == this.theme) {
28031
- this.styles = themeItem.stylesConfig;
28032
- break;
28033
- }
28034
- }
28035
- }
28036
- this.fontFamilyStyle = this.styles.fontFamily;
28037
- }
28038
- /// Initialize form control for month and year select
28039
- initializeForm() {
28040
- this.periodForm = this.formBuilder.group({
28041
- year: [{ value: '', disabled: this.disableYearPicker }, []],
28042
- month: [{ value: '', disabled: this.disableMonthPicker }, []],
28043
- });
28044
- }
28045
- // Initialize years and months for calendar
28046
- initializeYearsAndMonths() {
28047
- this.years = [];
28048
- this.months = [];
28049
- // Determine the date to use for initialization (initialDate or today)
28050
- let referenceDate;
28051
- if (this.initialDate) {
28052
- const normalizedInitialDate = this._dateUtilsService.normalizeDateToString(this.initialDate);
28053
- if (normalizedInitialDate) {
28054
- if (this.mode == 'greg') {
28055
- referenceDate = normalizedInitialDate;
28056
- }
28057
- else {
28058
- const hijriDate = this._dateUtilsService.convertDate(normalizedInitialDate, true);
28059
- referenceDate = hijriDate?.uD || this.todaysDate.ummAlQura;
28060
- }
28061
- }
28062
- else {
28063
- referenceDate =
28064
- this.mode == 'greg'
28065
- ? this.todaysDate.gregorian
28066
- : this.todaysDate.ummAlQura;
28067
- }
28068
- }
28069
- else {
28070
- referenceDate =
28071
- this.mode == 'greg'
28072
- ? this.todaysDate.gregorian
28073
- : this.todaysDate.ummAlQura;
28074
- }
28075
- if (this.mode == 'greg') {
28076
- this.gregYear =
28077
- this.futureYearsLimit == 0
28078
- ? Number(referenceDate?.split('/')[2])
28079
- : Number(referenceDate?.split('/')[2]) + this.futureYearsLimit;
28080
- for (let i = 0; i < this.gregYear; i++) {
28081
- if (i < this.pastYearsLimit) {
28082
- let val = this.gregYear--;
28083
- this.years.push(val);
28084
- }
28085
- else {
28086
- break;
28087
- }
28088
- }
28089
- this.months = this.gregMonths;
28090
- }
28091
- else {
28092
- this.ummAlQuraYear =
28093
- this.futureYearsLimit == 0
28094
- ? Number(referenceDate?.split('/')[2])
28095
- : Number(referenceDate?.split('/')[2]) + this.futureYearsLimit;
28096
- for (let i = 0; i < this.ummAlQuraYear; i++) {
28097
- if (i < this.pastYearsLimit) {
28098
- let val = this.ummAlQuraYear--;
28099
- this.years.push(val);
28100
- }
28101
- else {
28102
- break;
28103
- }
28104
- }
28105
- this.months = this.ummAlQuraMonths;
28106
- }
28107
- this.years.map((year) => {
28108
- if (year == referenceDate?.split('/')[2]) {
28109
- this.periodForm.controls['year'].setValue(year);
28110
- }
28111
- });
28112
- this.months.map((month) => {
28113
- if (month.value == referenceDate?.split('/')[1]) {
28114
- this.periodForm.controls['month'].setValue(month.value);
28115
- }
28116
- });
28117
- }
28118
- /// On change event of years and months
28119
- onPeriodChange(type) {
28120
- if (type == 'year') {
28121
- this.onYearChange.emit(this.periodForm.controls['year'].value);
28122
- }
28123
- else {
28124
- this.onMonthChange.emit(this.periodForm.controls['month'].value);
28125
- }
28126
- const days = this._dateUtilsService.getMonthData('01/' +
28127
- this.periodForm.controls['month'].value +
28128
- '/' +
28129
- this.periodForm.controls['year'].value, this.mode);
28130
- this.weeks = this.generateWeeksArray(days);
28131
- }
28132
- /// Get todays(greg and umm al qura) date info
28133
- getTodaysDateInfo() {
28134
- this.todaysDate.gregorian = this._dateUtilsService.formatDate(new Date());
28135
- this.todaysDate.ummAlQura = this._dateUtilsService.convertDate(this.todaysDate.gregorian, true)?.uD;
28136
- // Use initialDate if provided, otherwise use today's date
28137
- let dateToNavigate;
28138
- if (this.initialDate) {
28139
- // Normalize initialDate to DD/MM/YYYY format
28140
- const normalizedInitialDate = this._dateUtilsService.normalizeDateToString(this.initialDate);
28141
- if (normalizedInitialDate) {
28142
- if (this.mode == 'greg') {
28143
- dateToNavigate = normalizedInitialDate;
28144
- }
28145
- else {
28146
- // Convert to Hijri for ummAlQura mode
28147
- const hijriDate = this._dateUtilsService.convertDate(normalizedInitialDate, true);
28148
- dateToNavigate = hijriDate?.uD || this.todaysDate.ummAlQura;
28149
- }
28150
- }
28151
- else {
28152
- // Invalid initialDate, fall back to today
28153
- dateToNavigate =
28154
- this.mode == 'greg'
28155
- ? this.todaysDate.gregorian
28156
- : this.todaysDate.ummAlQura;
28157
- }
28158
- }
28159
- else {
28160
- // No initialDate provided, use today
28161
- dateToNavigate =
28162
- this.mode == 'greg'
28163
- ? this.todaysDate.gregorian
28164
- : this.todaysDate.ummAlQura;
28165
- }
28166
- this.generatetMonthData(dateToNavigate);
28167
- // Highlight initialDate or initialRange if provided
28168
- if (this.selectionMode === 'range' && (this.initialRangeStart || this.initialRangeEnd)) {
28169
- this.highlightInitialRange();
28170
- }
28171
- else if (this.initialDate) {
28172
- this.highlightInitialDate();
28173
- }
28174
- }
28175
- /// Generate month days from JSON
28176
- generatetMonthData(date) {
28177
- const days = this._dateUtilsService.getMonthData(date, this.mode);
28178
- this.weeks = this.generateWeeksArray(days);
28179
- }
28180
- /// Highlight initialDate on the calendar
28181
- highlightInitialDate() {
28182
- if (!this.initialDate) {
28183
- return;
28184
- }
28185
- const normalizedInitialDate = this._dateUtilsService.normalizeDateToString(this.initialDate);
28186
- if (!normalizedInitialDate) {
28187
- return;
28188
- }
28189
- // Find the day in the weeks array that matches initialDate
28190
- for (const week of this.weeks) {
28191
- for (const day of week) {
28192
- if (day && day.gD === normalizedInitialDate) {
28193
- // Don't select if date is disabled
28194
- if (!this.isDateDisabled(day)) {
28195
- // Mark as selected without triggering events
28196
- day.selected = true;
28197
- // Set as selectedDay based on selection mode
28198
- if (this.selectionMode === 'range') {
28199
- this.rangeStart = day;
28200
- }
28201
- else if (this.multiple) {
28202
- this.multipleSelectedDates = [day];
28203
- }
28204
- else {
28205
- this.selectedDay = day;
28206
- }
28207
- // Initialize time if enableTime is active
28208
- if (this.enableTime && !this.timeInitialized) {
28209
- this.initializeTime();
28210
- }
28211
- // Attach time to the day if it's a Date object with time
28212
- if (this.enableTime && this.initialDate instanceof Date) {
28213
- day.time = {
28214
- hour: this.initialDate.getHours(),
28215
- minute: this.initialDate.getMinutes()
28216
- };
28217
- }
28218
- }
28219
- return;
28220
- }
28221
- }
28222
- }
28223
- }
28224
- /// Highlight initial range (start and end dates) on the calendar
28225
- highlightInitialRange() {
28226
- if (!this.initialRangeStart && !this.initialRangeEnd) {
28227
- return;
28228
- }
28229
- const normalizedStartDate = this.initialRangeStart
28230
- ? this._dateUtilsService.normalizeDateToString(this.initialRangeStart)
28231
- : null;
28232
- const normalizedEndDate = this.initialRangeEnd
28233
- ? this._dateUtilsService.normalizeDateToString(this.initialRangeEnd)
28234
- : null;
28235
- let startDay = null;
28236
- let endDay = null;
28237
- // Find both start and end dates in the weeks array
28238
- for (const week of this.weeks) {
28239
- for (const day of week) {
28240
- if (day && normalizedStartDate && day.gD === normalizedStartDate) {
28241
- if (!this.isDateDisabled(day)) {
28242
- startDay = day;
28243
- }
28244
- }
28245
- if (day && normalizedEndDate && day.gD === normalizedEndDate) {
28246
- if (!this.isDateDisabled(day)) {
28247
- endDay = day;
28248
- }
28249
- }
28250
- }
28251
- }
28252
- // Set range start
28253
- if (startDay) {
28254
- startDay.selected = true;
28255
- this.rangeStart = startDay;
28256
- this.selectedDay = startDay;
28257
- // Initialize and attach time to start date
28258
- if (this.enableTime) {
28259
- if (!this.timeInitialized) {
28260
- this.initializeTime();
28261
- }
28262
- if (this.initialRangeStart instanceof Date) {
28263
- startDay.time = {
28264
- hour: this.initialRangeStart.getHours(),
28265
- minute: this.initialRangeStart.getMinutes()
28266
- };
28267
- }
28268
- else {
28269
- startDay.time = { ...this.selectedTime };
28270
- }
28271
- }
28272
- }
28273
- // Set range end if provided
28274
- if (endDay && startDay) {
28275
- // Swap if end is before start
28276
- const startDate = this.parseDateString(startDay.gD);
28277
- const endDate = this.parseDateString(endDay.gD);
28278
- if (endDate && startDate && endDate < startDate) {
28279
- // Swap
28280
- this.rangeEnd = startDay;
28281
- this.rangeStart = endDay;
28282
- endDay.selected = true;
28283
- }
28284
- else {
28285
- this.rangeEnd = endDay;
28286
- }
28287
- // Attach time to end date (inherit from start)
28288
- if (this.enableTime) {
28289
- const timeToUse = this.rangeStart.time || { ...this.selectedTime };
28290
- if (this.initialRangeEnd instanceof Date) {
28291
- this.rangeEnd.time = {
28292
- hour: this.initialRangeEnd.getHours(),
28293
- minute: this.initialRangeEnd.getMinutes()
28294
- };
28295
- }
28296
- else {
28297
- this.rangeEnd.time = { ...timeToUse };
28298
- }
28299
- // Ensure start also has time
28300
- this.rangeStart.time = { ...timeToUse };
28301
- }
28302
- // Highlight the range
28303
- this.highlightRange();
28304
- this.selectedDay = this.rangeEnd;
28305
- }
28306
- }
28307
- /// Generate month weeks
28308
- generateWeeksArray(daysArray) {
28309
- const firstDayName = daysArray[0]?.dN;
28310
- const startIndex = this.weekdaysEn.indexOf(firstDayName);
28311
- const weeks = [[]];
28312
- let currentWeek = 0;
28313
- let currentDayIndex = startIndex;
28314
- daysArray?.forEach((day) => {
28315
- if (!weeks[currentWeek]) {
28316
- weeks[currentWeek] = [];
28317
- }
28318
- weeks[currentWeek][currentDayIndex] = day;
28319
- currentDayIndex++;
28320
- if (currentDayIndex === 7) {
28321
- currentDayIndex = 0;
28322
- currentWeek++;
28323
- }
28324
- });
28325
- weeks.forEach((week) => {
28326
- while (week.length < 7) {
28327
- week.push({});
28328
- }
28329
- });
28330
- return weeks;
28331
- }
28332
- /// Change calendar mode 'greg' or 'ummAlQura'
28333
- changeCalendarMode() {
28334
- this.mode = this.mode == 'greg' ? 'ummAlQura' : 'greg';
28335
- this.initializeYearsAndMonths();
28336
- this.generatetMonthData('01/' +
28337
- this.periodForm.controls['month'].value +
28338
- '/' +
28339
- this.periodForm.controls['year'].value);
28340
- }
28341
- /// On day clicked handler
28342
- onDayClicked(day) {
28343
- if (day && day?.gD) {
28344
- // Check if day is disabled by min/max constraints
28345
- if (this.isDateDisabled(day)) {
28346
- return; // Don't allow selection of disabled dates
28347
- }
28348
- if (this.futureValidation) {
28349
- if (this.checkFutureValidation(day)) {
28350
- this.futureValidationMessage = true;
28351
- }
28352
- else {
28353
- this.futureValidationMessage = false;
28354
- this.markDaySelected(day);
28355
- }
28356
- }
28357
- else {
28358
- this.markDaySelected(day);
28359
- }
28360
- }
28361
- }
28362
- /// Mark day as selected
28363
- markDaySelected(dayInfo) {
28364
- // BACKWARD COMPATIBILITY: Range selection only when selectionMode='range'
28365
- if (this.selectionMode === 'range') {
28366
- this.handleRangeSelection(dayInfo);
28367
- return;
28368
- }
28369
- // BACKWARD COMPATIBILITY: Original behavior for single/multiple selection
28370
- if (dayInfo.selected) {
28371
- dayInfo.selected = false;
28372
- this.multipleSelectedDates = this.multipleSelectedDates.filter((day) => day !== dayInfo);
28373
- if (!this.multiple) {
28374
- this.selectedDay = undefined;
28375
- }
28376
- }
28377
- else {
28378
- if (!this.multiple) {
28379
- this.weeks.forEach((week) => {
28380
- week.forEach((day) => {
28381
- day.selected = false;
28382
- });
28383
- });
28384
- dayInfo.selected = true;
28385
- this.selectedDay = dayInfo;
28386
- this.multipleSelectedDates = [dayInfo];
28387
- // Attach current time if enableTime is active
28388
- if (this.enableTime) {
28389
- // Ensure time is initialized before attaching
28390
- if (!this.timeInitialized) {
28391
- this.initializeTime();
28392
- }
28393
- dayInfo.time = { ...this.selectedTime };
28394
- }
28395
- this.onDaySelect.emit(dayInfo);
28396
- }
28397
- else {
28398
- dayInfo.selected = true;
28399
- // Attach current time if enableTime is active
28400
- if (this.enableTime) {
28401
- // Ensure time is initialized before attaching
28402
- if (!this.timeInitialized) {
28403
- this.initializeTime();
28404
- }
28405
- dayInfo.time = { ...this.selectedTime };
28406
- }
28407
- this.onDaySelect.emit(dayInfo);
28408
- if (!this.multipleSelectedDates.includes(dayInfo)) {
28409
- this.multipleSelectedDates.push(dayInfo);
28410
- }
28411
- }
28412
- }
28413
- }
28414
- /**
28415
- * Handle range selection logic
28416
- * BACKWARD COMPATIBILITY: Only called when selectionMode='range'
28417
- *
28418
- * Range selection lifecycle:
28419
- * 1. First click → Sets rangeStart
28420
- * 2. Second click → Sets rangeEnd, highlights range
28421
- * 3. Third click → Resets range, starts new selection
28422
- */
28423
- handleRangeSelection(dayInfo) {
28424
- // First click or resetting range
28425
- if (!this.rangeStart || (this.rangeStart && this.rangeEnd)) {
28426
- this.resetRange();
28427
- this.rangeStart = dayInfo;
28428
- dayInfo.selected = true;
28429
- this.selectedDay = dayInfo;
28430
- // Attach current time if enableTime is active
28431
- if (this.enableTime) {
28432
- // Ensure selectedTime is initialized
28433
- // If time hasn't been initialized yet, initialize it now
28434
- if (!this.timeInitialized) {
28435
- this.initializeTime();
28436
- }
28437
- dayInfo.time = { ...this.selectedTime };
28438
- }
28439
- this.onDaySelect.emit({ start: dayInfo, end: null });
28440
- }
28441
- // Second click - complete the range
28442
- else if (this.rangeStart && !this.rangeEnd) {
28443
- const startDate = this.parseDateString(this.rangeStart.gD);
28444
- const endDate = this.parseDateString(dayInfo.gD);
28445
- // Swap if end is before start
28446
- if (endDate && startDate && endDate < startDate) {
28447
- this.rangeEnd = this.rangeStart;
28448
- this.rangeStart = dayInfo;
28449
- }
28450
- else {
28451
- this.rangeEnd = dayInfo;
28452
- }
28453
- // Attach time if enableTime is active
28454
- // IMPORTANT: Range end inherits time from range start (not current selectedTime)
28455
- if (this.enableTime) {
28456
- // Use rangeStart's time if it exists, otherwise use current selectedTime
28457
- const timeToUse = this.rangeStart.time || { ...this.selectedTime };
28458
- this.rangeStart.time = { ...timeToUse };
28459
- this.rangeEnd.time = { ...timeToUse };
28460
- }
28461
- this.highlightRange();
28462
- this.selectedDay = this.rangeEnd;
28463
- this.onDaySelect.emit({ start: this.rangeStart, end: this.rangeEnd });
28464
- }
28465
- }
28466
- /// On confirm button clicked
28467
- onConfirmClicked() {
28468
- // BACKWARD COMPATIBILITY: Range selection output when selectionMode='range'
28469
- if (this.selectionMode === 'range') {
28470
- if (this.rangeStart && this.rangeEnd) {
28471
- // Collect all dates in range
28472
- const rangeDates = [];
28473
- this.weeks.forEach((week) => {
28474
- week.forEach((day) => {
28475
- if (day && day.gD && (this.isInRange(day) || this.isRangeStart(day) || this.isRangeEnd(day))) {
28476
- // Attach current time if enableTime is active
28477
- if (this.enableTime && !day.time) {
28478
- day.time = { ...this.selectedTime };
28479
- }
28480
- rangeDates.push(day);
28481
- }
28482
- });
28483
- });
28484
- this.onSubmit.emit({
28485
- start: this.rangeStart,
28486
- end: this.rangeEnd,
28487
- dates: rangeDates
28488
- });
28489
- }
28490
- else {
28491
- // Incomplete range
28492
- this.onSubmit.emit({ start: this.rangeStart, end: null, dates: [] });
28493
- }
28494
- return;
28495
- }
28496
- // BACKWARD COMPATIBILITY: Original behavior for multiple/single selection
28497
- if (this.multiple) {
28498
- // For multiple dates, attach time to each if enableTime is active
28499
- if (this.enableTime) {
28500
- this.multipleSelectedDates.forEach((day) => {
28501
- if (!day.time) {
28502
- day.time = { ...this.selectedTime };
28503
- }
28504
- });
28505
- }
28506
- this.onSubmit.emit(this.multipleSelectedDates);
28507
- }
28508
- else {
28509
- // For single date, attach time if enableTime is active
28510
- if (this.enableTime && this.selectedDay) {
28511
- this.selectedDay.time = { ...this.selectedTime };
28512
- }
28513
- this.onSubmit.emit(this.selectedDay);
28514
- }
28515
- }
28516
- /// Check if date from future
28517
- checkFutureValidation(day) {
28518
- if (this._dateUtilsService.checkPastOrFuture(day?.gD, new Date()) == 'Future') {
28519
- return true;
28520
- }
28521
- }
28522
- /// Check if passed day is today or not
28523
- checkTodaysDate(day) {
28524
- return (this.todaysDate?.gregorian == day?.gD ||
28525
- this.todaysDate?.ummAlQura == day?.uD);
28526
- }
28527
- /**
28528
- * Check if a day is disabled based on min/max date constraints
28529
- * Works for both Gregorian and Hijri modes
28530
- */
28531
- isDateDisabled(day) {
28532
- if (!day || !day.gD)
28533
- return true;
28534
- // Normalize min/max dates to Gregorian DD/MM/YYYY format
28535
- const minDateStr = this.minDate
28536
- ? this._dateUtilsService.normalizeDateToString(this.minDate)
28537
- : null;
28538
- const maxDateStr = this.maxDate
28539
- ? this._dateUtilsService.normalizeDateToString(this.maxDate)
28540
- : null;
28541
- // Check if the day's Gregorian date is within range
28542
- return !this._dateUtilsService.isDateInRange(day.gD, minDateStr, maxDateStr);
28543
- }
28544
- /**
28545
- * Initialize time from current system time or initialDate
28546
- * BACKWARD COMPATIBILITY: Only called when enableTime=true
28547
- *
28548
- * Priority:
28549
- * 1. If initialDate has time, use that
28550
- * 2. If selectedDay has time, use that
28551
- * 3. Otherwise, use current system time
28552
- */
28553
- initializeTime() {
28554
- let timeSet = false;
28555
- // Check if initialDate has time information
28556
- if (this.initialDate && this.initialDate instanceof Date) {
28557
- this.selectedTime = {
28558
- hour: this.initialDate.getHours(),
28559
- minute: this.initialDate.getMinutes(),
28560
- };
28561
- timeSet = true;
28562
- }
28563
- // If no time from initialDate, use current system time
28564
- if (!timeSet) {
28565
- const now = new Date();
28566
- this.selectedTime = {
28567
- hour: now.getHours(),
28568
- minute: now.getMinutes(),
28569
- };
28570
- }
28571
- // Mark that time has been initialized
28572
- this.timeInitialized = true;
28573
- // BACKWARD COMPATIBILITY: Only set meridian when useMeridian=true
28574
- if (this.useMeridian) {
28575
- this.meridian = this.selectedTime.hour >= 12 ? 'PM' : 'AM';
28576
- }
28577
- }
28578
- /**
28579
- * Increment hour value with wraparound (0-23)
28580
- * BACKWARD COMPATIBILITY: Only available when enableTime=true
28581
- */
28582
- incrementHour() {
28583
- this.selectedTime.hour = (this.selectedTime.hour + 1) % 24;
28584
- this.updateSelectedDayTime();
28585
- }
28586
- /**
28587
- * Decrement hour value with wraparound (0-23)
28588
- * BACKWARD COMPATIBILITY: Only available when enableTime=true
28589
- */
28590
- decrementHour() {
28591
- this.selectedTime.hour = (this.selectedTime.hour - 1 + 24) % 24;
28592
- this.updateSelectedDayTime();
28593
- }
28594
- /**
28595
- * Increment minute value with wraparound (0-59)
28596
- * BACKWARD COMPATIBILITY: Only available when enableTime=true
28597
- */
28598
- incrementMinute() {
28599
- this.selectedTime.minute = (this.selectedTime.minute + 1) % 60;
28600
- this.updateSelectedDayTime();
28601
- }
28602
- /**
28603
- * Decrement minute value with wraparound (0-59)
28604
- * BACKWARD COMPATIBILITY: Only available when enableTime=true
28605
- */
28606
- decrementMinute() {
28607
- this.selectedTime.minute = (this.selectedTime.minute - 1 + 60) % 60;
28608
- this.updateSelectedDayTime();
28609
- }
28610
- /**
28611
- * Handle keyboard input for hours
28612
- * Validates and clamps to 0-23 range
28613
- * BACKWARD COMPATIBILITY: Only available when enableTime=true
28614
- */
28615
- onHourInputChange(event) {
28616
- let value = parseInt(event.target.value, 10);
28617
- if (isNaN(value) || value < 0) {
28618
- value = 0;
28619
- }
28620
- else if (value > 23) {
28621
- value = 23;
28622
- }
28623
- this.selectedTime.hour = value;
28624
- event.target.value = value;
28625
- this.updateSelectedDayTime();
28626
- }
28627
- /**
28628
- * Handle keyboard input for minutes
28629
- * Validates and clamps to 0-59 range
28630
- * BACKWARD COMPATIBILITY: Only available when enableTime=true
28631
- */
28632
- onMinuteInputChange(event) {
28633
- let value = parseInt(event.target.value, 10);
28634
- if (isNaN(value) || value < 0) {
28635
- value = 0;
28636
- }
28637
- else if (value > 59) {
28638
- value = 59;
28639
- }
28640
- this.selectedTime.minute = value;
28641
- event.target.value = value;
28642
- this.updateSelectedDayTime();
28643
- }
28644
- /**
28645
- * Handle keyboard arrow keys for hour/minute input
28646
- * BACKWARD COMPATIBILITY: Only available when enableTime=true
28647
- */
28648
- onTimeKeydown(event, type) {
28649
- if (event.key === 'ArrowUp') {
28650
- event.preventDefault();
28651
- if (type === 'hour') {
28652
- this.incrementHour();
28653
- }
28654
- else {
28655
- this.incrementMinute();
28656
- }
28657
- }
28658
- else if (event.key === 'ArrowDown') {
28659
- event.preventDefault();
28660
- if (type === 'hour') {
28661
- this.decrementHour();
28662
- }
28663
- else {
28664
- this.decrementMinute();
28665
- }
28666
- }
28667
- }
28668
- /**
28669
- * Update the selected day's time property when time changes
28670
- * BACKWARD COMPATIBILITY: Only called when enableTime=true
28671
- */
28672
- updateSelectedDayTime() {
28673
- if (this.selectedDay) {
28674
- this.selectedDay.time = { ...this.selectedTime };
28675
- }
28676
- }
28677
- /**
28678
- * Get display hour for 12-hour format
28679
- * BACKWARD COMPATIBILITY: Only used when useMeridian=true
28680
- *
28681
- * Conversion:
28682
- * - 0 (midnight) → 12 AM
28683
- * - 1-11 (AM) → 1-11 AM
28684
- * - 12 (noon) → 12 PM
28685
- * - 13-23 (PM) → 1-11 PM
28686
- *
28687
- * IMPORTANT: Hour 0 is NEVER displayed as 0, always as 12
28688
- */
28689
- getDisplayHour() {
28690
- if (!this.useMeridian) {
28691
- return this.selectedTime.hour;
28692
- }
28693
- const hour = this.selectedTime.hour;
28694
- // Midnight (0) → 12
28695
- if (hour === 0) {
28696
- return 12;
28697
- }
28698
- // 1-12 → 1-12 (no change)
28699
- else if (hour <= 12) {
28700
- return hour;
28701
- }
28702
- // 13-23 → 1-11 (subtract 12)
28703
- else {
28704
- return hour - 12;
28705
- }
28706
- }
28707
- /**
28708
- * Toggle AM/PM meridian
28709
- * BACKWARD COMPATIBILITY: Only available when useMeridian=true
28710
- *
28711
- * When toggling:
28712
- * - Adds or subtracts 12 hours
28713
- * - Maintains internal 24-hour format
28714
- */
28715
- toggleMeridian() {
28716
- if (this.meridian === 'AM') {
28717
- this.meridian = 'PM';
28718
- // Add 12 hours if not already in PM range
28719
- if (this.selectedTime.hour < 12) {
28720
- this.selectedTime.hour += 12;
28721
- }
28722
- }
28723
- else {
28724
- this.meridian = 'AM';
28725
- // Subtract 12 hours if in PM range
28726
- if (this.selectedTime.hour >= 12) {
28727
- this.selectedTime.hour -= 12;
28728
- }
28729
- }
28730
- this.updateSelectedDayTime();
28731
- }
28732
- /**
28733
- * Increment hour in 12-hour mode
28734
- * BACKWARD COMPATIBILITY: Only used when useMeridian=true
28735
- */
28736
- incrementHour12() {
28737
- let displayHour = this.getDisplayHour();
28738
- displayHour = (displayHour % 12) + 1; // 1-12 cycle
28739
- // Convert back to 24-hour format
28740
- if (this.meridian === 'AM') {
28741
- this.selectedTime.hour = displayHour === 12 ? 0 : displayHour;
28742
- }
28743
- else {
28744
- this.selectedTime.hour = displayHour === 12 ? 12 : displayHour + 12;
28745
- }
28746
- this.updateSelectedDayTime();
28747
- }
28748
- /**
28749
- * Decrement hour in 12-hour mode
28750
- * BACKWARD COMPATIBILITY: Only used when useMeridian=true
28751
- */
28752
- decrementHour12() {
28753
- let displayHour = this.getDisplayHour();
28754
- displayHour = displayHour === 1 ? 12 : displayHour - 1; // 1-12 cycle
28755
- // Convert back to 24-hour format
28756
- if (this.meridian === 'AM') {
28757
- this.selectedTime.hour = displayHour === 12 ? 0 : displayHour;
28758
- }
28759
- else {
28760
- this.selectedTime.hour = displayHour === 12 ? 12 : displayHour + 12;
28761
- }
28762
- this.updateSelectedDayTime();
28763
- }
28764
- /**
28765
- * Handle 12-hour input change
28766
- * BACKWARD COMPATIBILITY: Only used when useMeridian=true
28767
- *
28768
- * IMPORTANT: Input must be 1-12, never 0
28769
- * - User types 0 → converted to 12
28770
- * - User types > 12 → clamped to 12
28771
- */
28772
- onHour12InputChange(event) {
28773
- let value = parseInt(event.target.value, 10);
28774
- // Validate 1-12 range (0 is not allowed in 12-hour format)
28775
- if (isNaN(value) || value < 1 || value === 0) {
28776
- value = 12; // Default to 12 if invalid or 0
28777
- }
28778
- else if (value > 12) {
28779
- value = 12;
28780
- }
28781
- // Convert to 24-hour format
28782
- if (this.meridian === 'AM') {
28783
- this.selectedTime.hour = value === 12 ? 0 : value;
28784
- }
28785
- else {
28786
- this.selectedTime.hour = value === 12 ? 12 : value + 12;
28787
- }
28788
- event.target.value = value;
28789
- this.updateSelectedDayTime();
28790
- }
28791
- /**
28792
- * Check if a date is within the current range
28793
- * BACKWARD COMPATIBILITY: Only used when selectionMode='range'
28794
- */
28795
- isInRange(day) {
28796
- if (this.selectionMode !== 'range' || !this.rangeStart || !this.rangeEnd || !day?.gD) {
28797
- return false;
28798
- }
28799
- const dayDate = this.parseDateString(day.gD);
28800
- const startDate = this.parseDateString(this.rangeStart.gD);
28801
- const endDate = this.parseDateString(this.rangeEnd.gD);
28802
- if (!dayDate || !startDate || !endDate) {
28803
- return false;
28804
- }
28805
- return dayDate >= startDate && dayDate <= endDate;
28806
- }
28807
- /**
28808
- * Check if a date is the range start
28809
- * BACKWARD COMPATIBILITY: Only used when selectionMode='range'
28810
- */
28811
- isRangeStart(day) {
28812
- return this.selectionMode === 'range' &&
28813
- this.rangeStart?.gD === day?.gD;
28814
- }
28815
- /**
28816
- * Check if a date is the range end
28817
- * BACKWARD COMPATIBILITY: Only used when selectionMode='range'
28818
- */
28819
- isRangeEnd(day) {
28820
- return this.selectionMode === 'range' &&
28821
- this.rangeEnd?.gD === day?.gD;
28822
- }
28823
- /**
28824
- * Reset range selection
28825
- * BACKWARD COMPATIBILITY: Only used when selectionMode='range'
28826
- */
28827
- resetRange() {
28828
- if (this.selectionMode !== 'range') {
28829
- return;
28830
- }
28831
- // Clear range highlighting
28832
- this.weeks.forEach((week) => {
28833
- week.forEach((day) => {
28834
- if (day && day.gD) {
28835
- day.selected = false;
28836
- }
28837
- });
28838
- });
28839
- this.rangeStart = undefined;
28840
- this.rangeEnd = undefined;
28841
- this.selectedDay = undefined;
28842
- }
28843
- /**
28844
- * Parse date string (DD/MM/YYYY) to Date object
28845
- * Helper for range comparison
28846
- */
28847
- parseDateString(dateStr) {
28848
- if (!dateStr)
28849
- return null;
28850
- const parts = dateStr.split('/');
28851
- if (parts.length !== 3)
28852
- return null;
28853
- const day = parseInt(parts[0], 10);
28854
- const month = parseInt(parts[1], 10) - 1; // Month is 0-indexed
28855
- const year = parseInt(parts[2], 10);
28856
- return new Date(year, month, day);
28857
- }
28858
- /**
28859
- * Highlight all dates in range
28860
- * BACKWARD COMPATIBILITY: Only used when selectionMode='range'
28861
- */
28862
- highlightRange() {
28863
- if (this.selectionMode !== 'range' || !this.rangeStart || !this.rangeEnd) {
28864
- return;
28865
- }
28866
- this.weeks.forEach((week) => {
28867
- week.forEach((day) => {
28868
- if (day && day.gD) {
28869
- day.selected = this.isInRange(day) ||
28870
- this.isRangeStart(day) ||
28871
- this.isRangeEnd(day);
28872
- }
28873
- });
28874
- });
28875
- }
28876
- }
28877
- HijriGregorianDatepickerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: HijriGregorianDatepickerComponent, deps: [{ token: i1.UntypedFormBuilder }, { token: DateUtilitiesService }], target: i0.ɵɵFactoryTarget.Component });
28878
- HijriGregorianDatepickerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: HijriGregorianDatepickerComponent, selector: "hijri-gregorian-datepicker", inputs: { markToday: "markToday", canChangeMode: "canChangeMode", todaysDateSection: "todaysDateSection", futureValidation: "futureValidation", disableYearPicker: "disableYearPicker", disableMonthPicker: "disableMonthPicker", disableDayPicker: "disableDayPicker", multiple: "multiple", isRequired: "isRequired", showConfirmButton: "showConfirmButton", futureValidationMessage: "futureValidationMessage", arabicLayout: "arabicLayout", mode: "mode", dir: "dir", locale: "locale", submitTextButton: "submitTextButton", todaysDateText: "todaysDateText", ummAlQuraDateText: "ummAlQuraDateText", monthSelectLabel: "monthSelectLabel", yearSelectLabel: "yearSelectLabel", futureValidationMessageEn: "futureValidationMessageEn", futureValidationMessageAr: "futureValidationMessageAr", theme: "theme", pastYearsLimit: "pastYearsLimit", futureYearsLimit: "futureYearsLimit", styles: "styles", enableTime: "enableTime", minDate: "minDate", maxDate: "maxDate", initialDate: "initialDate", initialRangeStart: "initialRangeStart", initialRangeEnd: "initialRangeEnd", useMeridian: "useMeridian", selectionMode: "selectionMode" }, outputs: { onSubmit: "onSubmit", onDaySelect: "onDaySelect", onMonthChange: "onMonthChange", onYearChange: "onYearChange" }, host: { properties: { "style.font-family": "this.fontFamilyStyle" } }, usesOnChanges: true, ngImport: i0, template: "<div class=\"calendar-container\" [dir]=\"dir\" [attr.lang]=\"locale\">\n <div\n class=\"toggle-section\"\n [dir]=\"dir\"\n *ngIf=\"canChangeMode\"\n [ngStyle]=\"{ color: styles.primaryColor }\"\n >\n <span> {{ ummAlQuraDateText }} </span>\n <label class=\"switch\">\n <input\n type=\"checkbox\"\n [disabled]=\"!canChangeMode\"\n [checked]=\"mode === 'ummAlQura'\"\n (change)=\"changeCalendarMode()\"\n #calendarCheckbox\n />\n <span\n class=\"slider\"\n [ngStyle]=\"\n calendarCheckbox.checked\n ? { 'background-color': styles.primaryColor }\n : { 'background-color': styles.backgroundColor }\n \"\n ></span>\n </label>\n </div>\n\n <div\n class=\"todays-date-section\"\n *ngIf=\"todaysDateSection\"\n [ngStyle]=\"{\n 'background-color': styles.backgroundColor,\n color: styles.primaryColor,\n 'border-radius': styles.borderRadius\n }\"\n >\n <div\n class=\"text-info\"\n [ngClass]=\"{\n order: dir == 'rtl'\n }\"\n >\n <p>{{ todaysDateText }}</p>\n </div>\n\n <div\n class=\"data\"\n [dir]=\"dir\"\n [ngStyle]=\"{\n 'background-color': styles.todaysDateBgColor,\n color: styles.todaysDateTextColor\n }\"\n >\n <p *ngIf=\"mode == 'ummAlQura'\">\n <!-- {{todaysDate.ummAlQura}} -->\n {{\n locale == \"ar\"\n ? _dateUtilsService.convertDateNumerals(todaysDate.ummAlQura, \"ar\")\n : todaysDate.ummAlQura\n }}\n </p>\n <p *ngIf=\"mode == 'greg'\">\n {{\n locale == \"ar\"\n ? _dateUtilsService.convertDateNumerals(todaysDate.gregorian, \"ar\")\n : todaysDate.gregorian\n }}\n </p>\n </div>\n </div>\n\n <div class=\"period-container\">\n <form [formGroup]=\"periodForm\" class=\"period-form\">\n <div\n class=\"select-item\"\n [ngClass]=\"{\n order: dir == 'ltr'\n }\"\n [ngStyle]=\"{\n 'background-color': styles.backgroundColor,\n 'border-radius': styles.borderRadius\n }\"\n >\n <label *ngIf=\"!periodForm.controls['year'].value\">{{\n yearSelectLabel\n }}</label>\n\n <select\n formControlName=\"year\"\n class=\"{{ 'icon-' + dir }}\"\n placeholder=\"\u0627\u0644\u0633\u0646\u0629\"\n (change)=\"onPeriodChange('year')\"\n [dir]=\"dir\"\n [ngStyle]=\"{\n color: styles.primaryColor,\n 'font-family': styles.fontFamily\n }\"\n >\n <option *ngFor=\"let year of years\" [ngValue]=\"year\">\n {{ locale == \"ar\" ? _dateUtilsService.parseEnglish(year) : year }}\n </option>\n </select>\n </div>\n\n <div\n class=\"select-item\"\n [ngClass]=\"{\n order: dir == 'rtl'\n }\"\n [ngStyle]=\"{\n 'background-color': styles.backgroundColor,\n 'border-radius': styles.borderRadius\n }\"\n >\n <label *ngIf=\"!periodForm.controls['month'].value\">{{\n monthSelectLabel\n }}</label>\n <select\n class=\"{{ 'icon-' + dir }}\"\n formControlName=\"month\"\n (change)=\"onPeriodChange('month')\"\n [dir]=\"dir\"\n [ngStyle]=\"{\n color: styles.primaryColor,\n 'font-family': styles.fontFamily\n }\"\n >\n <option *ngFor=\"let month of months\" [ngValue]=\"month.value\">\n {{ locale == \"ar\" ? month?.labelAr : month?.labelEn }}\n </option>\n </select>\n </div>\n </form>\n </div>\n\n <div\n class=\"calendar-layout\"\n [ngStyle]=\"{\n 'background-color': styles.backgroundColor,\n 'border-radius': styles.borderRadius\n }\"\n >\n <div class=\"week-days\">\n <div\n class=\"week-day\"\n [ngStyle]=\"{ color: styles.dayNameColor }\"\n *ngFor=\"let date of locale == 'ar' ? weekdaysAr : weekdaysEn\"\n >\n {{ date }}\n </div>\n </div>\n\n <div [dir]=\"dir\">\n <div class=\"week\" *ngFor=\"let week of weeks\">\n <div\n class=\"day\"\n *ngFor=\"let day of week\"\n (click)=\"disableDayPicker == false ? onDayClicked(day) : ''\"\n [ngStyle]=\"{\n 'background-color': styles.backgroundColor,\n color: styles.dayColor\n }\"\n >\n <div\n id=\"greg-day\"\n [ngClass]=\"{\n 'todays-date': checkTodaysDate(day),\n 'selected-date': day?.selected == true\n }\"\n [ngStyle]=\"{\n border:\n markToday && checkTodaysDate(day)\n ? '1px solid ' + styles.secondaryColor\n : '',\n 'background-color':\n day?.selected == true ? styles.secondaryColor : '',\n color:\n (day?.selected == true ? styles.todaysDateTextColor : '') ||\n (checkFutureValidation(day) && futureValidation\n ? styles.disabledDayColor\n : '') ||\n (isDateDisabled(day) ? styles.disabledDayColor : ''),\n opacity: isDateDisabled(day) ? '0.4' : '1',\n cursor: isDateDisabled(day) ? 'not-allowed' : 'pointer'\n }\"\n >\n <span *ngIf=\"mode == 'greg'\">{{\n locale == \"ar\"\n ? _dateUtilsService.parseEnglish(\n day?.gD?.split(\"/\")[0] | number\n )\n : (day?.gD?.split(\"/\")[0] | number)\n }}</span>\n\n <span id=\"ummAlQura-day\" *ngIf=\"mode == 'ummAlQura'\">{{\n locale == \"ar\"\n ? _dateUtilsService.parseEnglish(\n day?.uD?.split(\"/\")[0] | number\n )\n : (day?.uD?.split(\"/\")[0] | number)\n }}</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"future-validation\" dir=\"auto\" *ngIf=\"futureValidationMessage\">\n <span *ngIf=\"locale == 'ar'\">\n {{ futureValidationMessageAr }}\n </span>\n <span *ngIf=\"locale == 'en'\">\n {{ futureValidationMessageEn }}\n </span>\n </div>\n\n <!-- Time Picker Section -->\n <!-- BACKWARD COMPATIBILITY: This section only renders when enableTime=true -->\n <div class=\"time-picker-section\" *ngIf=\"enableTime\" [dir]=\"'ltr'\">\n <div class=\"time-picker-wrapper\">\n <!-- Hour Input with Arrows -->\n <div class=\"time-input-container\">\n <button\n type=\"button\"\n class=\"time-arrow time-arrow-up\"\n (click)=\"useMeridian ? incrementHour12() : incrementHour()\"\n tabindex=\"-1\"\n aria-label=\"Increment hour\"\n >\n <i class=\"ri-arrow-drop-up-line\"></i>\n </button>\n <input\n type=\"number\"\n class=\"time-field\"\n [value]=\"getDisplayHour().toString().padStart(2, '0')\"\n (input)=\"\n useMeridian\n ? onHour12InputChange($event)\n : onHourInputChange($event)\n \"\n (keydown)=\"onTimeKeydown($event, 'hour')\"\n [min]=\"useMeridian ? 1 : 0\"\n [max]=\"useMeridian ? 12 : 23\"\n aria-label=\"Hour\"\n />\n <button\n type=\"button\"\n class=\"time-arrow time-arrow-down\"\n (click)=\"useMeridian ? decrementHour12() : decrementHour()\"\n tabindex=\"-1\"\n aria-label=\"Decrement hour\"\n >\n <i class=\"ri-arrow-drop-down-line\"></i>\n </button>\n </div>\n\n <!-- Colon Separator -->\n <span class=\"time-colon\">:</span>\n\n <!-- Minute Input with Arrows -->\n <div class=\"time-input-container\">\n <button\n type=\"button\"\n class=\"time-arrow time-arrow-up\"\n (click)=\"incrementMinute()\"\n tabindex=\"-1\"\n aria-label=\"Increment minute\"\n >\n <i class=\"ri-arrow-drop-up-line\"></i>\n </button>\n <input\n type=\"number\"\n class=\"time-field\"\n [value]=\"selectedTime.minute.toString().padStart(2, '0')\"\n (input)=\"onMinuteInputChange($event)\"\n (keydown)=\"onTimeKeydown($event, 'minute')\"\n min=\"0\"\n max=\"59\"\n aria-label=\"Minute\"\n />\n <button\n type=\"button\"\n class=\"time-arrow time-arrow-down\"\n (click)=\"decrementMinute()\"\n tabindex=\"-1\"\n aria-label=\"Decrement minute\"\n >\n <i class=\"ri-arrow-drop-down-line\"></i>\n </button>\n </div>\n\n <!-- AM/PM Button Group (only when useMeridian=true) -->\n <!-- BACKWARD COMPATIBILITY: This only renders when useMeridian=true -->\n <div class=\"meridian-toggle-group\" *ngIf=\"useMeridian\">\n <button\n type=\"button\"\n class=\"meridian-btn\"\n [class.active]=\"meridian === 'AM'\"\n (click)=\"meridian !== 'AM' && toggleMeridian()\"\n aria-label=\"Select AM\"\n >\n AM\n </button>\n <button\n type=\"button\"\n class=\"meridian-btn\"\n [class.active]=\"meridian === 'PM'\"\n (click)=\"meridian !== 'PM' && toggleMeridian()\"\n aria-label=\"Select PM\"\n >\n PM\n </button>\n </div>\n </div>\n </div>\n\n <div>\n <button\n type=\"button\"\n class=\"confirm-btn\"\n [disabled]=\"\n isRequired &&\n ((!selectedDay && !multiple) ||\n (!multipleSelectedDates.length && multiple))\n \"\n (click)=\"onConfirmClicked()\"\n *ngIf=\"showConfirmButton\"\n [ngStyle]=\"{\n 'background-color': styles.secondaryColor,\n color: styles.confirmBtnTextColor,\n 'font-family': styles.fontFamily,\n 'border-radius': styles.borderRadius\n }\"\n >\n {{ submitTextButton }}\n </button>\n </div>\n</div>\n", styles: [".calendar-container{margin:auto;display:block;border-radius:20px;font-family:Poppins,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-weight:400}.calendar-container[dir=rtl],.calendar-container[lang=ar]{font-family:Zain,Arabic Typesetting,Tahoma,sans-serif;font-weight:300;letter-spacing:0;line-height:1.7}.calendar-container .todays-date-section{border-radius:4px;margin-top:12px;display:flex;align-items:center;justify-content:space-between;padding-left:10px;padding-right:10px}.calendar-container .todays-date-section .text-info{display:flex;align-items:center}.calendar-container .todays-date-section .text-info p{font-size:17px;font-weight:500;letter-spacing:.02em}[dir=rtl] .calendar-container .todays-date-section .text-info p,[lang=ar] .calendar-container .todays-date-section .text-info p{font-weight:400;letter-spacing:0}[dir=rtl] .calendar-container .todays-date-section .data p,[lang=ar] .calendar-container .todays-date-section .data p{font-weight:300}.calendar-container .todays-date-section .data{border-radius:8px}.calendar-container .todays-date-section .data p{font-size:14px;font-weight:400;margin:5px 10px}.calendar-container .period-container{display:flex;justify-content:space-between;margin-top:8px}.calendar-container .period-container .period-form{width:100%;display:flex;justify-content:space-between}.calendar-container .period-container .period-form .select-item{width:42.5%;border-radius:4px;height:50px;padding-left:10px;padding-right:10px}.calendar-container .period-container .period-form label{margin-right:10px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .calendar-container .period-container .period-form label,[lang=ar] .calendar-container .period-container .period-form label{font-weight:400}.calendar-container .period-container .period-form select{width:100%;height:50px;border:none;font-size:16px;font-weight:500;display:block;margin:auto;background:url(\"data:image/svg+xml;utf8,<svg viewBox='0 0 140 140' width='15' height='15' xmlns='http://www.w3.org/2000/svg'><g><path d='m121.3,34.6c-1.6-1.6-4.2-1.6-5.8,0l-51,51.1-51.1-51.1c-1.6-1.6-4.2-1.6-5.8,0-1.6,1.6-1.6,4.2 0,5.8l53.9,53.9c0.8,0.8 1.8,1.2 2.9,1.2 1,0 2.1-0.4 2.9-1.2l53.9-53.9c1.7-1.6 1.7-4.2 0.1-5.8z' fill='black'/></g></svg>\") no-repeat 95% 50%;-webkit-appearance:none;appearance:none;cursor:pointer}.calendar-container .period-container .period-form select option,.calendar-container [dir=rtl] .period-container select{font-weight:400}.calendar-container [dir=rtl] .period-container select option{font-weight:300}.icon-ltr{background-position:right}.icon-rtl{background-position:left!important}select:focus{outline:none}.calendar-layout{border-radius:4px;margin:8px auto auto;display:block;padding-bottom:5px}.calendar-layout .week-days{text-align:center;margin-top:5px;display:flex;justify-content:space-evenly}.calendar-layout .week-days .week-day{display:inline-block;width:13%;text-align:center;padding:15px 0 10px;font-weight:600;font-size:13px;text-transform:uppercase;letter-spacing:.05em}[dir=rtl] .calendar-layout .week-days{flex-direction:row-reverse!important}[dir=rtl] .calendar-layout .week-days .week-day{font-weight:700;letter-spacing:0;text-transform:none;font-size:14px}.calendar-layout .week{text-align:center;display:flex;justify-content:space-evenly}.calendar-layout .day{display:inline-flex;width:13%;height:5.5vh;justify-content:center;align-items:center;cursor:pointer;font-weight:500;transition:all .2s ease;border-radius:4px}.calendar-layout .day:hover:not(.disabled-day){transform:scale(1.05)}[dir=rtl] .calendar-layout .day{font-weight:400}.calendar-layout #greg-day{position:relative;min-width:20px}.calendar-layout #greg-day span{font-size:14px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .calendar-layout #greg-day span,[lang=ar] .calendar-layout #greg-day span{font-weight:400}.calendar-layout #ummAlQura-day{font-size:11px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .calendar-layout #ummAlQura-day,[lang=ar] .calendar-layout #ummAlQura-day{font-weight:400}.calendar-layout .todays-date,.calendar-layout .selected-date{padding:10px;border-radius:5px}.confirm-btn{height:50px;width:100%;border:none;font-size:16px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;margin:8px auto 0;box-shadow:none!important;cursor:pointer;transition:all .2s ease;border-radius:8px}.confirm-btn:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 4px 12px #00000026!important}.confirm-btn:disabled{opacity:.5;cursor:not-allowed}[dir=rtl] .confirm-btn{font-weight:700;letter-spacing:0;text-transform:none;font-size:17px}.toggle-section{display:flex;align-items:center;justify-content:space-between}.toggle-section label{text-align:right;font-size:19px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .toggle-section label,[lang=ar] .toggle-section label{font-weight:400}.toggle-section .switch{position:relative;display:inline-block;width:50px;height:24px}.toggle-section .switch input{opacity:0;width:0;height:0}.toggle-section .slider{position:absolute;cursor:pointer;inset:0;background-color:#ccc;transition:.4s;border-radius:24px}.toggle-section .slider:before{content:\"\";position:absolute;height:18px;width:18px;left:3px;bottom:3px;background-color:#fff;transition:.4s;border-radius:50%}.toggle-section input:checked+.slider:before{transform:translate(26px)}.order{order:1}.future-validation{text-align:center;color:#eb445a;margin-top:8px;font-size:13px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .future-validation,[lang=ar] .future-validation{font-weight:400;line-height:1.8}.time-picker-section{padding:10px;background:transparent;border-radius:0;font-family:Poppins,sans-serif}.time-picker-section .time-picker-wrapper{display:flex;align-items:center;justify-content:center;gap:8px}.time-picker-section .time-picker-wrapper .time-input-container{position:relative;display:inline-flex;flex-direction:column;align-items:center}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow{width:100%;height:20px;border:1px solid #ddd;background:#ffffff;color:#5b479c;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s ease;padding:0;margin:0}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow i{font-size:20px;line-height:1;pointer-events:none;opacity:.7;transition:opacity .2s ease;display:flex;align-items:center;justify-content:center}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow:hover i{opacity:1}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow:active{background:#e9ecef}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow:focus{outline:none}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow.time-arrow-up{border-radius:4px 4px 0 0;border-bottom:none}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow.time-arrow-down{border-radius:0 0 4px 4px;border-top:none}.time-picker-section .time-picker-wrapper .time-input-container .time-field{width:50px;height:25px;border:1px solid #ddd;border-top:none;border-bottom:none;background:#ffffff;font-size:18px;font-weight:600;color:#333;text-align:center;padding:0;margin:0;transition:all .2s ease;font-family:Poppins,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;-webkit-appearance:textfield;appearance:textfield}[dir=rtl] .time-picker-section .time-picker-wrapper .time-input-container .time-field,[lang=ar] .time-picker-section .time-picker-wrapper .time-input-container .time-field{font-weight:700}.time-picker-section .time-picker-wrapper .time-input-container .time-field::-webkit-outer-spin-button,.time-picker-section .time-picker-wrapper .time-input-container .time-field::-webkit-inner-spin-button{-webkit-appearance:none;appearance:none;margin:0}.time-picker-section .time-picker-wrapper .time-input-container .time-field:focus{outline:none;box-shadow:0 0 0 2px #5b479c1a;z-index:1}.time-picker-section .time-picker-wrapper .time-colon{font-size:24px;font-weight:600;color:#5b479c;padding:0 4px;-webkit-user-select:none;user-select:none;line-height:1;font-family:Poppins,sans-serif}[dir=rtl] .time-picker-section .time-picker-wrapper .time-colon,[lang=ar] .time-picker-section .time-picker-wrapper .time-colon{font-weight:700}.time-picker-section .time-picker-wrapper .meridian-toggle-group{display:flex;flex-direction:column;gap:0;margin-left:8px}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn{width:45px;height:25px;border:1px solid #ddd;background:#ffffff;color:#666;font-size:13px;font-weight:600;text-align:center;padding:0;cursor:pointer;transition:all .2s ease;font-family:Poppins,sans-serif}[dir=rtl] .time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn,[lang=ar] .time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn{font-weight:700}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:first-child{border-radius:4px 4px 0 0;border-bottom:none}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:last-child{border-radius:0 0 4px 4px}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:hover:not(.active){background:#f8f9fa;border-color:#00ace4;color:#00ace4}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:active{transform:scale(.98)}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:focus{outline:none;border-color:#00ace4;box-shadow:0 0 0 2px #00ace41a;z-index:1}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn.active{background:rgb(0,77,97);border-color:#004d61;color:#fff;cursor:default}@media (max-width: 480px){.time-picker-section{padding:12px}.time-picker-section .time-picker-wrapper{gap:6px}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow{height:18px}.time-picker-section .time-picker-wrapper .time-input-container .time-field{width:50px;height:36px;font-size:20px}.time-picker-section .time-picker-wrapper .time-colon{font-size:24px}.time-picker-section .time-picker-wrapper .meridian-toggle-group{margin-left:6px}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn{width:45px;height:27px;font-size:12px}}\n"], dependencies: [{ kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i3.DecimalPipe, name: "number" }] });
28879
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: HijriGregorianDatepickerComponent, decorators: [{
28880
- type: Component,
28881
- args: [{ selector: 'hijri-gregorian-datepicker', template: "<div class=\"calendar-container\" [dir]=\"dir\" [attr.lang]=\"locale\">\n <div\n class=\"toggle-section\"\n [dir]=\"dir\"\n *ngIf=\"canChangeMode\"\n [ngStyle]=\"{ color: styles.primaryColor }\"\n >\n <span> {{ ummAlQuraDateText }} </span>\n <label class=\"switch\">\n <input\n type=\"checkbox\"\n [disabled]=\"!canChangeMode\"\n [checked]=\"mode === 'ummAlQura'\"\n (change)=\"changeCalendarMode()\"\n #calendarCheckbox\n />\n <span\n class=\"slider\"\n [ngStyle]=\"\n calendarCheckbox.checked\n ? { 'background-color': styles.primaryColor }\n : { 'background-color': styles.backgroundColor }\n \"\n ></span>\n </label>\n </div>\n\n <div\n class=\"todays-date-section\"\n *ngIf=\"todaysDateSection\"\n [ngStyle]=\"{\n 'background-color': styles.backgroundColor,\n color: styles.primaryColor,\n 'border-radius': styles.borderRadius\n }\"\n >\n <div\n class=\"text-info\"\n [ngClass]=\"{\n order: dir == 'rtl'\n }\"\n >\n <p>{{ todaysDateText }}</p>\n </div>\n\n <div\n class=\"data\"\n [dir]=\"dir\"\n [ngStyle]=\"{\n 'background-color': styles.todaysDateBgColor,\n color: styles.todaysDateTextColor\n }\"\n >\n <p *ngIf=\"mode == 'ummAlQura'\">\n <!-- {{todaysDate.ummAlQura}} -->\n {{\n locale == \"ar\"\n ? _dateUtilsService.convertDateNumerals(todaysDate.ummAlQura, \"ar\")\n : todaysDate.ummAlQura\n }}\n </p>\n <p *ngIf=\"mode == 'greg'\">\n {{\n locale == \"ar\"\n ? _dateUtilsService.convertDateNumerals(todaysDate.gregorian, \"ar\")\n : todaysDate.gregorian\n }}\n </p>\n </div>\n </div>\n\n <div class=\"period-container\">\n <form [formGroup]=\"periodForm\" class=\"period-form\">\n <div\n class=\"select-item\"\n [ngClass]=\"{\n order: dir == 'ltr'\n }\"\n [ngStyle]=\"{\n 'background-color': styles.backgroundColor,\n 'border-radius': styles.borderRadius\n }\"\n >\n <label *ngIf=\"!periodForm.controls['year'].value\">{{\n yearSelectLabel\n }}</label>\n\n <select\n formControlName=\"year\"\n class=\"{{ 'icon-' + dir }}\"\n placeholder=\"\u0627\u0644\u0633\u0646\u0629\"\n (change)=\"onPeriodChange('year')\"\n [dir]=\"dir\"\n [ngStyle]=\"{\n color: styles.primaryColor,\n 'font-family': styles.fontFamily\n }\"\n >\n <option *ngFor=\"let year of years\" [ngValue]=\"year\">\n {{ locale == \"ar\" ? _dateUtilsService.parseEnglish(year) : year }}\n </option>\n </select>\n </div>\n\n <div\n class=\"select-item\"\n [ngClass]=\"{\n order: dir == 'rtl'\n }\"\n [ngStyle]=\"{\n 'background-color': styles.backgroundColor,\n 'border-radius': styles.borderRadius\n }\"\n >\n <label *ngIf=\"!periodForm.controls['month'].value\">{{\n monthSelectLabel\n }}</label>\n <select\n class=\"{{ 'icon-' + dir }}\"\n formControlName=\"month\"\n (change)=\"onPeriodChange('month')\"\n [dir]=\"dir\"\n [ngStyle]=\"{\n color: styles.primaryColor,\n 'font-family': styles.fontFamily\n }\"\n >\n <option *ngFor=\"let month of months\" [ngValue]=\"month.value\">\n {{ locale == \"ar\" ? month?.labelAr : month?.labelEn }}\n </option>\n </select>\n </div>\n </form>\n </div>\n\n <div\n class=\"calendar-layout\"\n [ngStyle]=\"{\n 'background-color': styles.backgroundColor,\n 'border-radius': styles.borderRadius\n }\"\n >\n <div class=\"week-days\">\n <div\n class=\"week-day\"\n [ngStyle]=\"{ color: styles.dayNameColor }\"\n *ngFor=\"let date of locale == 'ar' ? weekdaysAr : weekdaysEn\"\n >\n {{ date }}\n </div>\n </div>\n\n <div [dir]=\"dir\">\n <div class=\"week\" *ngFor=\"let week of weeks\">\n <div\n class=\"day\"\n *ngFor=\"let day of week\"\n (click)=\"disableDayPicker == false ? onDayClicked(day) : ''\"\n [ngStyle]=\"{\n 'background-color': styles.backgroundColor,\n color: styles.dayColor\n }\"\n >\n <div\n id=\"greg-day\"\n [ngClass]=\"{\n 'todays-date': checkTodaysDate(day),\n 'selected-date': day?.selected == true\n }\"\n [ngStyle]=\"{\n border:\n markToday && checkTodaysDate(day)\n ? '1px solid ' + styles.secondaryColor\n : '',\n 'background-color':\n day?.selected == true ? styles.secondaryColor : '',\n color:\n (day?.selected == true ? styles.todaysDateTextColor : '') ||\n (checkFutureValidation(day) && futureValidation\n ? styles.disabledDayColor\n : '') ||\n (isDateDisabled(day) ? styles.disabledDayColor : ''),\n opacity: isDateDisabled(day) ? '0.4' : '1',\n cursor: isDateDisabled(day) ? 'not-allowed' : 'pointer'\n }\"\n >\n <span *ngIf=\"mode == 'greg'\">{{\n locale == \"ar\"\n ? _dateUtilsService.parseEnglish(\n day?.gD?.split(\"/\")[0] | number\n )\n : (day?.gD?.split(\"/\")[0] | number)\n }}</span>\n\n <span id=\"ummAlQura-day\" *ngIf=\"mode == 'ummAlQura'\">{{\n locale == \"ar\"\n ? _dateUtilsService.parseEnglish(\n day?.uD?.split(\"/\")[0] | number\n )\n : (day?.uD?.split(\"/\")[0] | number)\n }}</span>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"future-validation\" dir=\"auto\" *ngIf=\"futureValidationMessage\">\n <span *ngIf=\"locale == 'ar'\">\n {{ futureValidationMessageAr }}\n </span>\n <span *ngIf=\"locale == 'en'\">\n {{ futureValidationMessageEn }}\n </span>\n </div>\n\n <!-- Time Picker Section -->\n <!-- BACKWARD COMPATIBILITY: This section only renders when enableTime=true -->\n <div class=\"time-picker-section\" *ngIf=\"enableTime\" [dir]=\"'ltr'\">\n <div class=\"time-picker-wrapper\">\n <!-- Hour Input with Arrows -->\n <div class=\"time-input-container\">\n <button\n type=\"button\"\n class=\"time-arrow time-arrow-up\"\n (click)=\"useMeridian ? incrementHour12() : incrementHour()\"\n tabindex=\"-1\"\n aria-label=\"Increment hour\"\n >\n <i class=\"ri-arrow-drop-up-line\"></i>\n </button>\n <input\n type=\"number\"\n class=\"time-field\"\n [value]=\"getDisplayHour().toString().padStart(2, '0')\"\n (input)=\"\n useMeridian\n ? onHour12InputChange($event)\n : onHourInputChange($event)\n \"\n (keydown)=\"onTimeKeydown($event, 'hour')\"\n [min]=\"useMeridian ? 1 : 0\"\n [max]=\"useMeridian ? 12 : 23\"\n aria-label=\"Hour\"\n />\n <button\n type=\"button\"\n class=\"time-arrow time-arrow-down\"\n (click)=\"useMeridian ? decrementHour12() : decrementHour()\"\n tabindex=\"-1\"\n aria-label=\"Decrement hour\"\n >\n <i class=\"ri-arrow-drop-down-line\"></i>\n </button>\n </div>\n\n <!-- Colon Separator -->\n <span class=\"time-colon\">:</span>\n\n <!-- Minute Input with Arrows -->\n <div class=\"time-input-container\">\n <button\n type=\"button\"\n class=\"time-arrow time-arrow-up\"\n (click)=\"incrementMinute()\"\n tabindex=\"-1\"\n aria-label=\"Increment minute\"\n >\n <i class=\"ri-arrow-drop-up-line\"></i>\n </button>\n <input\n type=\"number\"\n class=\"time-field\"\n [value]=\"selectedTime.minute.toString().padStart(2, '0')\"\n (input)=\"onMinuteInputChange($event)\"\n (keydown)=\"onTimeKeydown($event, 'minute')\"\n min=\"0\"\n max=\"59\"\n aria-label=\"Minute\"\n />\n <button\n type=\"button\"\n class=\"time-arrow time-arrow-down\"\n (click)=\"decrementMinute()\"\n tabindex=\"-1\"\n aria-label=\"Decrement minute\"\n >\n <i class=\"ri-arrow-drop-down-line\"></i>\n </button>\n </div>\n\n <!-- AM/PM Button Group (only when useMeridian=true) -->\n <!-- BACKWARD COMPATIBILITY: This only renders when useMeridian=true -->\n <div class=\"meridian-toggle-group\" *ngIf=\"useMeridian\">\n <button\n type=\"button\"\n class=\"meridian-btn\"\n [class.active]=\"meridian === 'AM'\"\n (click)=\"meridian !== 'AM' && toggleMeridian()\"\n aria-label=\"Select AM\"\n >\n AM\n </button>\n <button\n type=\"button\"\n class=\"meridian-btn\"\n [class.active]=\"meridian === 'PM'\"\n (click)=\"meridian !== 'PM' && toggleMeridian()\"\n aria-label=\"Select PM\"\n >\n PM\n </button>\n </div>\n </div>\n </div>\n\n <div>\n <button\n type=\"button\"\n class=\"confirm-btn\"\n [disabled]=\"\n isRequired &&\n ((!selectedDay && !multiple) ||\n (!multipleSelectedDates.length && multiple))\n \"\n (click)=\"onConfirmClicked()\"\n *ngIf=\"showConfirmButton\"\n [ngStyle]=\"{\n 'background-color': styles.secondaryColor,\n color: styles.confirmBtnTextColor,\n 'font-family': styles.fontFamily,\n 'border-radius': styles.borderRadius\n }\"\n >\n {{ submitTextButton }}\n </button>\n </div>\n</div>\n", styles: [".calendar-container{margin:auto;display:block;border-radius:20px;font-family:Poppins,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-weight:400}.calendar-container[dir=rtl],.calendar-container[lang=ar]{font-family:Zain,Arabic Typesetting,Tahoma,sans-serif;font-weight:300;letter-spacing:0;line-height:1.7}.calendar-container .todays-date-section{border-radius:4px;margin-top:12px;display:flex;align-items:center;justify-content:space-between;padding-left:10px;padding-right:10px}.calendar-container .todays-date-section .text-info{display:flex;align-items:center}.calendar-container .todays-date-section .text-info p{font-size:17px;font-weight:500;letter-spacing:.02em}[dir=rtl] .calendar-container .todays-date-section .text-info p,[lang=ar] .calendar-container .todays-date-section .text-info p{font-weight:400;letter-spacing:0}[dir=rtl] .calendar-container .todays-date-section .data p,[lang=ar] .calendar-container .todays-date-section .data p{font-weight:300}.calendar-container .todays-date-section .data{border-radius:8px}.calendar-container .todays-date-section .data p{font-size:14px;font-weight:400;margin:5px 10px}.calendar-container .period-container{display:flex;justify-content:space-between;margin-top:8px}.calendar-container .period-container .period-form{width:100%;display:flex;justify-content:space-between}.calendar-container .period-container .period-form .select-item{width:42.5%;border-radius:4px;height:50px;padding-left:10px;padding-right:10px}.calendar-container .period-container .period-form label{margin-right:10px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .calendar-container .period-container .period-form label,[lang=ar] .calendar-container .period-container .period-form label{font-weight:400}.calendar-container .period-container .period-form select{width:100%;height:50px;border:none;font-size:16px;font-weight:500;display:block;margin:auto;background:url(\"data:image/svg+xml;utf8,<svg viewBox='0 0 140 140' width='15' height='15' xmlns='http://www.w3.org/2000/svg'><g><path d='m121.3,34.6c-1.6-1.6-4.2-1.6-5.8,0l-51,51.1-51.1-51.1c-1.6-1.6-4.2-1.6-5.8,0-1.6,1.6-1.6,4.2 0,5.8l53.9,53.9c0.8,0.8 1.8,1.2 2.9,1.2 1,0 2.1-0.4 2.9-1.2l53.9-53.9c1.7-1.6 1.7-4.2 0.1-5.8z' fill='black'/></g></svg>\") no-repeat 95% 50%;-webkit-appearance:none;appearance:none;cursor:pointer}.calendar-container .period-container .period-form select option,.calendar-container [dir=rtl] .period-container select{font-weight:400}.calendar-container [dir=rtl] .period-container select option{font-weight:300}.icon-ltr{background-position:right}.icon-rtl{background-position:left!important}select:focus{outline:none}.calendar-layout{border-radius:4px;margin:8px auto auto;display:block;padding-bottom:5px}.calendar-layout .week-days{text-align:center;margin-top:5px;display:flex;justify-content:space-evenly}.calendar-layout .week-days .week-day{display:inline-block;width:13%;text-align:center;padding:15px 0 10px;font-weight:600;font-size:13px;text-transform:uppercase;letter-spacing:.05em}[dir=rtl] .calendar-layout .week-days{flex-direction:row-reverse!important}[dir=rtl] .calendar-layout .week-days .week-day{font-weight:700;letter-spacing:0;text-transform:none;font-size:14px}.calendar-layout .week{text-align:center;display:flex;justify-content:space-evenly}.calendar-layout .day{display:inline-flex;width:13%;height:5.5vh;justify-content:center;align-items:center;cursor:pointer;font-weight:500;transition:all .2s ease;border-radius:4px}.calendar-layout .day:hover:not(.disabled-day){transform:scale(1.05)}[dir=rtl] .calendar-layout .day{font-weight:400}.calendar-layout #greg-day{position:relative;min-width:20px}.calendar-layout #greg-day span{font-size:14px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .calendar-layout #greg-day span,[lang=ar] .calendar-layout #greg-day span{font-weight:400}.calendar-layout #ummAlQura-day{font-size:11px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .calendar-layout #ummAlQura-day,[lang=ar] .calendar-layout #ummAlQura-day{font-weight:400}.calendar-layout .todays-date,.calendar-layout .selected-date{padding:10px;border-radius:5px}.confirm-btn{height:50px;width:100%;border:none;font-size:16px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;margin:8px auto 0;box-shadow:none!important;cursor:pointer;transition:all .2s ease;border-radius:8px}.confirm-btn:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 4px 12px #00000026!important}.confirm-btn:disabled{opacity:.5;cursor:not-allowed}[dir=rtl] .confirm-btn{font-weight:700;letter-spacing:0;text-transform:none;font-size:17px}.toggle-section{display:flex;align-items:center;justify-content:space-between}.toggle-section label{text-align:right;font-size:19px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .toggle-section label,[lang=ar] .toggle-section label{font-weight:400}.toggle-section .switch{position:relative;display:inline-block;width:50px;height:24px}.toggle-section .switch input{opacity:0;width:0;height:0}.toggle-section .slider{position:absolute;cursor:pointer;inset:0;background-color:#ccc;transition:.4s;border-radius:24px}.toggle-section .slider:before{content:\"\";position:absolute;height:18px;width:18px;left:3px;bottom:3px;background-color:#fff;transition:.4s;border-radius:50%}.toggle-section input:checked+.slider:before{transform:translate(26px)}.order{order:1}.future-validation{text-align:center;color:#eb445a;margin-top:8px;font-size:13px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .future-validation,[lang=ar] .future-validation{font-weight:400;line-height:1.8}.time-picker-section{padding:10px;background:transparent;border-radius:0;font-family:Poppins,sans-serif}.time-picker-section .time-picker-wrapper{display:flex;align-items:center;justify-content:center;gap:8px}.time-picker-section .time-picker-wrapper .time-input-container{position:relative;display:inline-flex;flex-direction:column;align-items:center}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow{width:100%;height:20px;border:1px solid #ddd;background:#ffffff;color:#5b479c;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s ease;padding:0;margin:0}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow i{font-size:20px;line-height:1;pointer-events:none;opacity:.7;transition:opacity .2s ease;display:flex;align-items:center;justify-content:center}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow:hover i{opacity:1}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow:active{background:#e9ecef}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow:focus{outline:none}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow.time-arrow-up{border-radius:4px 4px 0 0;border-bottom:none}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow.time-arrow-down{border-radius:0 0 4px 4px;border-top:none}.time-picker-section .time-picker-wrapper .time-input-container .time-field{width:50px;height:25px;border:1px solid #ddd;border-top:none;border-bottom:none;background:#ffffff;font-size:18px;font-weight:600;color:#333;text-align:center;padding:0;margin:0;transition:all .2s ease;font-family:Poppins,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;-webkit-appearance:textfield;appearance:textfield}[dir=rtl] .time-picker-section .time-picker-wrapper .time-input-container .time-field,[lang=ar] .time-picker-section .time-picker-wrapper .time-input-container .time-field{font-weight:700}.time-picker-section .time-picker-wrapper .time-input-container .time-field::-webkit-outer-spin-button,.time-picker-section .time-picker-wrapper .time-input-container .time-field::-webkit-inner-spin-button{-webkit-appearance:none;appearance:none;margin:0}.time-picker-section .time-picker-wrapper .time-input-container .time-field:focus{outline:none;box-shadow:0 0 0 2px #5b479c1a;z-index:1}.time-picker-section .time-picker-wrapper .time-colon{font-size:24px;font-weight:600;color:#5b479c;padding:0 4px;-webkit-user-select:none;user-select:none;line-height:1;font-family:Poppins,sans-serif}[dir=rtl] .time-picker-section .time-picker-wrapper .time-colon,[lang=ar] .time-picker-section .time-picker-wrapper .time-colon{font-weight:700}.time-picker-section .time-picker-wrapper .meridian-toggle-group{display:flex;flex-direction:column;gap:0;margin-left:8px}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn{width:45px;height:25px;border:1px solid #ddd;background:#ffffff;color:#666;font-size:13px;font-weight:600;text-align:center;padding:0;cursor:pointer;transition:all .2s ease;font-family:Poppins,sans-serif}[dir=rtl] .time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn,[lang=ar] .time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn{font-weight:700}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:first-child{border-radius:4px 4px 0 0;border-bottom:none}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:last-child{border-radius:0 0 4px 4px}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:hover:not(.active){background:#f8f9fa;border-color:#00ace4;color:#00ace4}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:active{transform:scale(.98)}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:focus{outline:none;border-color:#00ace4;box-shadow:0 0 0 2px #00ace41a;z-index:1}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn.active{background:rgb(0,77,97);border-color:#004d61;color:#fff;cursor:default}@media (max-width: 480px){.time-picker-section{padding:12px}.time-picker-section .time-picker-wrapper{gap:6px}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow{height:18px}.time-picker-section .time-picker-wrapper .time-input-container .time-field{width:50px;height:36px;font-size:20px}.time-picker-section .time-picker-wrapper .time-colon{font-size:24px}.time-picker-section .time-picker-wrapper .meridian-toggle-group{margin-left:6px}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn{width:45px;height:27px;font-size:12px}}\n"] }]
28882
- }], ctorParameters: function () { return [{ type: i1.UntypedFormBuilder }, { type: DateUtilitiesService }]; }, propDecorators: { markToday: [{
28883
- type: Input
28884
- }], canChangeMode: [{
28885
- type: Input
28886
- }], todaysDateSection: [{
28887
- type: Input
28888
- }], futureValidation: [{
28889
- type: Input
28890
- }], disableYearPicker: [{
28891
- type: Input
28892
- }], disableMonthPicker: [{
28893
- type: Input
28894
- }], disableDayPicker: [{
28895
- type: Input
28896
- }], multiple: [{
28897
- type: Input
28898
- }], isRequired: [{
28899
- type: Input
28900
- }], showConfirmButton: [{
28901
- type: Input
28902
- }], futureValidationMessage: [{
28903
- type: Input
28904
- }], arabicLayout: [{
28905
- type: Input
28906
- }], mode: [{
28907
- type: Input
28908
- }], dir: [{
28909
- type: Input
28910
- }], locale: [{
28911
- type: Input
28912
- }], submitTextButton: [{
28913
- type: Input
28914
- }], todaysDateText: [{
28915
- type: Input
28916
- }], ummAlQuraDateText: [{
28917
- type: Input
28918
- }], monthSelectLabel: [{
28919
- type: Input
28920
- }], yearSelectLabel: [{
28921
- type: Input
28922
- }], futureValidationMessageEn: [{
28923
- type: Input
28924
- }], futureValidationMessageAr: [{
28925
- type: Input
28926
- }], theme: [{
28927
- type: Input
28928
- }], pastYearsLimit: [{
28929
- type: Input
28930
- }], futureYearsLimit: [{
28931
- type: Input
28932
- }], styles: [{
28933
- type: Input
28934
- }], enableTime: [{
28935
- type: Input
28936
- }], minDate: [{
28937
- type: Input
28938
- }], maxDate: [{
28939
- type: Input
28940
- }], initialDate: [{
28941
- type: Input
28942
- }], initialRangeStart: [{
28943
- type: Input
28944
- }], initialRangeEnd: [{
28945
- type: Input
28946
- }], useMeridian: [{
28947
- type: Input
28948
- }], selectionMode: [{
28949
- type: Input
28950
- }], onSubmit: [{
28951
- type: Output
28952
- }], onDaySelect: [{
28953
- type: Output
28954
- }], onMonthChange: [{
28955
- type: Output
28956
- }], onYearChange: [{
28957
- type: Output
28958
- }], fontFamilyStyle: [{
28959
- type: HostBinding,
28960
- args: ['style.font-family']
27911
+ class HijriGregorianDatepickerComponent {
27912
+ constructor(formBuilder, _dateUtilsService) {
27913
+ this.formBuilder = formBuilder;
27914
+ this._dateUtilsService = _dateUtilsService;
27915
+ /// Inputs
27916
+ this.markToday = true;
27917
+ this.canChangeMode = true;
27918
+ this.todaysDateSection = true;
27919
+ this.futureValidation = true;
27920
+ this.disableYearPicker = false;
27921
+ this.disableMonthPicker = false;
27922
+ this.disableDayPicker = false;
27923
+ this.multiple = false;
27924
+ this.isRequired = false;
27925
+ this.showConfirmButton = true;
27926
+ this.futureValidationMessage = false;
27927
+ this.arabicLayout = false;
27928
+ this.mode = 'greg';
27929
+ this.dir = 'ltr';
27930
+ this.locale = 'en';
27931
+ this.submitTextButton = 'Confirm';
27932
+ this.todaysDateText = "Today's Date";
27933
+ this.ummAlQuraDateText = 'Hijri Date';
27934
+ this.monthSelectLabel = 'Month';
27935
+ this.yearSelectLabel = 'Year';
27936
+ this.theme = '';
27937
+ this.pastYearsLimit = 90;
27938
+ this.futureYearsLimit = 0;
27939
+ this.styles = {};
27940
+ // New inputs for extended functionality
27941
+ this.enableTime = false; // Enable time picker (hours & minutes)
27942
+ // BACKWARD COMPATIBILITY: Default to false (24-hour format)
27943
+ // When true, displays 12-hour format with AM/PM toggle
27944
+ this.useMeridian = false; // Enable 12-hour format with AM/PM
27945
+ // BACKWARD COMPATIBILITY: Default to 'single' (existing behavior)
27946
+ // 'range' enables range selection mode (first click = start, second click = end)
27947
+ this.selectionMode = 'single';
27948
+ /// Outputs
27949
+ this.onSubmit = new EventEmitter();
27950
+ this.onDaySelect = new EventEmitter();
27951
+ this.onMonthChange = new EventEmitter();
27952
+ this.onYearChange = new EventEmitter();
27953
+ /// Variables
27954
+ this.ummAlQuraMonths = [
27955
+ { labelAr: 'محرم', labelEn: 'Muharram', value: 1 },
27956
+ { labelAr: 'صفر', labelEn: 'Safar', value: 2 },
27957
+ { labelAr: 'ربيع الأول', labelEn: 'Rabi al-Awwal', value: 3 },
27958
+ { labelAr: 'ربيع الثاني', labelEn: 'Rabi al-Thani', value: 4 },
27959
+ { labelAr: 'جمادى الأولى', labelEn: 'Jumada al-Awwal', value: 5 },
27960
+ { labelAr: 'جمادى الآخرة', labelEn: 'Jumada al-Thani', value: 6 },
27961
+ { labelAr: 'رجب', labelEn: 'Rajab', value: 7 },
27962
+ { labelAr: 'شعبان', labelEn: 'Shaban', value: 8 },
27963
+ { labelAr: 'رمضان', labelEn: 'Ramadan', value: 9 },
27964
+ { labelAr: 'شوال', labelEn: 'Shawwal', value: 10 },
27965
+ { labelAr: 'ذو القعدة', labelEn: 'Dhu al-Qadah', value: 11 },
27966
+ { labelAr: 'ذو الحجة', labelEn: 'Dhu al-Hijjah', value: 12 },
27967
+ ];
27968
+ this.gregMonths = [
27969
+ { labelAr: 'يناير', labelEn: 'January', value: 1 },
27970
+ { labelAr: 'فبراير', labelEn: 'February', value: 2 },
27971
+ { labelAr: 'مارس', labelEn: 'March', value: 3 },
27972
+ { labelAr: 'ابريل', labelEn: 'April', value: 4 },
27973
+ { labelAr: 'مايو', labelEn: 'May', value: 5 },
27974
+ { labelAr: 'يونيو', labelEn: 'June', value: 6 },
27975
+ { labelAr: 'يوليو', labelEn: 'July', value: 7 },
27976
+ { labelAr: 'اغسطس', labelEn: 'August', value: 8 },
27977
+ { labelAr: 'سبتمبر', labelEn: 'September', value: 9 },
27978
+ { labelAr: 'اكتوبر', labelEn: 'October', value: 10 },
27979
+ { labelAr: 'نوفمبر', labelEn: 'November', value: 11 },
27980
+ { labelAr: 'ديسمبر', labelEn: 'December', value: 12 },
27981
+ ];
27982
+ this.weekdaysEn = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
27983
+ this.weekdaysAr = ['سبت', 'جمعة', 'خميس', 'أربعاء', 'ثلاثاء', 'اثنين', 'أحد'];
27984
+ // weekdaysAr = ['س', 'ج', 'خ', 'أر', 'ث', 'إث', 'أح'];
27985
+ this.todaysDate = {};
27986
+ this.multipleSelectedDates = [];
27987
+ this.themes = [];
27988
+ // Time picker variables
27989
+ // BACKWARD COMPATIBILITY: selectedTime defaults to 0:0 to preserve existing behavior when enableTime=false
27990
+ // When enableTime=true, this will be initialized to current system time in ngOnInit
27991
+ this.selectedTime = { hour: 0, minute: 0 };
27992
+ // Track if time has been initialized to avoid re-initializing at midnight
27993
+ this.timeInitialized = false;
27994
+ // BACKWARD COMPATIBILITY: Meridian only used when useMeridian=true
27995
+ // Tracks AM/PM state for 12-hour format
27996
+ this.meridian = 'AM';
27997
+ // Range selection state
27998
+ // BACKWARD COMPATIBILITY: These are only used when selectionMode='range'
27999
+ // They do not affect single or multiple selection modes
28000
+ this.rangeStart = undefined;
28001
+ this.rangeEnd = undefined;
28002
+ }
28003
+ ngOnInit() {
28004
+ this.initTheme();
28005
+ this.initializeForm();
28006
+ this.getTodaysDateInfo();
28007
+ this.initializeYearsAndMonths();
28008
+ // Initialize time from current system time or initialDate
28009
+ // BACKWARD COMPATIBILITY: This only runs when enableTime=true
28010
+ if (this.enableTime) {
28011
+ this.initializeTime();
28012
+ }
28013
+ }
28014
+ ngAfterViewInit() {
28015
+ // Double-check time initialization after view is ready
28016
+ // This handles cases where enableTime might be set after ngOnInit
28017
+ if (this.enableTime && !this.timeInitialized) {
28018
+ this.initializeTime();
28019
+ }
28020
+ }
28021
+ ngOnChanges(changes) {
28022
+ if (!changes['mode'].isFirstChange()) {
28023
+ this.changeCalendarMode();
28024
+ }
28025
+ }
28026
+ initTheme() {
28027
+ if (this.theme != '') {
28028
+ this.themes = themesConfig;
28029
+ for (const themeItem of this.themes['default']) {
28030
+ if (themeItem.name == this.theme) {
28031
+ this.styles = themeItem.stylesConfig;
28032
+ break;
28033
+ }
28034
+ }
28035
+ }
28036
+ this.fontFamilyStyle = this.styles.fontFamily;
28037
+ }
28038
+ /// Initialize form control for month and year select
28039
+ initializeForm() {
28040
+ this.periodForm = this.formBuilder.group({
28041
+ year: [{ value: '', disabled: this.disableYearPicker }, []],
28042
+ month: [{ value: '', disabled: this.disableMonthPicker }, []],
28043
+ });
28044
+ }
28045
+ // Initialize years and months for calendar
28046
+ initializeYearsAndMonths() {
28047
+ this.years = [];
28048
+ this.months = [];
28049
+ // Determine the date to use for initialization (initialDate or today)
28050
+ let referenceDate;
28051
+ if (this.initialDate) {
28052
+ const normalizedInitialDate = this._dateUtilsService.normalizeDateToString(this.initialDate);
28053
+ if (normalizedInitialDate) {
28054
+ if (this.mode == 'greg') {
28055
+ referenceDate = normalizedInitialDate;
28056
+ }
28057
+ else {
28058
+ const hijriDate = this._dateUtilsService.convertDate(normalizedInitialDate, true);
28059
+ referenceDate = hijriDate?.uD || this.todaysDate.ummAlQura;
28060
+ }
28061
+ }
28062
+ else {
28063
+ referenceDate =
28064
+ this.mode == 'greg'
28065
+ ? this.todaysDate.gregorian
28066
+ : this.todaysDate.ummAlQura;
28067
+ }
28068
+ }
28069
+ else {
28070
+ referenceDate =
28071
+ this.mode == 'greg'
28072
+ ? this.todaysDate.gregorian
28073
+ : this.todaysDate.ummAlQura;
28074
+ }
28075
+ if (this.mode == 'greg') {
28076
+ this.gregYear =
28077
+ this.futureYearsLimit == 0
28078
+ ? Number(referenceDate?.split('/')[2])
28079
+ : Number(referenceDate?.split('/')[2]) + this.futureYearsLimit;
28080
+ for (let i = 0; i < this.gregYear; i++) {
28081
+ if (i < this.pastYearsLimit) {
28082
+ let val = this.gregYear--;
28083
+ this.years.push(val);
28084
+ }
28085
+ else {
28086
+ break;
28087
+ }
28088
+ }
28089
+ this.months = this.gregMonths;
28090
+ }
28091
+ else {
28092
+ this.ummAlQuraYear =
28093
+ this.futureYearsLimit == 0
28094
+ ? Number(referenceDate?.split('/')[2])
28095
+ : Number(referenceDate?.split('/')[2]) + this.futureYearsLimit;
28096
+ for (let i = 0; i < this.ummAlQuraYear; i++) {
28097
+ if (i < this.pastYearsLimit) {
28098
+ let val = this.ummAlQuraYear--;
28099
+ this.years.push(val);
28100
+ }
28101
+ else {
28102
+ break;
28103
+ }
28104
+ }
28105
+ this.months = this.ummAlQuraMonths;
28106
+ }
28107
+ this.years.map((year) => {
28108
+ if (year == referenceDate?.split('/')[2]) {
28109
+ this.periodForm.controls['year'].setValue(year);
28110
+ }
28111
+ });
28112
+ this.months.map((month) => {
28113
+ if (month.value == referenceDate?.split('/')[1]) {
28114
+ this.periodForm.controls['month'].setValue(month.value);
28115
+ }
28116
+ });
28117
+ }
28118
+ /// On change event of years and months
28119
+ onPeriodChange(type) {
28120
+ if (type == 'year') {
28121
+ this.onYearChange.emit(this.periodForm.controls['year'].value);
28122
+ }
28123
+ else {
28124
+ this.onMonthChange.emit(this.periodForm.controls['month'].value);
28125
+ }
28126
+ const days = this._dateUtilsService.getMonthData('01/' +
28127
+ this.periodForm.controls['month'].value +
28128
+ '/' +
28129
+ this.periodForm.controls['year'].value, this.mode);
28130
+ this.weeks = this.generateWeeksArray(days);
28131
+ }
28132
+ /// Get todays(greg and umm al qura) date info
28133
+ getTodaysDateInfo() {
28134
+ this.todaysDate.gregorian = this._dateUtilsService.formatDate(new Date());
28135
+ this.todaysDate.ummAlQura = this._dateUtilsService.convertDate(this.todaysDate.gregorian, true)?.uD;
28136
+ // Use initialDate if provided, otherwise use today's date
28137
+ let dateToNavigate;
28138
+ if (this.initialDate) {
28139
+ // Normalize initialDate to DD/MM/YYYY format
28140
+ const normalizedInitialDate = this._dateUtilsService.normalizeDateToString(this.initialDate);
28141
+ if (normalizedInitialDate) {
28142
+ if (this.mode == 'greg') {
28143
+ dateToNavigate = normalizedInitialDate;
28144
+ }
28145
+ else {
28146
+ // Convert to Hijri for ummAlQura mode
28147
+ const hijriDate = this._dateUtilsService.convertDate(normalizedInitialDate, true);
28148
+ dateToNavigate = hijriDate?.uD || this.todaysDate.ummAlQura;
28149
+ }
28150
+ }
28151
+ else {
28152
+ // Invalid initialDate, fall back to today
28153
+ dateToNavigate =
28154
+ this.mode == 'greg'
28155
+ ? this.todaysDate.gregorian
28156
+ : this.todaysDate.ummAlQura;
28157
+ }
28158
+ }
28159
+ else {
28160
+ // No initialDate provided, use today
28161
+ dateToNavigate =
28162
+ this.mode == 'greg'
28163
+ ? this.todaysDate.gregorian
28164
+ : this.todaysDate.ummAlQura;
28165
+ }
28166
+ this.generatetMonthData(dateToNavigate);
28167
+ // Highlight initialDate or initialRange if provided
28168
+ if (this.selectionMode === 'range' && (this.initialRangeStart || this.initialRangeEnd)) {
28169
+ this.highlightInitialRange();
28170
+ }
28171
+ else if (this.initialDate) {
28172
+ this.highlightInitialDate();
28173
+ }
28174
+ }
28175
+ /// Generate month days from JSON
28176
+ generatetMonthData(date) {
28177
+ const days = this._dateUtilsService.getMonthData(date, this.mode);
28178
+ this.weeks = this.generateWeeksArray(days);
28179
+ }
28180
+ /// Highlight initialDate on the calendar
28181
+ highlightInitialDate() {
28182
+ if (!this.initialDate) {
28183
+ return;
28184
+ }
28185
+ const normalizedInitialDate = this._dateUtilsService.normalizeDateToString(this.initialDate);
28186
+ if (!normalizedInitialDate) {
28187
+ return;
28188
+ }
28189
+ // Find the day in the weeks array that matches initialDate
28190
+ for (const week of this.weeks) {
28191
+ for (const day of week) {
28192
+ if (day && day.gD === normalizedInitialDate) {
28193
+ // Don't select if date is disabled
28194
+ if (!this.isDateDisabled(day)) {
28195
+ // Mark as selected without triggering events
28196
+ day.selected = true;
28197
+ // Set as selectedDay based on selection mode
28198
+ if (this.selectionMode === 'range') {
28199
+ this.rangeStart = day;
28200
+ }
28201
+ else if (this.multiple) {
28202
+ this.multipleSelectedDates = [day];
28203
+ }
28204
+ else {
28205
+ this.selectedDay = day;
28206
+ }
28207
+ // Initialize time if enableTime is active
28208
+ if (this.enableTime && !this.timeInitialized) {
28209
+ this.initializeTime();
28210
+ }
28211
+ // Attach time to the day if it's a Date object with time
28212
+ if (this.enableTime && this.initialDate instanceof Date) {
28213
+ day.time = {
28214
+ hour: this.initialDate.getHours(),
28215
+ minute: this.initialDate.getMinutes()
28216
+ };
28217
+ }
28218
+ }
28219
+ return;
28220
+ }
28221
+ }
28222
+ }
28223
+ }
28224
+ /// Highlight initial range (start and end dates) on the calendar
28225
+ highlightInitialRange() {
28226
+ if (!this.initialRangeStart && !this.initialRangeEnd) {
28227
+ return;
28228
+ }
28229
+ const normalizedStartDate = this.initialRangeStart
28230
+ ? this._dateUtilsService.normalizeDateToString(this.initialRangeStart)
28231
+ : null;
28232
+ const normalizedEndDate = this.initialRangeEnd
28233
+ ? this._dateUtilsService.normalizeDateToString(this.initialRangeEnd)
28234
+ : null;
28235
+ let startDay = null;
28236
+ let endDay = null;
28237
+ // Find both start and end dates in the weeks array
28238
+ for (const week of this.weeks) {
28239
+ for (const day of week) {
28240
+ if (day && normalizedStartDate && day.gD === normalizedStartDate) {
28241
+ if (!this.isDateDisabled(day)) {
28242
+ startDay = day;
28243
+ }
28244
+ }
28245
+ if (day && normalizedEndDate && day.gD === normalizedEndDate) {
28246
+ if (!this.isDateDisabled(day)) {
28247
+ endDay = day;
28248
+ }
28249
+ }
28250
+ }
28251
+ }
28252
+ // Set range start
28253
+ if (startDay) {
28254
+ startDay.selected = true;
28255
+ this.rangeStart = startDay;
28256
+ this.selectedDay = startDay;
28257
+ // Initialize and attach time to start date
28258
+ if (this.enableTime) {
28259
+ if (!this.timeInitialized) {
28260
+ this.initializeTime();
28261
+ }
28262
+ if (this.initialRangeStart instanceof Date) {
28263
+ startDay.time = {
28264
+ hour: this.initialRangeStart.getHours(),
28265
+ minute: this.initialRangeStart.getMinutes()
28266
+ };
28267
+ }
28268
+ else {
28269
+ startDay.time = { ...this.selectedTime };
28270
+ }
28271
+ }
28272
+ }
28273
+ // Set range end if provided
28274
+ if (endDay && startDay) {
28275
+ // Swap if end is before start
28276
+ const startDate = this.parseDateString(startDay.gD);
28277
+ const endDate = this.parseDateString(endDay.gD);
28278
+ if (endDate && startDate && endDate < startDate) {
28279
+ // Swap
28280
+ this.rangeEnd = startDay;
28281
+ this.rangeStart = endDay;
28282
+ endDay.selected = true;
28283
+ }
28284
+ else {
28285
+ this.rangeEnd = endDay;
28286
+ }
28287
+ // Attach time to end date (inherit from start)
28288
+ if (this.enableTime) {
28289
+ const timeToUse = this.rangeStart.time || { ...this.selectedTime };
28290
+ if (this.initialRangeEnd instanceof Date) {
28291
+ this.rangeEnd.time = {
28292
+ hour: this.initialRangeEnd.getHours(),
28293
+ minute: this.initialRangeEnd.getMinutes()
28294
+ };
28295
+ }
28296
+ else {
28297
+ this.rangeEnd.time = { ...timeToUse };
28298
+ }
28299
+ // Ensure start also has time
28300
+ this.rangeStart.time = { ...timeToUse };
28301
+ }
28302
+ // Highlight the range
28303
+ this.highlightRange();
28304
+ this.selectedDay = this.rangeEnd;
28305
+ }
28306
+ }
28307
+ /// Generate month weeks
28308
+ generateWeeksArray(daysArray) {
28309
+ const firstDayName = daysArray[0]?.dN;
28310
+ const startIndex = this.weekdaysEn.indexOf(firstDayName);
28311
+ const weeks = [[]];
28312
+ let currentWeek = 0;
28313
+ let currentDayIndex = startIndex;
28314
+ daysArray?.forEach((day) => {
28315
+ if (!weeks[currentWeek]) {
28316
+ weeks[currentWeek] = [];
28317
+ }
28318
+ weeks[currentWeek][currentDayIndex] = day;
28319
+ currentDayIndex++;
28320
+ if (currentDayIndex === 7) {
28321
+ currentDayIndex = 0;
28322
+ currentWeek++;
28323
+ }
28324
+ });
28325
+ weeks.forEach((week) => {
28326
+ while (week.length < 7) {
28327
+ week.push({});
28328
+ }
28329
+ });
28330
+ return weeks;
28331
+ }
28332
+ /// Change calendar mode 'greg' or 'ummAlQura'
28333
+ changeCalendarMode() {
28334
+ this.mode = this.mode == 'greg' ? 'ummAlQura' : 'greg';
28335
+ this.initializeYearsAndMonths();
28336
+ this.generatetMonthData('01/' +
28337
+ this.periodForm.controls['month'].value +
28338
+ '/' +
28339
+ this.periodForm.controls['year'].value);
28340
+ }
28341
+ /// On day clicked handler
28342
+ onDayClicked(day) {
28343
+ if (day && day?.gD) {
28344
+ // Check if day is disabled by min/max constraints
28345
+ if (this.isDateDisabled(day)) {
28346
+ return; // Don't allow selection of disabled dates
28347
+ }
28348
+ if (this.futureValidation) {
28349
+ if (this.checkFutureValidation(day)) {
28350
+ this.futureValidationMessage = true;
28351
+ }
28352
+ else {
28353
+ this.futureValidationMessage = false;
28354
+ this.markDaySelected(day);
28355
+ }
28356
+ }
28357
+ else {
28358
+ this.markDaySelected(day);
28359
+ }
28360
+ }
28361
+ }
28362
+ /// Mark day as selected
28363
+ markDaySelected(dayInfo) {
28364
+ // BACKWARD COMPATIBILITY: Range selection only when selectionMode='range'
28365
+ if (this.selectionMode === 'range') {
28366
+ this.handleRangeSelection(dayInfo);
28367
+ return;
28368
+ }
28369
+ // BACKWARD COMPATIBILITY: Original behavior for single/multiple selection
28370
+ if (dayInfo.selected) {
28371
+ dayInfo.selected = false;
28372
+ this.multipleSelectedDates = this.multipleSelectedDates.filter((day) => day !== dayInfo);
28373
+ if (!this.multiple) {
28374
+ this.selectedDay = undefined;
28375
+ }
28376
+ }
28377
+ else {
28378
+ if (!this.multiple) {
28379
+ this.weeks.forEach((week) => {
28380
+ week.forEach((day) => {
28381
+ day.selected = false;
28382
+ });
28383
+ });
28384
+ dayInfo.selected = true;
28385
+ this.selectedDay = dayInfo;
28386
+ this.multipleSelectedDates = [dayInfo];
28387
+ // Attach current time if enableTime is active
28388
+ if (this.enableTime) {
28389
+ // Ensure time is initialized before attaching
28390
+ if (!this.timeInitialized) {
28391
+ this.initializeTime();
28392
+ }
28393
+ dayInfo.time = { ...this.selectedTime };
28394
+ }
28395
+ this.onDaySelect.emit(dayInfo);
28396
+ }
28397
+ else {
28398
+ dayInfo.selected = true;
28399
+ // Attach current time if enableTime is active
28400
+ if (this.enableTime) {
28401
+ // Ensure time is initialized before attaching
28402
+ if (!this.timeInitialized) {
28403
+ this.initializeTime();
28404
+ }
28405
+ dayInfo.time = { ...this.selectedTime };
28406
+ }
28407
+ this.onDaySelect.emit(dayInfo);
28408
+ if (!this.multipleSelectedDates.includes(dayInfo)) {
28409
+ this.multipleSelectedDates.push(dayInfo);
28410
+ }
28411
+ }
28412
+ }
28413
+ }
28414
+ /**
28415
+ * Handle range selection logic
28416
+ * BACKWARD COMPATIBILITY: Only called when selectionMode='range'
28417
+ *
28418
+ * Range selection lifecycle:
28419
+ * 1. First click → Sets rangeStart
28420
+ * 2. Second click → Sets rangeEnd, highlights range
28421
+ * 3. Third click → Resets range, starts new selection
28422
+ */
28423
+ handleRangeSelection(dayInfo) {
28424
+ // First click or resetting range
28425
+ if (!this.rangeStart || (this.rangeStart && this.rangeEnd)) {
28426
+ this.resetRange();
28427
+ this.rangeStart = dayInfo;
28428
+ dayInfo.selected = true;
28429
+ this.selectedDay = dayInfo;
28430
+ // Attach current time if enableTime is active
28431
+ if (this.enableTime) {
28432
+ // Ensure selectedTime is initialized
28433
+ // If time hasn't been initialized yet, initialize it now
28434
+ if (!this.timeInitialized) {
28435
+ this.initializeTime();
28436
+ }
28437
+ dayInfo.time = { ...this.selectedTime };
28438
+ }
28439
+ this.onDaySelect.emit({ start: dayInfo, end: null });
28440
+ }
28441
+ // Second click - complete the range
28442
+ else if (this.rangeStart && !this.rangeEnd) {
28443
+ const startDate = this.parseDateString(this.rangeStart.gD);
28444
+ const endDate = this.parseDateString(dayInfo.gD);
28445
+ // Swap if end is before start
28446
+ if (endDate && startDate && endDate < startDate) {
28447
+ this.rangeEnd = this.rangeStart;
28448
+ this.rangeStart = dayInfo;
28449
+ }
28450
+ else {
28451
+ this.rangeEnd = dayInfo;
28452
+ }
28453
+ // Attach time if enableTime is active
28454
+ // IMPORTANT: Range end inherits time from range start (not current selectedTime)
28455
+ if (this.enableTime) {
28456
+ // Use rangeStart's time if it exists, otherwise use current selectedTime
28457
+ const timeToUse = this.rangeStart.time || { ...this.selectedTime };
28458
+ this.rangeStart.time = { ...timeToUse };
28459
+ this.rangeEnd.time = { ...timeToUse };
28460
+ }
28461
+ this.highlightRange();
28462
+ this.selectedDay = this.rangeEnd;
28463
+ this.onDaySelect.emit({ start: this.rangeStart, end: this.rangeEnd });
28464
+ }
28465
+ }
28466
+ /// On confirm button clicked
28467
+ onConfirmClicked() {
28468
+ // BACKWARD COMPATIBILITY: Range selection output when selectionMode='range'
28469
+ if (this.selectionMode === 'range') {
28470
+ if (this.rangeStart && this.rangeEnd) {
28471
+ // Collect all dates in range
28472
+ const rangeDates = [];
28473
+ this.weeks.forEach((week) => {
28474
+ week.forEach((day) => {
28475
+ if (day && day.gD && (this.isInRange(day) || this.isRangeStart(day) || this.isRangeEnd(day))) {
28476
+ // Attach current time if enableTime is active
28477
+ if (this.enableTime && !day.time) {
28478
+ day.time = { ...this.selectedTime };
28479
+ }
28480
+ rangeDates.push(day);
28481
+ }
28482
+ });
28483
+ });
28484
+ this.onSubmit.emit({
28485
+ start: this.rangeStart,
28486
+ end: this.rangeEnd,
28487
+ dates: rangeDates
28488
+ });
28489
+ }
28490
+ else {
28491
+ // Incomplete range
28492
+ this.onSubmit.emit({ start: this.rangeStart, end: null, dates: [] });
28493
+ }
28494
+ return;
28495
+ }
28496
+ // BACKWARD COMPATIBILITY: Original behavior for multiple/single selection
28497
+ if (this.multiple) {
28498
+ // For multiple dates, attach time to each if enableTime is active
28499
+ if (this.enableTime) {
28500
+ this.multipleSelectedDates.forEach((day) => {
28501
+ if (!day.time) {
28502
+ day.time = { ...this.selectedTime };
28503
+ }
28504
+ });
28505
+ }
28506
+ this.onSubmit.emit(this.multipleSelectedDates);
28507
+ }
28508
+ else {
28509
+ // For single date, attach time if enableTime is active
28510
+ if (this.enableTime && this.selectedDay) {
28511
+ this.selectedDay.time = { ...this.selectedTime };
28512
+ }
28513
+ this.onSubmit.emit(this.selectedDay);
28514
+ }
28515
+ }
28516
+ /// Check if date from future
28517
+ checkFutureValidation(day) {
28518
+ if (this._dateUtilsService.checkPastOrFuture(day?.gD, new Date()) == 'Future') {
28519
+ return true;
28520
+ }
28521
+ }
28522
+ /// Check if passed day is today or not
28523
+ checkTodaysDate(day) {
28524
+ return (this.todaysDate?.gregorian == day?.gD ||
28525
+ this.todaysDate?.ummAlQura == day?.uD);
28526
+ }
28527
+ /**
28528
+ * Check if a day is disabled based on min/max date constraints
28529
+ * Works for both Gregorian and Hijri modes
28530
+ */
28531
+ isDateDisabled(day) {
28532
+ if (!day || !day.gD)
28533
+ return true;
28534
+ // Normalize min/max dates to Gregorian DD/MM/YYYY format
28535
+ const minDateStr = this.minDate
28536
+ ? this._dateUtilsService.normalizeDateToString(this.minDate)
28537
+ : null;
28538
+ const maxDateStr = this.maxDate
28539
+ ? this._dateUtilsService.normalizeDateToString(this.maxDate)
28540
+ : null;
28541
+ // Check if the day's Gregorian date is within range
28542
+ return !this._dateUtilsService.isDateInRange(day.gD, minDateStr, maxDateStr);
28543
+ }
28544
+ /**
28545
+ * Initialize time from current system time or initialDate
28546
+ * BACKWARD COMPATIBILITY: Only called when enableTime=true
28547
+ *
28548
+ * Priority:
28549
+ * 1. If initialDate has time, use that
28550
+ * 2. If selectedDay has time, use that
28551
+ * 3. Otherwise, use current system time
28552
+ */
28553
+ initializeTime() {
28554
+ let timeSet = false;
28555
+ // Check if initialDate has time information
28556
+ if (this.initialDate && this.initialDate instanceof Date) {
28557
+ this.selectedTime = {
28558
+ hour: this.initialDate.getHours(),
28559
+ minute: this.initialDate.getMinutes(),
28560
+ };
28561
+ timeSet = true;
28562
+ }
28563
+ // If no time from initialDate, use current system time
28564
+ if (!timeSet) {
28565
+ const now = new Date();
28566
+ this.selectedTime = {
28567
+ hour: now.getHours(),
28568
+ minute: now.getMinutes(),
28569
+ };
28570
+ }
28571
+ // Mark that time has been initialized
28572
+ this.timeInitialized = true;
28573
+ // BACKWARD COMPATIBILITY: Only set meridian when useMeridian=true
28574
+ if (this.useMeridian) {
28575
+ this.meridian = this.selectedTime.hour >= 12 ? 'PM' : 'AM';
28576
+ }
28577
+ }
28578
+ /**
28579
+ * Increment hour value with wraparound (0-23)
28580
+ * BACKWARD COMPATIBILITY: Only available when enableTime=true
28581
+ */
28582
+ incrementHour() {
28583
+ this.selectedTime.hour = (this.selectedTime.hour + 1) % 24;
28584
+ this.updateSelectedDayTime();
28585
+ }
28586
+ /**
28587
+ * Decrement hour value with wraparound (0-23)
28588
+ * BACKWARD COMPATIBILITY: Only available when enableTime=true
28589
+ */
28590
+ decrementHour() {
28591
+ this.selectedTime.hour = (this.selectedTime.hour - 1 + 24) % 24;
28592
+ this.updateSelectedDayTime();
28593
+ }
28594
+ /**
28595
+ * Increment minute value with wraparound (0-59)
28596
+ * BACKWARD COMPATIBILITY: Only available when enableTime=true
28597
+ */
28598
+ incrementMinute() {
28599
+ this.selectedTime.minute = (this.selectedTime.minute + 1) % 60;
28600
+ this.updateSelectedDayTime();
28601
+ }
28602
+ /**
28603
+ * Decrement minute value with wraparound (0-59)
28604
+ * BACKWARD COMPATIBILITY: Only available when enableTime=true
28605
+ */
28606
+ decrementMinute() {
28607
+ this.selectedTime.minute = (this.selectedTime.minute - 1 + 60) % 60;
28608
+ this.updateSelectedDayTime();
28609
+ }
28610
+ /**
28611
+ * Handle keyboard input for hours
28612
+ * Validates and clamps to 0-23 range
28613
+ * BACKWARD COMPATIBILITY: Only available when enableTime=true
28614
+ */
28615
+ onHourInputChange(event) {
28616
+ let value = parseInt(event.target.value, 10);
28617
+ if (isNaN(value) || value < 0) {
28618
+ value = 0;
28619
+ }
28620
+ else if (value > 23) {
28621
+ value = 23;
28622
+ }
28623
+ this.selectedTime.hour = value;
28624
+ event.target.value = value;
28625
+ this.updateSelectedDayTime();
28626
+ }
28627
+ /**
28628
+ * Handle keyboard input for minutes
28629
+ * Validates and clamps to 0-59 range
28630
+ * BACKWARD COMPATIBILITY: Only available when enableTime=true
28631
+ */
28632
+ onMinuteInputChange(event) {
28633
+ let value = parseInt(event.target.value, 10);
28634
+ if (isNaN(value) || value < 0) {
28635
+ value = 0;
28636
+ }
28637
+ else if (value > 59) {
28638
+ value = 59;
28639
+ }
28640
+ this.selectedTime.minute = value;
28641
+ event.target.value = value;
28642
+ this.updateSelectedDayTime();
28643
+ }
28644
+ /**
28645
+ * Handle keyboard arrow keys for hour/minute input
28646
+ * BACKWARD COMPATIBILITY: Only available when enableTime=true
28647
+ */
28648
+ onTimeKeydown(event, type) {
28649
+ if (event.key === 'ArrowUp') {
28650
+ event.preventDefault();
28651
+ if (type === 'hour') {
28652
+ this.incrementHour();
28653
+ }
28654
+ else {
28655
+ this.incrementMinute();
28656
+ }
28657
+ }
28658
+ else if (event.key === 'ArrowDown') {
28659
+ event.preventDefault();
28660
+ if (type === 'hour') {
28661
+ this.decrementHour();
28662
+ }
28663
+ else {
28664
+ this.decrementMinute();
28665
+ }
28666
+ }
28667
+ }
28668
+ /**
28669
+ * Update the selected day's time property when time changes
28670
+ * BACKWARD COMPATIBILITY: Only called when enableTime=true
28671
+ */
28672
+ updateSelectedDayTime() {
28673
+ if (this.selectedDay) {
28674
+ this.selectedDay.time = { ...this.selectedTime };
28675
+ }
28676
+ }
28677
+ /**
28678
+ * Get display hour for 12-hour format
28679
+ * BACKWARD COMPATIBILITY: Only used when useMeridian=true
28680
+ *
28681
+ * Conversion:
28682
+ * - 0 (midnight) → 12 AM
28683
+ * - 1-11 (AM) → 1-11 AM
28684
+ * - 12 (noon) → 12 PM
28685
+ * - 13-23 (PM) → 1-11 PM
28686
+ *
28687
+ * IMPORTANT: Hour 0 is NEVER displayed as 0, always as 12
28688
+ */
28689
+ getDisplayHour() {
28690
+ if (!this.useMeridian) {
28691
+ return this.selectedTime.hour;
28692
+ }
28693
+ const hour = this.selectedTime.hour;
28694
+ // Midnight (0) → 12
28695
+ if (hour === 0) {
28696
+ return 12;
28697
+ }
28698
+ // 1-12 → 1-12 (no change)
28699
+ else if (hour <= 12) {
28700
+ return hour;
28701
+ }
28702
+ // 13-23 → 1-11 (subtract 12)
28703
+ else {
28704
+ return hour - 12;
28705
+ }
28706
+ }
28707
+ /**
28708
+ * Toggle AM/PM meridian
28709
+ * BACKWARD COMPATIBILITY: Only available when useMeridian=true
28710
+ *
28711
+ * When toggling:
28712
+ * - Adds or subtracts 12 hours
28713
+ * - Maintains internal 24-hour format
28714
+ */
28715
+ toggleMeridian() {
28716
+ if (this.meridian === 'AM') {
28717
+ this.meridian = 'PM';
28718
+ // Add 12 hours if not already in PM range
28719
+ if (this.selectedTime.hour < 12) {
28720
+ this.selectedTime.hour += 12;
28721
+ }
28722
+ }
28723
+ else {
28724
+ this.meridian = 'AM';
28725
+ // Subtract 12 hours if in PM range
28726
+ if (this.selectedTime.hour >= 12) {
28727
+ this.selectedTime.hour -= 12;
28728
+ }
28729
+ }
28730
+ this.updateSelectedDayTime();
28731
+ }
28732
+ /**
28733
+ * Increment hour in 12-hour mode
28734
+ * BACKWARD COMPATIBILITY: Only used when useMeridian=true
28735
+ */
28736
+ incrementHour12() {
28737
+ let displayHour = this.getDisplayHour();
28738
+ displayHour = (displayHour % 12) + 1; // 1-12 cycle
28739
+ // Convert back to 24-hour format
28740
+ if (this.meridian === 'AM') {
28741
+ this.selectedTime.hour = displayHour === 12 ? 0 : displayHour;
28742
+ }
28743
+ else {
28744
+ this.selectedTime.hour = displayHour === 12 ? 12 : displayHour + 12;
28745
+ }
28746
+ this.updateSelectedDayTime();
28747
+ }
28748
+ /**
28749
+ * Decrement hour in 12-hour mode
28750
+ * BACKWARD COMPATIBILITY: Only used when useMeridian=true
28751
+ */
28752
+ decrementHour12() {
28753
+ let displayHour = this.getDisplayHour();
28754
+ displayHour = displayHour === 1 ? 12 : displayHour - 1; // 1-12 cycle
28755
+ // Convert back to 24-hour format
28756
+ if (this.meridian === 'AM') {
28757
+ this.selectedTime.hour = displayHour === 12 ? 0 : displayHour;
28758
+ }
28759
+ else {
28760
+ this.selectedTime.hour = displayHour === 12 ? 12 : displayHour + 12;
28761
+ }
28762
+ this.updateSelectedDayTime();
28763
+ }
28764
+ /**
28765
+ * Handle 12-hour input change
28766
+ * BACKWARD COMPATIBILITY: Only used when useMeridian=true
28767
+ *
28768
+ * IMPORTANT: Input must be 1-12, never 0
28769
+ * - User types 0 → converted to 12
28770
+ * - User types > 12 → clamped to 12
28771
+ */
28772
+ onHour12InputChange(event) {
28773
+ let value = parseInt(event.target.value, 10);
28774
+ // Validate 1-12 range (0 is not allowed in 12-hour format)
28775
+ if (isNaN(value) || value < 1 || value === 0) {
28776
+ value = 12; // Default to 12 if invalid or 0
28777
+ }
28778
+ else if (value > 12) {
28779
+ value = 12;
28780
+ }
28781
+ // Convert to 24-hour format
28782
+ if (this.meridian === 'AM') {
28783
+ this.selectedTime.hour = value === 12 ? 0 : value;
28784
+ }
28785
+ else {
28786
+ this.selectedTime.hour = value === 12 ? 12 : value + 12;
28787
+ }
28788
+ event.target.value = value;
28789
+ this.updateSelectedDayTime();
28790
+ }
28791
+ /**
28792
+ * Check if a date is within the current range
28793
+ * BACKWARD COMPATIBILITY: Only used when selectionMode='range'
28794
+ */
28795
+ isInRange(day) {
28796
+ if (this.selectionMode !== 'range' || !this.rangeStart || !this.rangeEnd || !day?.gD) {
28797
+ return false;
28798
+ }
28799
+ const dayDate = this.parseDateString(day.gD);
28800
+ const startDate = this.parseDateString(this.rangeStart.gD);
28801
+ const endDate = this.parseDateString(this.rangeEnd.gD);
28802
+ if (!dayDate || !startDate || !endDate) {
28803
+ return false;
28804
+ }
28805
+ return dayDate >= startDate && dayDate <= endDate;
28806
+ }
28807
+ /**
28808
+ * Check if a date is the range start
28809
+ * BACKWARD COMPATIBILITY: Only used when selectionMode='range'
28810
+ */
28811
+ isRangeStart(day) {
28812
+ return this.selectionMode === 'range' &&
28813
+ this.rangeStart?.gD === day?.gD;
28814
+ }
28815
+ /**
28816
+ * Check if a date is the range end
28817
+ * BACKWARD COMPATIBILITY: Only used when selectionMode='range'
28818
+ */
28819
+ isRangeEnd(day) {
28820
+ return this.selectionMode === 'range' &&
28821
+ this.rangeEnd?.gD === day?.gD;
28822
+ }
28823
+ /**
28824
+ * Reset range selection
28825
+ * BACKWARD COMPATIBILITY: Only used when selectionMode='range'
28826
+ */
28827
+ resetRange() {
28828
+ if (this.selectionMode !== 'range') {
28829
+ return;
28830
+ }
28831
+ // Clear range highlighting
28832
+ this.weeks.forEach((week) => {
28833
+ week.forEach((day) => {
28834
+ if (day && day.gD) {
28835
+ day.selected = false;
28836
+ }
28837
+ });
28838
+ });
28839
+ this.rangeStart = undefined;
28840
+ this.rangeEnd = undefined;
28841
+ this.selectedDay = undefined;
28842
+ }
28843
+ /**
28844
+ * Parse date string (DD/MM/YYYY) to Date object
28845
+ * Helper for range comparison
28846
+ */
28847
+ parseDateString(dateStr) {
28848
+ if (!dateStr)
28849
+ return null;
28850
+ const parts = dateStr.split('/');
28851
+ if (parts.length !== 3)
28852
+ return null;
28853
+ const day = parseInt(parts[0], 10);
28854
+ const month = parseInt(parts[1], 10) - 1; // Month is 0-indexed
28855
+ const year = parseInt(parts[2], 10);
28856
+ return new Date(year, month, day);
28857
+ }
28858
+ /**
28859
+ * Highlight all dates in range
28860
+ * BACKWARD COMPATIBILITY: Only used when selectionMode='range'
28861
+ */
28862
+ highlightRange() {
28863
+ if (this.selectionMode !== 'range' || !this.rangeStart || !this.rangeEnd) {
28864
+ return;
28865
+ }
28866
+ this.weeks.forEach((week) => {
28867
+ week.forEach((day) => {
28868
+ if (day && day.gD) {
28869
+ day.selected = this.isInRange(day) ||
28870
+ this.isRangeStart(day) ||
28871
+ this.isRangeEnd(day);
28872
+ }
28873
+ });
28874
+ });
28875
+ }
28876
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: HijriGregorianDatepickerComponent, deps: [{ token: i1.UntypedFormBuilder }, { token: DateUtilitiesService }], target: i0.ɵɵFactoryTarget.Component }); }
28877
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: HijriGregorianDatepickerComponent, isStandalone: false, selector: "hijri-gregorian-datepicker", inputs: { markToday: "markToday", canChangeMode: "canChangeMode", todaysDateSection: "todaysDateSection", futureValidation: "futureValidation", disableYearPicker: "disableYearPicker", disableMonthPicker: "disableMonthPicker", disableDayPicker: "disableDayPicker", multiple: "multiple", isRequired: "isRequired", showConfirmButton: "showConfirmButton", futureValidationMessage: "futureValidationMessage", arabicLayout: "arabicLayout", mode: "mode", dir: "dir", locale: "locale", submitTextButton: "submitTextButton", todaysDateText: "todaysDateText", ummAlQuraDateText: "ummAlQuraDateText", monthSelectLabel: "monthSelectLabel", yearSelectLabel: "yearSelectLabel", futureValidationMessageEn: "futureValidationMessageEn", futureValidationMessageAr: "futureValidationMessageAr", theme: "theme", pastYearsLimit: "pastYearsLimit", futureYearsLimit: "futureYearsLimit", styles: "styles", enableTime: "enableTime", minDate: "minDate", maxDate: "maxDate", initialDate: "initialDate", initialRangeStart: "initialRangeStart", initialRangeEnd: "initialRangeEnd", useMeridian: "useMeridian", selectionMode: "selectionMode" }, outputs: { onSubmit: "onSubmit", onDaySelect: "onDaySelect", onMonthChange: "onMonthChange", onYearChange: "onYearChange" }, host: { properties: { "style.font-family": "this.fontFamilyStyle" } }, usesOnChanges: true, ngImport: i0, template: "<div class=\"calendar-container\" [dir]=\"dir\" [attr.lang]=\"locale\">\r\n <div\r\n class=\"toggle-section\"\r\n [dir]=\"dir\"\r\n *ngIf=\"canChangeMode\"\r\n [ngStyle]=\"{ color: styles.primaryColor }\"\r\n >\r\n <span> {{ ummAlQuraDateText }} </span>\r\n <label class=\"switch\">\r\n <input\r\n type=\"checkbox\"\r\n [disabled]=\"!canChangeMode\"\r\n [checked]=\"mode === 'ummAlQura'\"\r\n (change)=\"changeCalendarMode()\"\r\n #calendarCheckbox\r\n />\r\n <span\r\n class=\"slider\"\r\n [ngStyle]=\"\r\n calendarCheckbox.checked\r\n ? { 'background-color': styles.primaryColor }\r\n : { 'background-color': styles.backgroundColor }\r\n \"\r\n ></span>\r\n </label>\r\n </div>\r\n\r\n <div\r\n class=\"todays-date-section\"\r\n *ngIf=\"todaysDateSection\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.backgroundColor,\r\n color: styles.primaryColor,\r\n 'border-radius': styles.borderRadius\r\n }\"\r\n >\r\n <div\r\n class=\"text-info\"\r\n [ngClass]=\"{\r\n order: dir == 'rtl'\r\n }\"\r\n >\r\n <p>{{ todaysDateText }}</p>\r\n </div>\r\n\r\n <div\r\n class=\"data\"\r\n [dir]=\"dir\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.todaysDateBgColor,\r\n color: styles.todaysDateTextColor\r\n }\"\r\n >\r\n <p *ngIf=\"mode == 'ummAlQura'\">\r\n <!-- {{todaysDate.ummAlQura}} -->\r\n {{\r\n locale == \"ar\"\r\n ? _dateUtilsService.convertDateNumerals(todaysDate.ummAlQura, \"ar\")\r\n : todaysDate.ummAlQura\r\n }}\r\n </p>\r\n <p *ngIf=\"mode == 'greg'\">\r\n {{\r\n locale == \"ar\"\r\n ? _dateUtilsService.convertDateNumerals(todaysDate.gregorian, \"ar\")\r\n : todaysDate.gregorian\r\n }}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n <div class=\"period-container\">\r\n <form [formGroup]=\"periodForm\" class=\"period-form\">\r\n <div\r\n class=\"select-item\"\r\n [ngClass]=\"{\r\n order: dir == 'ltr'\r\n }\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.backgroundColor,\r\n 'border-radius': styles.borderRadius\r\n }\"\r\n >\r\n <label *ngIf=\"!periodForm.controls['year'].value\">{{\r\n yearSelectLabel\r\n }}</label>\r\n\r\n <select\r\n formControlName=\"year\"\r\n class=\"{{ 'icon-' + dir }}\"\r\n placeholder=\"\u0627\u0644\u0633\u0646\u0629\"\r\n (change)=\"onPeriodChange('year')\"\r\n [dir]=\"dir\"\r\n [ngStyle]=\"{\r\n color: styles.primaryColor,\r\n 'font-family': styles.fontFamily\r\n }\"\r\n >\r\n <option *ngFor=\"let year of years\" [ngValue]=\"year\">\r\n {{ locale == \"ar\" ? _dateUtilsService.parseEnglish(year) : year }}\r\n </option>\r\n </select>\r\n </div>\r\n\r\n <div\r\n class=\"select-item\"\r\n [ngClass]=\"{\r\n order: dir == 'rtl'\r\n }\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.backgroundColor,\r\n 'border-radius': styles.borderRadius\r\n }\"\r\n >\r\n <label *ngIf=\"!periodForm.controls['month'].value\">{{\r\n monthSelectLabel\r\n }}</label>\r\n <select\r\n class=\"{{ 'icon-' + dir }}\"\r\n formControlName=\"month\"\r\n (change)=\"onPeriodChange('month')\"\r\n [dir]=\"dir\"\r\n [ngStyle]=\"{\r\n color: styles.primaryColor,\r\n 'font-family': styles.fontFamily\r\n }\"\r\n >\r\n <option *ngFor=\"let month of months\" [ngValue]=\"month.value\">\r\n {{ locale == \"ar\" ? month?.labelAr : month?.labelEn }}\r\n </option>\r\n </select>\r\n </div>\r\n </form>\r\n </div>\r\n\r\n <div\r\n class=\"calendar-layout\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.backgroundColor,\r\n 'border-radius': styles.borderRadius\r\n }\"\r\n >\r\n <div class=\"week-days\">\r\n <div\r\n class=\"week-day\"\r\n [ngStyle]=\"{ color: styles.dayNameColor }\"\r\n *ngFor=\"let date of locale == 'ar' ? weekdaysAr : weekdaysEn\"\r\n >\r\n {{ date }}\r\n </div>\r\n </div>\r\n\r\n <div [dir]=\"dir\">\r\n <div class=\"week\" *ngFor=\"let week of weeks\">\r\n <div\r\n class=\"day\"\r\n *ngFor=\"let day of week\"\r\n (click)=\"disableDayPicker == false ? onDayClicked(day) : ''\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.backgroundColor,\r\n color: styles.dayColor\r\n }\"\r\n >\r\n <div\r\n id=\"greg-day\"\r\n [ngClass]=\"{\r\n 'todays-date': checkTodaysDate(day),\r\n 'selected-date': day?.selected == true\r\n }\"\r\n [ngStyle]=\"{\r\n border:\r\n markToday && checkTodaysDate(day)\r\n ? '1px solid ' + styles.secondaryColor\r\n : '',\r\n 'background-color':\r\n day?.selected == true ? styles.secondaryColor : '',\r\n color:\r\n (day?.selected == true ? styles.todaysDateTextColor : '') ||\r\n (checkFutureValidation(day) && futureValidation\r\n ? styles.disabledDayColor\r\n : '') ||\r\n (isDateDisabled(day) ? styles.disabledDayColor : ''),\r\n opacity: isDateDisabled(day) ? '0.4' : '1',\r\n cursor: isDateDisabled(day) ? 'not-allowed' : 'pointer'\r\n }\"\r\n >\r\n <span *ngIf=\"mode == 'greg'\">{{\r\n locale == \"ar\"\r\n ? _dateUtilsService.parseEnglish(\r\n day?.gD?.split(\"/\")[0] | number\r\n )\r\n : (day?.gD?.split(\"/\")[0] | number)\r\n }}</span>\r\n\r\n <span id=\"ummAlQura-day\" *ngIf=\"mode == 'ummAlQura'\">{{\r\n locale == \"ar\"\r\n ? _dateUtilsService.parseEnglish(\r\n day?.uD?.split(\"/\")[0] | number\r\n )\r\n : (day?.uD?.split(\"/\")[0] | number)\r\n }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"future-validation\" dir=\"auto\" *ngIf=\"futureValidationMessage\">\r\n <span *ngIf=\"locale == 'ar'\">\r\n {{ futureValidationMessageAr }}\r\n </span>\r\n <span *ngIf=\"locale == 'en'\">\r\n {{ futureValidationMessageEn }}\r\n </span>\r\n </div>\r\n\r\n <!-- Time Picker Section -->\r\n <!-- BACKWARD COMPATIBILITY: This section only renders when enableTime=true -->\r\n <div class=\"time-picker-section\" *ngIf=\"enableTime\" [dir]=\"'ltr'\">\r\n <div class=\"time-picker-wrapper\">\r\n <!-- Hour Input with Arrows -->\r\n <div class=\"time-input-container\">\r\n <button\r\n type=\"button\"\r\n class=\"time-arrow time-arrow-up\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.timePickerBgColor || '#ffffff',\r\n 'border-color': styles.timePickerBorderColor || '#ddd',\r\n color: styles.timePickerArrowColor || '#5b479c'\r\n }\"\r\n (click)=\"useMeridian ? incrementHour12() : incrementHour()\"\r\n tabindex=\"-1\"\r\n aria-label=\"Increment hour\"\r\n >\r\n <i class=\"ri-arrow-drop-up-line\"></i>\r\n </button>\r\n <input\r\n type=\"number\"\r\n class=\"time-field\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.timePickerBgColor || '#ffffff',\r\n 'border-color': styles.timePickerBorderColor || '#ddd',\r\n color: styles.timePickerTextColor || '#333'\r\n }\"\r\n [value]=\"getDisplayHour().toString().padStart(2, '0')\"\r\n (input)=\"\r\n useMeridian\r\n ? onHour12InputChange($event)\r\n : onHourInputChange($event)\r\n \"\r\n (keydown)=\"onTimeKeydown($event, 'hour')\"\r\n [min]=\"useMeridian ? 1 : 0\"\r\n [max]=\"useMeridian ? 12 : 23\"\r\n aria-label=\"Hour\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"time-arrow time-arrow-down\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.timePickerBgColor || '#ffffff',\r\n 'border-color': styles.timePickerBorderColor || '#ddd',\r\n color: styles.timePickerArrowColor || '#5b479c'\r\n }\"\r\n (click)=\"useMeridian ? decrementHour12() : decrementHour()\"\r\n tabindex=\"-1\"\r\n aria-label=\"Decrement hour\"\r\n >\r\n <i class=\"ri-arrow-drop-down-line\"></i>\r\n </button>\r\n </div>\r\n\r\n <!-- Colon Separator -->\r\n <span\r\n class=\"time-colon\"\r\n [ngStyle]=\"{\r\n color: styles.timePickerColonColor || '#5b479c'\r\n }\"\r\n >:</span\r\n >\r\n\r\n <!-- Minute Input with Arrows -->\r\n <div class=\"time-input-container\">\r\n <button\r\n type=\"button\"\r\n class=\"time-arrow time-arrow-up\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.timePickerBgColor || '#ffffff',\r\n 'border-color': styles.timePickerBorderColor || '#ddd',\r\n color: styles.timePickerArrowColor || '#5b479c'\r\n }\"\r\n (click)=\"incrementMinute()\"\r\n tabindex=\"-1\"\r\n aria-label=\"Increment minute\"\r\n >\r\n <i class=\"ri-arrow-drop-up-line\"></i>\r\n </button>\r\n <input\r\n type=\"number\"\r\n class=\"time-field\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.timePickerBgColor || '#ffffff',\r\n 'border-color': styles.timePickerBorderColor || '#ddd',\r\n color: styles.timePickerTextColor || '#333'\r\n }\"\r\n [value]=\"selectedTime.minute.toString().padStart(2, '0')\"\r\n (input)=\"onMinuteInputChange($event)\"\r\n (keydown)=\"onTimeKeydown($event, 'minute')\"\r\n min=\"0\"\r\n max=\"59\"\r\n aria-label=\"Minute\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"time-arrow time-arrow-down\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.timePickerBgColor || '#ffffff',\r\n 'border-color': styles.timePickerBorderColor || '#ddd',\r\n color: styles.timePickerArrowColor || '#5b479c'\r\n }\"\r\n (click)=\"decrementMinute()\"\r\n tabindex=\"-1\"\r\n aria-label=\"Decrement minute\"\r\n >\r\n <i class=\"ri-arrow-drop-down-line\"></i>\r\n </button>\r\n </div>\r\n\r\n <!-- AM/PM Button Group (only when useMeridian=true) -->\r\n <!-- BACKWARD COMPATIBILITY: This only renders when useMeridian=true -->\r\n <div class=\"meridian-toggle-group\" *ngIf=\"useMeridian\">\r\n <button\r\n type=\"button\"\r\n class=\"meridian-btn\"\r\n [class.active]=\"meridian === 'AM'\"\r\n [ngStyle]=\"\r\n meridian === 'AM'\r\n ? {\r\n 'background-color':\r\n styles.meridianActiveBgColor || 'rgb(0, 77, 97)',\r\n 'border-color':\r\n styles.meridianActiveBgColor || 'rgb(0, 77, 97)',\r\n color: styles.meridianActiveTextColor || '#ffffff'\r\n }\r\n : {\r\n 'background-color': styles.meridianBgColor || '#ffffff',\r\n 'border-color': styles.timePickerBorderColor || '#ddd',\r\n color: styles.meridianTextColor || '#666'\r\n }\r\n \"\r\n (click)=\"meridian !== 'AM' && toggleMeridian()\"\r\n aria-label=\"Select AM\"\r\n >\r\n AM\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"meridian-btn\"\r\n [class.active]=\"meridian === 'PM'\"\r\n [ngStyle]=\"\r\n meridian === 'PM'\r\n ? {\r\n 'background-color':\r\n styles.meridianActiveBgColor || 'rgb(0, 77, 97)',\r\n 'border-color':\r\n styles.meridianActiveBgColor || 'rgb(0, 77, 97)',\r\n color: styles.meridianActiveTextColor || '#ffffff'\r\n }\r\n : {\r\n 'background-color': styles.meridianBgColor || '#ffffff',\r\n 'border-color': styles.timePickerBorderColor || '#ddd',\r\n color: styles.meridianTextColor || '#666'\r\n }\r\n \"\r\n (click)=\"meridian !== 'PM' && toggleMeridian()\"\r\n aria-label=\"Select PM\"\r\n >\r\n PM\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div>\r\n <button\r\n type=\"button\"\r\n class=\"confirm-btn\"\r\n [disabled]=\"\r\n isRequired &&\r\n ((!selectedDay && !multiple) ||\r\n (!multipleSelectedDates.length && multiple))\r\n \"\r\n (click)=\"onConfirmClicked()\"\r\n *ngIf=\"showConfirmButton\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.secondaryColor,\r\n color: styles.confirmBtnTextColor,\r\n 'font-family': styles.fontFamily,\r\n 'border-radius': styles.borderRadius\r\n }\"\r\n >\r\n {{ submitTextButton }}\r\n </button>\r\n </div>\r\n</div>\r\n", styles: [".calendar-container{margin:auto;display:block;border-radius:20px;font-family:Poppins,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-weight:400}.calendar-container[dir=rtl],.calendar-container[lang=ar]{font-family:Zain,Arabic Typesetting,Tahoma,sans-serif;font-weight:300;letter-spacing:0;line-height:1.7}.calendar-container .todays-date-section{border-radius:4px;margin-top:12px;display:flex;align-items:center;justify-content:space-between;padding-left:10px;padding-right:10px}.calendar-container .todays-date-section .text-info{display:flex;align-items:center}.calendar-container .todays-date-section .text-info p{font-size:17px;font-weight:500;letter-spacing:.02em}[dir=rtl] .calendar-container .todays-date-section .text-info p,[lang=ar] .calendar-container .todays-date-section .text-info p{font-weight:400;letter-spacing:0}[dir=rtl] .calendar-container .todays-date-section .data p,[lang=ar] .calendar-container .todays-date-section .data p{font-weight:300}.calendar-container .todays-date-section .data{border-radius:8px}.calendar-container .todays-date-section .data p{font-size:14px;font-weight:400;margin:5px 10px}.calendar-container .period-container{display:flex;justify-content:space-between;margin-top:8px}.calendar-container .period-container .period-form{width:100%;display:flex;justify-content:space-between}.calendar-container .period-container .period-form .select-item{width:42.5%;border-radius:4px;height:50px;padding-left:10px;padding-right:10px}.calendar-container .period-container .period-form label{margin-right:10px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .calendar-container .period-container .period-form label,[lang=ar] .calendar-container .period-container .period-form label{font-weight:400}.calendar-container .period-container .period-form select{width:100%;height:50px;border:none;font-size:16px;font-weight:500;display:block;margin:auto;background:url(\"data:image/svg+xml;utf8,<svg viewBox='0 0 140 140' width='15' height='15' xmlns='http://www.w3.org/2000/svg'><g><path d='m121.3,34.6c-1.6-1.6-4.2-1.6-5.8,0l-51,51.1-51.1-51.1c-1.6-1.6-4.2-1.6-5.8,0-1.6,1.6-1.6,4.2 0,5.8l53.9,53.9c0.8,0.8 1.8,1.2 2.9,1.2 1,0 2.1-0.4 2.9-1.2l53.9-53.9c1.7-1.6 1.7-4.2 0.1-5.8z' fill='black'/></g></svg>\") no-repeat 95% 50%;-moz-appearance:none;-webkit-appearance:none;appearance:none;cursor:pointer}.calendar-container .period-container .period-form select option,.calendar-container [dir=rtl] .period-container select{font-weight:400}.calendar-container [dir=rtl] .period-container select option{font-weight:300}.icon-ltr{background-position:right}.icon-rtl{background-position:left!important}select:focus{outline:none}.calendar-layout{border-radius:4px;margin:8px auto auto;display:block;padding-bottom:5px}.calendar-layout .week-days{text-align:center;margin-top:5px;display:flex;justify-content:space-evenly}.calendar-layout .week-days .week-day{display:inline-block;width:13%;text-align:center;padding:15px 0 10px;font-weight:600;font-size:13px;text-transform:uppercase;letter-spacing:.05em}[dir=rtl] .calendar-layout .week-days{flex-direction:row-reverse!important}[dir=rtl] .calendar-layout .week-days .week-day{font-weight:700;letter-spacing:0;text-transform:none;font-size:14px}.calendar-layout .week{text-align:center;display:flex;justify-content:space-evenly}.calendar-layout .day{display:inline-flex;width:13%;height:5.5vh;justify-content:center;align-items:center;cursor:pointer;font-weight:500;transition:all .2s ease;border-radius:4px}.calendar-layout .day:hover:not(.disabled-day){transform:scale(1.05)}[dir=rtl] .calendar-layout .day{font-weight:400}.calendar-layout #greg-day{position:relative;min-width:20px}.calendar-layout #greg-day span{font-size:14px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .calendar-layout #greg-day span,[lang=ar] .calendar-layout #greg-day span{font-weight:400}.calendar-layout #ummAlQura-day{font-size:11px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .calendar-layout #ummAlQura-day,[lang=ar] .calendar-layout #ummAlQura-day{font-weight:400}.calendar-layout .todays-date,.calendar-layout .selected-date{padding:10px;border-radius:5px}.confirm-btn{height:50px;width:100%;border:none;font-size:16px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;margin:8px auto 0;box-shadow:none!important;cursor:pointer;transition:all .2s ease;border-radius:8px}.confirm-btn:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 4px 12px #00000026!important}.confirm-btn:disabled{opacity:.5;cursor:not-allowed}[dir=rtl] .confirm-btn{font-weight:700;letter-spacing:0;text-transform:none;font-size:17px}.toggle-section{display:flex;align-items:center;justify-content:space-between}.toggle-section label{text-align:right;font-size:19px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .toggle-section label,[lang=ar] .toggle-section label{font-weight:400}.toggle-section .switch{position:relative;display:inline-block;width:50px;height:24px}.toggle-section .switch input{opacity:0;width:0;height:0}.toggle-section .slider{position:absolute;cursor:pointer;inset:0;background-color:#ccc;transition:.4s;border-radius:24px}.toggle-section .slider:before{content:\"\";position:absolute;height:18px;width:18px;left:3px;bottom:3px;background-color:#fff;transition:.4s;border-radius:50%}.toggle-section input:checked+.slider:before{transform:translate(26px)}.order{order:1}.future-validation{text-align:center;color:#eb445a;margin-top:8px;font-size:13px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .future-validation,[lang=ar] .future-validation{font-weight:400;line-height:1.8}.time-picker-section{padding:10px;background:transparent;border-radius:0;font-family:Poppins,sans-serif}.time-picker-section .time-picker-wrapper{display:flex;align-items:center;justify-content:center;gap:8px}.time-picker-section .time-picker-wrapper .time-input-container{position:relative;display:inline-flex;flex-direction:column;align-items:center}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow{width:100%;height:20px;border:1px solid #ddd;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s ease;padding:0;margin:0}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow i{font-size:20px;line-height:1;pointer-events:none;opacity:.7;transition:opacity .2s ease;display:flex;align-items:center;justify-content:center}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow:hover i{opacity:1}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow:active{background:#e9ecef}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow:focus{outline:none}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow.time-arrow-up{border-radius:4px 4px 0 0;border-bottom:none}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow.time-arrow-down{border-radius:0 0 4px 4px;border-top:none}.time-picker-section .time-picker-wrapper .time-input-container .time-field{width:50px;height:25px;border:1px solid #ddd;border-top:none;border-bottom:none;background:#fff;font-size:18px;font-weight:600;color:#333;text-align:center;padding:0;margin:0;transition:all .2s ease;font-family:Poppins,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;-moz-appearance:textfield;appearance:textfield}[dir=rtl] .time-picker-section .time-picker-wrapper .time-input-container .time-field,[lang=ar] .time-picker-section .time-picker-wrapper .time-input-container .time-field{font-weight:700}.time-picker-section .time-picker-wrapper .time-input-container .time-field::-webkit-outer-spin-button,.time-picker-section .time-picker-wrapper .time-input-container .time-field::-webkit-inner-spin-button{-webkit-appearance:none;appearance:none;margin:0}.time-picker-section .time-picker-wrapper .time-input-container .time-field:focus{outline:none;box-shadow:0 0 0 2px #5b479c1a;z-index:1}.time-picker-section .time-picker-wrapper .time-colon{font-size:24px;font-weight:600;color:#5b479c;padding:0 4px;-webkit-user-select:none;user-select:none;line-height:1;font-family:Poppins,sans-serif}[dir=rtl] .time-picker-section .time-picker-wrapper .time-colon,[lang=ar] .time-picker-section .time-picker-wrapper .time-colon{font-weight:700}.time-picker-section .time-picker-wrapper .meridian-toggle-group{display:flex;flex-direction:column;gap:0;margin-left:8px}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn{width:45px;height:25px;border:1px solid #ddd;background:#fff;color:#666;font-size:13px;font-weight:600;text-align:center;padding:0;cursor:pointer;transition:all .2s ease;font-family:Poppins,sans-serif}[dir=rtl] .time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn,[lang=ar] .time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn{font-weight:700}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:first-child{border-radius:4px 4px 0 0;border-bottom:none}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:last-child{border-radius:0 0 4px 4px}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:hover:not(.active){background:#f8f9fa;border-color:#00ace4;color:#00ace4}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:active{transform:scale(.98)}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:focus{outline:none;border-color:#00ace4;box-shadow:0 0 0 2px #00ace41a;z-index:1}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn.active{background:#004d61;border-color:#004d61;color:#fff;cursor:default}@media (max-width: 480px){.time-picker-section{padding:12px}.time-picker-section .time-picker-wrapper{gap:6px}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow{height:18px}.time-picker-section .time-picker-wrapper .time-input-container .time-field{width:50px;height:36px;font-size:20px}.time-picker-section .time-picker-wrapper .time-colon{font-size:24px}.time-picker-section .time-picker-wrapper .meridian-toggle-group{margin-left:6px}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn{width:45px;height:27px;font-size:12px}}\n"], dependencies: [{ kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i3.DecimalPipe, name: "number" }] }); }
28878
+ }
28879
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: HijriGregorianDatepickerComponent, decorators: [{
28880
+ type: Component,
28881
+ args: [{ standalone: false, selector: 'hijri-gregorian-datepicker', template: "<div class=\"calendar-container\" [dir]=\"dir\" [attr.lang]=\"locale\">\r\n <div\r\n class=\"toggle-section\"\r\n [dir]=\"dir\"\r\n *ngIf=\"canChangeMode\"\r\n [ngStyle]=\"{ color: styles.primaryColor }\"\r\n >\r\n <span> {{ ummAlQuraDateText }} </span>\r\n <label class=\"switch\">\r\n <input\r\n type=\"checkbox\"\r\n [disabled]=\"!canChangeMode\"\r\n [checked]=\"mode === 'ummAlQura'\"\r\n (change)=\"changeCalendarMode()\"\r\n #calendarCheckbox\r\n />\r\n <span\r\n class=\"slider\"\r\n [ngStyle]=\"\r\n calendarCheckbox.checked\r\n ? { 'background-color': styles.primaryColor }\r\n : { 'background-color': styles.backgroundColor }\r\n \"\r\n ></span>\r\n </label>\r\n </div>\r\n\r\n <div\r\n class=\"todays-date-section\"\r\n *ngIf=\"todaysDateSection\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.backgroundColor,\r\n color: styles.primaryColor,\r\n 'border-radius': styles.borderRadius\r\n }\"\r\n >\r\n <div\r\n class=\"text-info\"\r\n [ngClass]=\"{\r\n order: dir == 'rtl'\r\n }\"\r\n >\r\n <p>{{ todaysDateText }}</p>\r\n </div>\r\n\r\n <div\r\n class=\"data\"\r\n [dir]=\"dir\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.todaysDateBgColor,\r\n color: styles.todaysDateTextColor\r\n }\"\r\n >\r\n <p *ngIf=\"mode == 'ummAlQura'\">\r\n <!-- {{todaysDate.ummAlQura}} -->\r\n {{\r\n locale == \"ar\"\r\n ? _dateUtilsService.convertDateNumerals(todaysDate.ummAlQura, \"ar\")\r\n : todaysDate.ummAlQura\r\n }}\r\n </p>\r\n <p *ngIf=\"mode == 'greg'\">\r\n {{\r\n locale == \"ar\"\r\n ? _dateUtilsService.convertDateNumerals(todaysDate.gregorian, \"ar\")\r\n : todaysDate.gregorian\r\n }}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n <div class=\"period-container\">\r\n <form [formGroup]=\"periodForm\" class=\"period-form\">\r\n <div\r\n class=\"select-item\"\r\n [ngClass]=\"{\r\n order: dir == 'ltr'\r\n }\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.backgroundColor,\r\n 'border-radius': styles.borderRadius\r\n }\"\r\n >\r\n <label *ngIf=\"!periodForm.controls['year'].value\">{{\r\n yearSelectLabel\r\n }}</label>\r\n\r\n <select\r\n formControlName=\"year\"\r\n class=\"{{ 'icon-' + dir }}\"\r\n placeholder=\"\u0627\u0644\u0633\u0646\u0629\"\r\n (change)=\"onPeriodChange('year')\"\r\n [dir]=\"dir\"\r\n [ngStyle]=\"{\r\n color: styles.primaryColor,\r\n 'font-family': styles.fontFamily\r\n }\"\r\n >\r\n <option *ngFor=\"let year of years\" [ngValue]=\"year\">\r\n {{ locale == \"ar\" ? _dateUtilsService.parseEnglish(year) : year }}\r\n </option>\r\n </select>\r\n </div>\r\n\r\n <div\r\n class=\"select-item\"\r\n [ngClass]=\"{\r\n order: dir == 'rtl'\r\n }\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.backgroundColor,\r\n 'border-radius': styles.borderRadius\r\n }\"\r\n >\r\n <label *ngIf=\"!periodForm.controls['month'].value\">{{\r\n monthSelectLabel\r\n }}</label>\r\n <select\r\n class=\"{{ 'icon-' + dir }}\"\r\n formControlName=\"month\"\r\n (change)=\"onPeriodChange('month')\"\r\n [dir]=\"dir\"\r\n [ngStyle]=\"{\r\n color: styles.primaryColor,\r\n 'font-family': styles.fontFamily\r\n }\"\r\n >\r\n <option *ngFor=\"let month of months\" [ngValue]=\"month.value\">\r\n {{ locale == \"ar\" ? month?.labelAr : month?.labelEn }}\r\n </option>\r\n </select>\r\n </div>\r\n </form>\r\n </div>\r\n\r\n <div\r\n class=\"calendar-layout\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.backgroundColor,\r\n 'border-radius': styles.borderRadius\r\n }\"\r\n >\r\n <div class=\"week-days\">\r\n <div\r\n class=\"week-day\"\r\n [ngStyle]=\"{ color: styles.dayNameColor }\"\r\n *ngFor=\"let date of locale == 'ar' ? weekdaysAr : weekdaysEn\"\r\n >\r\n {{ date }}\r\n </div>\r\n </div>\r\n\r\n <div [dir]=\"dir\">\r\n <div class=\"week\" *ngFor=\"let week of weeks\">\r\n <div\r\n class=\"day\"\r\n *ngFor=\"let day of week\"\r\n (click)=\"disableDayPicker == false ? onDayClicked(day) : ''\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.backgroundColor,\r\n color: styles.dayColor\r\n }\"\r\n >\r\n <div\r\n id=\"greg-day\"\r\n [ngClass]=\"{\r\n 'todays-date': checkTodaysDate(day),\r\n 'selected-date': day?.selected == true\r\n }\"\r\n [ngStyle]=\"{\r\n border:\r\n markToday && checkTodaysDate(day)\r\n ? '1px solid ' + styles.secondaryColor\r\n : '',\r\n 'background-color':\r\n day?.selected == true ? styles.secondaryColor : '',\r\n color:\r\n (day?.selected == true ? styles.todaysDateTextColor : '') ||\r\n (checkFutureValidation(day) && futureValidation\r\n ? styles.disabledDayColor\r\n : '') ||\r\n (isDateDisabled(day) ? styles.disabledDayColor : ''),\r\n opacity: isDateDisabled(day) ? '0.4' : '1',\r\n cursor: isDateDisabled(day) ? 'not-allowed' : 'pointer'\r\n }\"\r\n >\r\n <span *ngIf=\"mode == 'greg'\">{{\r\n locale == \"ar\"\r\n ? _dateUtilsService.parseEnglish(\r\n day?.gD?.split(\"/\")[0] | number\r\n )\r\n : (day?.gD?.split(\"/\")[0] | number)\r\n }}</span>\r\n\r\n <span id=\"ummAlQura-day\" *ngIf=\"mode == 'ummAlQura'\">{{\r\n locale == \"ar\"\r\n ? _dateUtilsService.parseEnglish(\r\n day?.uD?.split(\"/\")[0] | number\r\n )\r\n : (day?.uD?.split(\"/\")[0] | number)\r\n }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"future-validation\" dir=\"auto\" *ngIf=\"futureValidationMessage\">\r\n <span *ngIf=\"locale == 'ar'\">\r\n {{ futureValidationMessageAr }}\r\n </span>\r\n <span *ngIf=\"locale == 'en'\">\r\n {{ futureValidationMessageEn }}\r\n </span>\r\n </div>\r\n\r\n <!-- Time Picker Section -->\r\n <!-- BACKWARD COMPATIBILITY: This section only renders when enableTime=true -->\r\n <div class=\"time-picker-section\" *ngIf=\"enableTime\" [dir]=\"'ltr'\">\r\n <div class=\"time-picker-wrapper\">\r\n <!-- Hour Input with Arrows -->\r\n <div class=\"time-input-container\">\r\n <button\r\n type=\"button\"\r\n class=\"time-arrow time-arrow-up\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.timePickerBgColor || '#ffffff',\r\n 'border-color': styles.timePickerBorderColor || '#ddd',\r\n color: styles.timePickerArrowColor || '#5b479c'\r\n }\"\r\n (click)=\"useMeridian ? incrementHour12() : incrementHour()\"\r\n tabindex=\"-1\"\r\n aria-label=\"Increment hour\"\r\n >\r\n <i class=\"ri-arrow-drop-up-line\"></i>\r\n </button>\r\n <input\r\n type=\"number\"\r\n class=\"time-field\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.timePickerBgColor || '#ffffff',\r\n 'border-color': styles.timePickerBorderColor || '#ddd',\r\n color: styles.timePickerTextColor || '#333'\r\n }\"\r\n [value]=\"getDisplayHour().toString().padStart(2, '0')\"\r\n (input)=\"\r\n useMeridian\r\n ? onHour12InputChange($event)\r\n : onHourInputChange($event)\r\n \"\r\n (keydown)=\"onTimeKeydown($event, 'hour')\"\r\n [min]=\"useMeridian ? 1 : 0\"\r\n [max]=\"useMeridian ? 12 : 23\"\r\n aria-label=\"Hour\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"time-arrow time-arrow-down\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.timePickerBgColor || '#ffffff',\r\n 'border-color': styles.timePickerBorderColor || '#ddd',\r\n color: styles.timePickerArrowColor || '#5b479c'\r\n }\"\r\n (click)=\"useMeridian ? decrementHour12() : decrementHour()\"\r\n tabindex=\"-1\"\r\n aria-label=\"Decrement hour\"\r\n >\r\n <i class=\"ri-arrow-drop-down-line\"></i>\r\n </button>\r\n </div>\r\n\r\n <!-- Colon Separator -->\r\n <span\r\n class=\"time-colon\"\r\n [ngStyle]=\"{\r\n color: styles.timePickerColonColor || '#5b479c'\r\n }\"\r\n >:</span\r\n >\r\n\r\n <!-- Minute Input with Arrows -->\r\n <div class=\"time-input-container\">\r\n <button\r\n type=\"button\"\r\n class=\"time-arrow time-arrow-up\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.timePickerBgColor || '#ffffff',\r\n 'border-color': styles.timePickerBorderColor || '#ddd',\r\n color: styles.timePickerArrowColor || '#5b479c'\r\n }\"\r\n (click)=\"incrementMinute()\"\r\n tabindex=\"-1\"\r\n aria-label=\"Increment minute\"\r\n >\r\n <i class=\"ri-arrow-drop-up-line\"></i>\r\n </button>\r\n <input\r\n type=\"number\"\r\n class=\"time-field\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.timePickerBgColor || '#ffffff',\r\n 'border-color': styles.timePickerBorderColor || '#ddd',\r\n color: styles.timePickerTextColor || '#333'\r\n }\"\r\n [value]=\"selectedTime.minute.toString().padStart(2, '0')\"\r\n (input)=\"onMinuteInputChange($event)\"\r\n (keydown)=\"onTimeKeydown($event, 'minute')\"\r\n min=\"0\"\r\n max=\"59\"\r\n aria-label=\"Minute\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"time-arrow time-arrow-down\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.timePickerBgColor || '#ffffff',\r\n 'border-color': styles.timePickerBorderColor || '#ddd',\r\n color: styles.timePickerArrowColor || '#5b479c'\r\n }\"\r\n (click)=\"decrementMinute()\"\r\n tabindex=\"-1\"\r\n aria-label=\"Decrement minute\"\r\n >\r\n <i class=\"ri-arrow-drop-down-line\"></i>\r\n </button>\r\n </div>\r\n\r\n <!-- AM/PM Button Group (only when useMeridian=true) -->\r\n <!-- BACKWARD COMPATIBILITY: This only renders when useMeridian=true -->\r\n <div class=\"meridian-toggle-group\" *ngIf=\"useMeridian\">\r\n <button\r\n type=\"button\"\r\n class=\"meridian-btn\"\r\n [class.active]=\"meridian === 'AM'\"\r\n [ngStyle]=\"\r\n meridian === 'AM'\r\n ? {\r\n 'background-color':\r\n styles.meridianActiveBgColor || 'rgb(0, 77, 97)',\r\n 'border-color':\r\n styles.meridianActiveBgColor || 'rgb(0, 77, 97)',\r\n color: styles.meridianActiveTextColor || '#ffffff'\r\n }\r\n : {\r\n 'background-color': styles.meridianBgColor || '#ffffff',\r\n 'border-color': styles.timePickerBorderColor || '#ddd',\r\n color: styles.meridianTextColor || '#666'\r\n }\r\n \"\r\n (click)=\"meridian !== 'AM' && toggleMeridian()\"\r\n aria-label=\"Select AM\"\r\n >\r\n AM\r\n </button>\r\n <button\r\n type=\"button\"\r\n class=\"meridian-btn\"\r\n [class.active]=\"meridian === 'PM'\"\r\n [ngStyle]=\"\r\n meridian === 'PM'\r\n ? {\r\n 'background-color':\r\n styles.meridianActiveBgColor || 'rgb(0, 77, 97)',\r\n 'border-color':\r\n styles.meridianActiveBgColor || 'rgb(0, 77, 97)',\r\n color: styles.meridianActiveTextColor || '#ffffff'\r\n }\r\n : {\r\n 'background-color': styles.meridianBgColor || '#ffffff',\r\n 'border-color': styles.timePickerBorderColor || '#ddd',\r\n color: styles.meridianTextColor || '#666'\r\n }\r\n \"\r\n (click)=\"meridian !== 'PM' && toggleMeridian()\"\r\n aria-label=\"Select PM\"\r\n >\r\n PM\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div>\r\n <button\r\n type=\"button\"\r\n class=\"confirm-btn\"\r\n [disabled]=\"\r\n isRequired &&\r\n ((!selectedDay && !multiple) ||\r\n (!multipleSelectedDates.length && multiple))\r\n \"\r\n (click)=\"onConfirmClicked()\"\r\n *ngIf=\"showConfirmButton\"\r\n [ngStyle]=\"{\r\n 'background-color': styles.secondaryColor,\r\n color: styles.confirmBtnTextColor,\r\n 'font-family': styles.fontFamily,\r\n 'border-radius': styles.borderRadius\r\n }\"\r\n >\r\n {{ submitTextButton }}\r\n </button>\r\n </div>\r\n</div>\r\n", styles: [".calendar-container{margin:auto;display:block;border-radius:20px;font-family:Poppins,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;font-weight:400}.calendar-container[dir=rtl],.calendar-container[lang=ar]{font-family:Zain,Arabic Typesetting,Tahoma,sans-serif;font-weight:300;letter-spacing:0;line-height:1.7}.calendar-container .todays-date-section{border-radius:4px;margin-top:12px;display:flex;align-items:center;justify-content:space-between;padding-left:10px;padding-right:10px}.calendar-container .todays-date-section .text-info{display:flex;align-items:center}.calendar-container .todays-date-section .text-info p{font-size:17px;font-weight:500;letter-spacing:.02em}[dir=rtl] .calendar-container .todays-date-section .text-info p,[lang=ar] .calendar-container .todays-date-section .text-info p{font-weight:400;letter-spacing:0}[dir=rtl] .calendar-container .todays-date-section .data p,[lang=ar] .calendar-container .todays-date-section .data p{font-weight:300}.calendar-container .todays-date-section .data{border-radius:8px}.calendar-container .todays-date-section .data p{font-size:14px;font-weight:400;margin:5px 10px}.calendar-container .period-container{display:flex;justify-content:space-between;margin-top:8px}.calendar-container .period-container .period-form{width:100%;display:flex;justify-content:space-between}.calendar-container .period-container .period-form .select-item{width:42.5%;border-radius:4px;height:50px;padding-left:10px;padding-right:10px}.calendar-container .period-container .period-form label{margin-right:10px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .calendar-container .period-container .period-form label,[lang=ar] .calendar-container .period-container .period-form label{font-weight:400}.calendar-container .period-container .period-form select{width:100%;height:50px;border:none;font-size:16px;font-weight:500;display:block;margin:auto;background:url(\"data:image/svg+xml;utf8,<svg viewBox='0 0 140 140' width='15' height='15' xmlns='http://www.w3.org/2000/svg'><g><path d='m121.3,34.6c-1.6-1.6-4.2-1.6-5.8,0l-51,51.1-51.1-51.1c-1.6-1.6-4.2-1.6-5.8,0-1.6,1.6-1.6,4.2 0,5.8l53.9,53.9c0.8,0.8 1.8,1.2 2.9,1.2 1,0 2.1-0.4 2.9-1.2l53.9-53.9c1.7-1.6 1.7-4.2 0.1-5.8z' fill='black'/></g></svg>\") no-repeat 95% 50%;-moz-appearance:none;-webkit-appearance:none;appearance:none;cursor:pointer}.calendar-container .period-container .period-form select option,.calendar-container [dir=rtl] .period-container select{font-weight:400}.calendar-container [dir=rtl] .period-container select option{font-weight:300}.icon-ltr{background-position:right}.icon-rtl{background-position:left!important}select:focus{outline:none}.calendar-layout{border-radius:4px;margin:8px auto auto;display:block;padding-bottom:5px}.calendar-layout .week-days{text-align:center;margin-top:5px;display:flex;justify-content:space-evenly}.calendar-layout .week-days .week-day{display:inline-block;width:13%;text-align:center;padding:15px 0 10px;font-weight:600;font-size:13px;text-transform:uppercase;letter-spacing:.05em}[dir=rtl] .calendar-layout .week-days{flex-direction:row-reverse!important}[dir=rtl] .calendar-layout .week-days .week-day{font-weight:700;letter-spacing:0;text-transform:none;font-size:14px}.calendar-layout .week{text-align:center;display:flex;justify-content:space-evenly}.calendar-layout .day{display:inline-flex;width:13%;height:5.5vh;justify-content:center;align-items:center;cursor:pointer;font-weight:500;transition:all .2s ease;border-radius:4px}.calendar-layout .day:hover:not(.disabled-day){transform:scale(1.05)}[dir=rtl] .calendar-layout .day{font-weight:400}.calendar-layout #greg-day{position:relative;min-width:20px}.calendar-layout #greg-day span{font-size:14px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .calendar-layout #greg-day span,[lang=ar] .calendar-layout #greg-day span{font-weight:400}.calendar-layout #ummAlQura-day{font-size:11px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .calendar-layout #ummAlQura-day,[lang=ar] .calendar-layout #ummAlQura-day{font-weight:400}.calendar-layout .todays-date,.calendar-layout .selected-date{padding:10px;border-radius:5px}.confirm-btn{height:50px;width:100%;border:none;font-size:16px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;margin:8px auto 0;box-shadow:none!important;cursor:pointer;transition:all .2s ease;border-radius:8px}.confirm-btn:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 4px 12px #00000026!important}.confirm-btn:disabled{opacity:.5;cursor:not-allowed}[dir=rtl] .confirm-btn{font-weight:700;letter-spacing:0;text-transform:none;font-size:17px}.toggle-section{display:flex;align-items:center;justify-content:space-between}.toggle-section label{text-align:right;font-size:19px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .toggle-section label,[lang=ar] .toggle-section label{font-weight:400}.toggle-section .switch{position:relative;display:inline-block;width:50px;height:24px}.toggle-section .switch input{opacity:0;width:0;height:0}.toggle-section .slider{position:absolute;cursor:pointer;inset:0;background-color:#ccc;transition:.4s;border-radius:24px}.toggle-section .slider:before{content:\"\";position:absolute;height:18px;width:18px;left:3px;bottom:3px;background-color:#fff;transition:.4s;border-radius:50%}.toggle-section input:checked+.slider:before{transform:translate(26px)}.order{order:1}.future-validation{text-align:center;color:#eb445a;margin-top:8px;font-size:13px;font-family:Poppins,sans-serif;font-weight:500}[dir=rtl] .future-validation,[lang=ar] .future-validation{font-weight:400;line-height:1.8}.time-picker-section{padding:10px;background:transparent;border-radius:0;font-family:Poppins,sans-serif}.time-picker-section .time-picker-wrapper{display:flex;align-items:center;justify-content:center;gap:8px}.time-picker-section .time-picker-wrapper .time-input-container{position:relative;display:inline-flex;flex-direction:column;align-items:center}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow{width:100%;height:20px;border:1px solid #ddd;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s ease;padding:0;margin:0}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow i{font-size:20px;line-height:1;pointer-events:none;opacity:.7;transition:opacity .2s ease;display:flex;align-items:center;justify-content:center}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow:hover i{opacity:1}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow:active{background:#e9ecef}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow:focus{outline:none}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow.time-arrow-up{border-radius:4px 4px 0 0;border-bottom:none}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow.time-arrow-down{border-radius:0 0 4px 4px;border-top:none}.time-picker-section .time-picker-wrapper .time-input-container .time-field{width:50px;height:25px;border:1px solid #ddd;border-top:none;border-bottom:none;background:#fff;font-size:18px;font-weight:600;color:#333;text-align:center;padding:0;margin:0;transition:all .2s ease;font-family:Poppins,-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif;-moz-appearance:textfield;appearance:textfield}[dir=rtl] .time-picker-section .time-picker-wrapper .time-input-container .time-field,[lang=ar] .time-picker-section .time-picker-wrapper .time-input-container .time-field{font-weight:700}.time-picker-section .time-picker-wrapper .time-input-container .time-field::-webkit-outer-spin-button,.time-picker-section .time-picker-wrapper .time-input-container .time-field::-webkit-inner-spin-button{-webkit-appearance:none;appearance:none;margin:0}.time-picker-section .time-picker-wrapper .time-input-container .time-field:focus{outline:none;box-shadow:0 0 0 2px #5b479c1a;z-index:1}.time-picker-section .time-picker-wrapper .time-colon{font-size:24px;font-weight:600;color:#5b479c;padding:0 4px;-webkit-user-select:none;user-select:none;line-height:1;font-family:Poppins,sans-serif}[dir=rtl] .time-picker-section .time-picker-wrapper .time-colon,[lang=ar] .time-picker-section .time-picker-wrapper .time-colon{font-weight:700}.time-picker-section .time-picker-wrapper .meridian-toggle-group{display:flex;flex-direction:column;gap:0;margin-left:8px}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn{width:45px;height:25px;border:1px solid #ddd;background:#fff;color:#666;font-size:13px;font-weight:600;text-align:center;padding:0;cursor:pointer;transition:all .2s ease;font-family:Poppins,sans-serif}[dir=rtl] .time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn,[lang=ar] .time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn{font-weight:700}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:first-child{border-radius:4px 4px 0 0;border-bottom:none}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:last-child{border-radius:0 0 4px 4px}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:hover:not(.active){background:#f8f9fa;border-color:#00ace4;color:#00ace4}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:active{transform:scale(.98)}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn:focus{outline:none;border-color:#00ace4;box-shadow:0 0 0 2px #00ace41a;z-index:1}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn.active{background:#004d61;border-color:#004d61;color:#fff;cursor:default}@media (max-width: 480px){.time-picker-section{padding:12px}.time-picker-section .time-picker-wrapper{gap:6px}.time-picker-section .time-picker-wrapper .time-input-container .time-arrow{height:18px}.time-picker-section .time-picker-wrapper .time-input-container .time-field{width:50px;height:36px;font-size:20px}.time-picker-section .time-picker-wrapper .time-colon{font-size:24px}.time-picker-section .time-picker-wrapper .meridian-toggle-group{margin-left:6px}.time-picker-section .time-picker-wrapper .meridian-toggle-group .meridian-btn{width:45px;height:27px;font-size:12px}}\n"] }]
28882
+ }], ctorParameters: () => [{ type: i1.UntypedFormBuilder }, { type: DateUtilitiesService }], propDecorators: { markToday: [{
28883
+ type: Input
28884
+ }], canChangeMode: [{
28885
+ type: Input
28886
+ }], todaysDateSection: [{
28887
+ type: Input
28888
+ }], futureValidation: [{
28889
+ type: Input
28890
+ }], disableYearPicker: [{
28891
+ type: Input
28892
+ }], disableMonthPicker: [{
28893
+ type: Input
28894
+ }], disableDayPicker: [{
28895
+ type: Input
28896
+ }], multiple: [{
28897
+ type: Input
28898
+ }], isRequired: [{
28899
+ type: Input
28900
+ }], showConfirmButton: [{
28901
+ type: Input
28902
+ }], futureValidationMessage: [{
28903
+ type: Input
28904
+ }], arabicLayout: [{
28905
+ type: Input
28906
+ }], mode: [{
28907
+ type: Input
28908
+ }], dir: [{
28909
+ type: Input
28910
+ }], locale: [{
28911
+ type: Input
28912
+ }], submitTextButton: [{
28913
+ type: Input
28914
+ }], todaysDateText: [{
28915
+ type: Input
28916
+ }], ummAlQuraDateText: [{
28917
+ type: Input
28918
+ }], monthSelectLabel: [{
28919
+ type: Input
28920
+ }], yearSelectLabel: [{
28921
+ type: Input
28922
+ }], futureValidationMessageEn: [{
28923
+ type: Input
28924
+ }], futureValidationMessageAr: [{
28925
+ type: Input
28926
+ }], theme: [{
28927
+ type: Input
28928
+ }], pastYearsLimit: [{
28929
+ type: Input
28930
+ }], futureYearsLimit: [{
28931
+ type: Input
28932
+ }], styles: [{
28933
+ type: Input
28934
+ }], enableTime: [{
28935
+ type: Input
28936
+ }], minDate: [{
28937
+ type: Input
28938
+ }], maxDate: [{
28939
+ type: Input
28940
+ }], initialDate: [{
28941
+ type: Input
28942
+ }], initialRangeStart: [{
28943
+ type: Input
28944
+ }], initialRangeEnd: [{
28945
+ type: Input
28946
+ }], useMeridian: [{
28947
+ type: Input
28948
+ }], selectionMode: [{
28949
+ type: Input
28950
+ }], onSubmit: [{
28951
+ type: Output
28952
+ }], onDaySelect: [{
28953
+ type: Output
28954
+ }], onMonthChange: [{
28955
+ type: Output
28956
+ }], onYearChange: [{
28957
+ type: Output
28958
+ }], fontFamilyStyle: [{
28959
+ type: HostBinding,
28960
+ args: ['style.font-family']
28961
28961
  }] } });
28962
28962
 
28963
- class HijriGregorianDatepickerModule {
28964
- }
28965
- HijriGregorianDatepickerModulefac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: HijriGregorianDatepickerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
28966
- HijriGregorianDatepickerModulemod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: HijriGregorianDatepickerModule, declarations: [HijriGregorianDatepickerComponent], imports: [FormsModule, ReactiveFormsModule, CommonModule], exports: [HijriGregorianDatepickerComponent] });
28967
- HijriGregorianDatepickerModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: HijriGregorianDatepickerModule, imports: [FormsModule, ReactiveFormsModule, CommonModule] });
28968
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: HijriGregorianDatepickerModule, decorators: [{
28969
- type: NgModule,
28970
- args: [{
28971
- declarations: [HijriGregorianDatepickerComponent],
28972
- imports: [FormsModule, ReactiveFormsModule, CommonModule],
28973
- exports: [HijriGregorianDatepickerComponent],
28974
- }]
28963
+ class HijriGregorianDatepickerModule {
28964
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: HijriGregorianDatepickerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
28965
+ static { thismod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: HijriGregorianDatepickerModule, declarations: [HijriGregorianDatepickerComponent], imports: [FormsModule, ReactiveFormsModule, CommonModule], exports: [HijriGregorianDatepickerComponent] }); }
28966
+ static { thisinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: HijriGregorianDatepickerModule, imports: [FormsModule, ReactiveFormsModule, CommonModule] }); }
28967
+ }
28968
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: HijriGregorianDatepickerModule, decorators: [{
28969
+ type: NgModule,
28970
+ args: [{
28971
+ declarations: [HijriGregorianDatepickerComponent],
28972
+ imports: [FormsModule, ReactiveFormsModule, CommonModule],
28973
+ exports: [HijriGregorianDatepickerComponent],
28974
+ }]
28975
28975
  }] });
28976
28976
 
28977
- /*
28978
- * Public API Surface of hijri-gregorian-datepicker
28977
+ /*
28978
+ * Public API Surface of hijri-gregorian-datepicker
28979
28979
  */
28980
28980
 
28981
- /**
28982
- * Generated bundle index. Do not edit.
28981
+ /**
28982
+ * Generated bundle index. Do not edit.
28983
28983
  */
28984
28984
 
28985
28985
  export { DateUtilitiesService, HijriGregorianDatepickerComponent, HijriGregorianDatepickerModule };