pdm-ui-kit 0.1.20 → 0.1.22

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.
@@ -4,6 +4,7 @@ import * as i0 from '@angular/core';
4
4
  import { EventEmitter, Component, ChangeDetectionStrategy, Input, Output, HostListener, ViewChildren, ViewChild, NgModule } from '@angular/core';
5
5
  import { icons } from 'lucide';
6
6
  import * as i1$1 from '@angular/platform-browser';
7
+ import { format } from 'date-fns';
7
8
 
8
9
  class PdmAccordionComponent {
9
10
  constructor() {
@@ -392,23 +393,40 @@ class PdmButtonComponent {
392
393
  get isDisabled() {
393
394
  return this.disabled || this.loading || this.variant === 'loading';
394
395
  }
396
+ get resolvedVariant() {
397
+ return this.isValidVariant(this.variant) ? this.variant : 'default';
398
+ }
399
+ get resolvedState() {
400
+ return this.state === 'hover' ? 'hover' : 'default';
401
+ }
402
+ get resolvedSize() {
403
+ if (this.size === 'small' || this.size === 'large') {
404
+ return this.size;
405
+ }
406
+ return 'default';
407
+ }
408
+ get showsIconSlot() {
409
+ const variant = this.resolvedVariant;
410
+ return variant === 'with-icon' || variant === 'icon' || variant === 'icon-circle' || variant === 'rounded';
411
+ }
395
412
  get rootClasses() {
396
- const currentState = this.state === 'hover' ? 'hover' : 'default';
397
- const toneClass = this.toneClassMap[this.variant][currentState];
413
+ const currentState = this.resolvedState;
414
+ const variant = this.resolvedVariant;
415
+ const toneClass = this.toneClassMap[variant][currentState];
398
416
  return [
399
417
  'inline-flex items-center justify-center gap-2 rounded-md border text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 bg-clip-padding',
400
- this.variant === 'link' ? 'px-4 py-2 h-9' : '',
401
- this.variant === 'icon' ? 'h-9 w-9 p-0' : '',
402
- this.variant === 'icon-circle' ? 'h-10 w-10 rounded-full p-0' : '',
403
- this.variant === 'rounded' ? 'h-9 w-9 rounded-full p-0' : '',
404
- this.variant !== 'icon' && this.variant !== 'icon-circle' && this.variant !== 'rounded'
405
- ? this.size === 'small'
418
+ variant === 'link' ? 'px-4 py-2 h-9' : '',
419
+ variant === 'icon' ? 'h-9 w-9 p-0' : '',
420
+ variant === 'icon-circle' ? 'h-10 w-10 rounded-full p-0' : '',
421
+ variant === 'rounded' ? 'h-9 w-9 rounded-full p-0' : '',
422
+ variant !== 'icon' && variant !== 'icon-circle' && variant !== 'rounded'
423
+ ? this.resolvedSize === 'small'
406
424
  ? 'h-8 px-3 text-xs'
407
- : this.size === 'large'
425
+ : this.resolvedSize === 'large'
408
426
  ? 'h-10 px-8'
409
427
  : 'h-9 px-4'
410
428
  : '',
411
- this.variant === 'link' && this.state === 'hover' ? 'underline underline-offset-4' : '',
429
+ variant === 'link' && currentState === 'hover' ? 'underline underline-offset-4' : '',
412
430
  toneClass,
413
431
  this.className
414
432
  ];
@@ -418,12 +436,27 @@ class PdmButtonComponent {
418
436
  this.pressed.emit(event);
419
437
  }
420
438
  }
439
+ isValidVariant(value) {
440
+ return (value === 'default' ||
441
+ value === 'primary' ||
442
+ value === 'destructive' ||
443
+ value === 'outline' ||
444
+ value === 'subtle' ||
445
+ value === 'secondary' ||
446
+ value === 'ghost' ||
447
+ value === 'link' ||
448
+ value === 'with-icon' ||
449
+ value === 'icon' ||
450
+ value === 'icon-circle' ||
451
+ value === 'rounded' ||
452
+ value === 'loading');
453
+ }
421
454
  }
422
455
  PdmButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
423
- PdmButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmButtonComponent, selector: "pdm-button", inputs: { type: "type", variant: "variant", state: "state", size: "size", disabled: "disabled", loading: "loading", className: "className" }, outputs: { pressed: "pressed" }, ngImport: i0, template: "<button\n [type]=\"type\"\n [disabled]=\"isDisabled\"\n [attr.aria-busy]=\"loading\"\n [ngClass]=\"rootClasses\"\n (click)=\"onClick($event)\"\n>\n <span\n *ngIf=\"loading\"\n class=\"inline-block h-4 w-4 animate-spin rounded-full border-2 border-current border-r-transparent\"\n aria-hidden=\"true\"\n ></span>\n <ng-content select=\"[pdmButtonIcon]\" *ngIf=\"variant === 'with-icon' || variant === 'icon' || variant === 'icon-circle' || variant === 'rounded'\"></ng-content>\n <ng-content></ng-content>\n</button>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
456
+ PdmButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmButtonComponent, selector: "pdm-button", inputs: { type: "type", variant: "variant", state: "state", size: "size", disabled: "disabled", loading: "loading", className: "className" }, outputs: { pressed: "pressed" }, ngImport: i0, template: "<button\n [type]=\"type\"\n [disabled]=\"isDisabled\"\n [attr.aria-busy]=\"loading\"\n [ngClass]=\"rootClasses\"\n (click)=\"onClick($event)\"\n>\n <span\n *ngIf=\"loading\"\n class=\"inline-block h-4 w-4 animate-spin rounded-full border-2 border-current border-r-transparent\"\n aria-hidden=\"true\"\n ></span>\n <ng-content select=\"[pdmButtonIcon]\" *ngIf=\"showsIconSlot\"></ng-content>\n <ng-content></ng-content>\n</button>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
424
457
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmButtonComponent, decorators: [{
425
458
  type: Component,
426
- args: [{ selector: 'pdm-button', changeDetection: ChangeDetectionStrategy.OnPush, template: "<button\n [type]=\"type\"\n [disabled]=\"isDisabled\"\n [attr.aria-busy]=\"loading\"\n [ngClass]=\"rootClasses\"\n (click)=\"onClick($event)\"\n>\n <span\n *ngIf=\"loading\"\n class=\"inline-block h-4 w-4 animate-spin rounded-full border-2 border-current border-r-transparent\"\n aria-hidden=\"true\"\n ></span>\n <ng-content select=\"[pdmButtonIcon]\" *ngIf=\"variant === 'with-icon' || variant === 'icon' || variant === 'icon-circle' || variant === 'rounded'\"></ng-content>\n <ng-content></ng-content>\n</button>\n" }]
459
+ args: [{ selector: 'pdm-button', changeDetection: ChangeDetectionStrategy.OnPush, template: "<button\n [type]=\"type\"\n [disabled]=\"isDisabled\"\n [attr.aria-busy]=\"loading\"\n [ngClass]=\"rootClasses\"\n (click)=\"onClick($event)\"\n>\n <span\n *ngIf=\"loading\"\n class=\"inline-block h-4 w-4 animate-spin rounded-full border-2 border-current border-r-transparent\"\n aria-hidden=\"true\"\n ></span>\n <ng-content select=\"[pdmButtonIcon]\" *ngIf=\"showsIconSlot\"></ng-content>\n <ng-content></ng-content>\n</button>\n" }]
427
460
  }], propDecorators: { type: [{
428
461
  type: Input
429
462
  }], variant: [{
@@ -442,71 +475,475 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
442
475
  type: Output
443
476
  }] } });
444
477
 
478
+ const DEFAULT_VIEW_MONTH = new Date(2025, 5, 1); // June 2025 (Figma default)
479
+ const DAY_MS = 24 * 60 * 60 * 1000;
445
480
  class PdmCalendarComponent {
446
- constructor() {
447
- this.mode = 'single';
448
- this.month = 6;
449
- this.year = 2025;
450
- this.selectedDay = 25;
451
- this.rangeStartDay = 25;
452
- this.rangeEndDay = 9;
481
+ constructor(cdr) {
482
+ this.cdr = cdr;
483
+ this._value = null;
484
+ this._rangeValue = null;
485
+ this._month = null;
486
+ this.variant = 'single';
453
487
  this.className = '';
488
+ this.disabledDates = [];
489
+ this.minDate = null;
490
+ this.maxDate = null;
491
+ this.isDateDisabled = null;
492
+ this.allowSameDayRange = true;
493
+ this.readonly = false;
494
+ this.valueChange = new EventEmitter();
495
+ this.rangeValueChange = new EventEmitter();
496
+ this.monthChange = new EventEmitter();
497
+ this.dateClick = new EventEmitter();
498
+ this.disabledDateClick = new EventEmitter();
454
499
  this.weekdays = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
500
+ this.monthOptions = [
501
+ { value: 0, label: 'Jan' },
502
+ { value: 1, label: 'Feb' },
503
+ { value: 2, label: 'Mar' },
504
+ { value: 3, label: 'Apr' },
505
+ { value: 4, label: 'May' },
506
+ { value: 5, label: 'Jun' },
507
+ { value: 6, label: 'Jul' },
508
+ { value: 7, label: 'Aug' },
509
+ { value: 8, label: 'Sep' },
510
+ { value: 9, label: 'Oct' },
511
+ { value: 10, label: 'Nov' },
512
+ { value: 11, label: 'Dec' }
513
+ ];
514
+ this.trackByIndex = (index) => {
515
+ return index;
516
+ };
517
+ this.trackByDate = (_index, cell) => {
518
+ return this.dateKey(cell.date);
519
+ };
520
+ }
521
+ set value(value) {
522
+ this._value = this.normalizeDate(value);
523
+ }
524
+ get value() {
525
+ return this._value;
526
+ }
527
+ set rangeValue(value) {
528
+ this._rangeValue = value
529
+ ? {
530
+ start: this.normalizeDate(value.start),
531
+ end: this.normalizeDate(value.end)
532
+ }
533
+ : null;
534
+ }
535
+ get rangeValue() {
536
+ return this._rangeValue;
537
+ }
538
+ set month(value) {
539
+ this._month = value ? this.startOfMonth(value) : null;
540
+ }
541
+ get month() {
542
+ return this._month;
543
+ }
544
+ get resolvedVariant() {
545
+ return this.variant === 'range' ? 'range' : 'single';
546
+ }
547
+ get visibleMonths() {
548
+ const baseMonth = this.getAnchorMonth();
549
+ if (this.resolvedVariant === 'single') {
550
+ return [
551
+ {
552
+ date: baseMonth,
553
+ title: this.formatMonthYear(baseMonth),
554
+ titleStyle: 'dropdowns',
555
+ dropdownMonth: this.formatMonthShort(baseMonth),
556
+ dropdownYear: String(baseMonth.getFullYear()),
557
+ showPrevButton: true,
558
+ showNextButton: true,
559
+ weeks: this.buildMonthWeeks(baseMonth, false)
560
+ }
561
+ ];
562
+ }
563
+ const nextMonth = this.addMonths(baseMonth, 1);
564
+ return [
565
+ {
566
+ date: baseMonth,
567
+ title: this.formatMonthYear(baseMonth),
568
+ titleStyle: 'plain',
569
+ showPrevButton: true,
570
+ showNextButton: false,
571
+ weeks: this.buildMonthWeeks(baseMonth, true)
572
+ },
573
+ {
574
+ date: nextMonth,
575
+ title: this.formatMonthYear(nextMonth),
576
+ titleStyle: 'plain',
577
+ showPrevButton: false,
578
+ showNextButton: true,
579
+ weeks: this.buildMonthWeeks(nextMonth, true)
580
+ }
581
+ ];
582
+ }
583
+ get singleHeaderMonth() {
584
+ return this.getAnchorMonth().getMonth();
585
+ }
586
+ get singleHeaderYear() {
587
+ return this.getAnchorMonth().getFullYear();
588
+ }
589
+ get yearOptions() {
590
+ const currentYear = this.singleHeaderYear;
591
+ const minYear = this.minDate ? this.minDate.getFullYear() : currentYear - 100;
592
+ const maxYear = this.maxDate ? this.maxDate.getFullYear() : currentYear + 100;
593
+ const years = [];
594
+ for (let year = minYear; year <= maxYear; year += 1) {
595
+ years.push(year);
596
+ }
597
+ return years;
598
+ }
599
+ get rootClasses() {
600
+ return [
601
+ 'border-border bg-background relative rounded-[10px] border p-3 shadow-sm',
602
+ this.resolvedVariant === 'range'
603
+ ? 'inline-flex items-start justify-center gap-4 shrink-0 grow-0 basis-auto'
604
+ : 'inline-flex flex-col gap-4 shrink-0 grow-0 basis-auto',
605
+ this.className
606
+ ];
607
+ }
608
+ get rootStyle() {
609
+ const width = this.resolvedVariant === 'range' ? '488px' : '250px';
610
+ return {
611
+ width,
612
+ minWidth: width,
613
+ maxWidth: width,
614
+ minHeight: '293px',
615
+ flex: '0 0 auto',
616
+ alignSelf: 'flex-start'
617
+ };
618
+ }
619
+ monthPanelClasses(_index) {
620
+ return ['flex flex-col items-start', this.resolvedVariant === 'range' ? 'w-[224px] gap-4' : 'w-full gap-0'];
621
+ }
622
+ headerClasses(month) {
623
+ return ['flex w-full items-center justify-between', month.titleStyle === 'dropdowns' ? '' : 'mb-4'];
624
+ }
625
+ navButtonClasses() {
626
+ return [
627
+ 'flex h-8 w-8 items-center justify-center rounded-md text-foreground',
628
+ 'disabled:pointer-events-none disabled:opacity-40'
629
+ ];
630
+ }
631
+ navPlaceholderClasses() {
632
+ return ['h-7 w-7 shrink-0'];
633
+ }
634
+ dropdownWrapClasses() {
635
+ return ['flex w-40 items-center justify-center gap-2'];
636
+ }
637
+ dropdownClasses(widthClass) {
638
+ return ['flex h-8 items-center justify-center gap-1 px-1', widthClass];
639
+ }
640
+ dropdownSelectClasses() {
641
+ return [
642
+ 'text-foreground h-full bg-transparent text-sm font-medium leading-5',
643
+ 'appearance-none border-0 outline-none ring-0 focus:outline-none focus:ring-0 text-center cursor-pointer'
644
+ ];
645
+ }
646
+ get dropdownSelectStyle() {
647
+ return {
648
+ appearance: 'none',
649
+ WebkitAppearance: 'none',
650
+ MozAppearance: 'none',
651
+ background: 'transparent',
652
+ border: '0',
653
+ boxShadow: 'none',
654
+ outline: '0',
655
+ padding: '0',
656
+ margin: '0'
657
+ };
658
+ }
659
+ calendarGridWrapClasses() {
660
+ return ['flex w-full flex-col items-start'];
661
+ }
662
+ weekdayRowClasses() {
663
+ return ['flex w-full items-center'];
664
+ }
665
+ weekdayCellClasses() {
666
+ return ['text-muted-foreground flex h-[21px] w-8 items-center justify-center rounded-md text-xs leading-4'];
667
+ }
668
+ weekRowClasses() {
669
+ return ['flex w-full items-start pt-2'];
670
+ }
671
+ dayCellClasses(cell) {
672
+ return [
673
+ 'relative flex h-8 w-8 shrink-0 items-center justify-center',
674
+ cell.rangeFill ? 'bg-accent' : '',
675
+ cell.rangeLeftCap ? 'rounded-l-md' : '',
676
+ cell.rangeRightCap ? 'rounded-r-md' : ''
677
+ ];
678
+ }
679
+ dayButtonClasses(cell) {
680
+ return [
681
+ 'relative z-10 flex h-8 w-8 items-center justify-center rounded-md text-sm leading-5',
682
+ cell.selected ? 'bg-primary text-primary-foreground' : cell.rangeFill ? 'text-accent-foreground' : 'text-foreground',
683
+ cell.muted && !cell.rangeFill ? 'opacity-50' : '',
684
+ cell.disabled ? 'cursor-not-allowed opacity-40' : '',
685
+ !cell.disabled && !this.readonly && !cell.selected ? 'hover:bg-accent/70' : ''
686
+ ];
687
+ }
688
+ dayLabelClasses(_cell) {
689
+ return ['font-normal'];
690
+ }
691
+ goToPreviousMonth() {
692
+ this.setAnchorMonth(this.addMonths(this.getAnchorMonth(), -1));
693
+ }
694
+ goToNextMonth() {
695
+ this.setAnchorMonth(this.addMonths(this.getAnchorMonth(), 1));
696
+ }
697
+ onSingleMonthChange(monthValue) {
698
+ const month = Number(monthValue);
699
+ if (Number.isNaN(month) || month < 0 || month > 11) {
700
+ return;
701
+ }
702
+ const anchor = this.getAnchorMonth();
703
+ this.setAnchorMonth(new Date(anchor.getFullYear(), month, 1));
704
+ }
705
+ onSingleYearChange(yearValue) {
706
+ const year = Number(yearValue);
707
+ if (Number.isNaN(year)) {
708
+ return;
709
+ }
710
+ const anchor = this.getAnchorMonth();
711
+ this.setAnchorMonth(new Date(year, anchor.getMonth(), 1));
712
+ }
713
+ onDatePressed(cell) {
714
+ const date = this.cloneDate(cell.date);
715
+ if (cell.disabled) {
716
+ this.disabledDateClick.emit(date);
717
+ return;
718
+ }
719
+ if (this.readonly) {
720
+ return;
721
+ }
722
+ this.dateClick.emit(date);
723
+ if (this.resolvedVariant === 'single') {
724
+ this._value = date;
725
+ this.valueChange.emit(this.cloneDate(date));
726
+ this.syncVisibleMonthToDate(date);
727
+ this.cdr.markForCheck();
728
+ return;
729
+ }
730
+ this.handleRangeSelection(date);
731
+ this.cdr.markForCheck();
732
+ }
733
+ handleRangeSelection(date) {
734
+ const current = this._rangeValue;
735
+ const currentStart = (current === null || current === void 0 ? void 0 : current.start) ? this.cloneDate(current.start) : null;
736
+ const currentEnd = (current === null || current === void 0 ? void 0 : current.end) ? this.cloneDate(current.end) : null;
737
+ if (!currentStart || (currentStart && currentEnd)) {
738
+ this._rangeValue = { start: date, end: null };
739
+ this.rangeValueChange.emit({ start: this.cloneDate(date), end: null });
740
+ this.syncVisibleMonthToDate(date);
741
+ return;
742
+ }
743
+ if (this.isSameDay(currentStart, date) && !this.allowSameDayRange) {
744
+ this._rangeValue = { start: date, end: null };
745
+ this.rangeValueChange.emit({ start: this.cloneDate(date), end: null });
746
+ return;
747
+ }
748
+ const start = this.compareDate(date, currentStart) < 0 ? date : currentStart;
749
+ const end = this.compareDate(date, currentStart) < 0 ? currentStart : date;
750
+ if (this.rangeContainsBlockedDate(start, end)) {
751
+ this.disabledDateClick.emit(this.cloneDate(date));
752
+ return;
753
+ }
754
+ this._rangeValue = { start, end };
755
+ this.rangeValueChange.emit({ start: this.cloneDate(start), end: this.cloneDate(end) });
756
+ this.syncVisibleMonthToDate(start);
757
+ }
758
+ buildMonthWeeks(month, includeRange) {
759
+ const firstOfMonth = this.startOfMonth(month);
760
+ const start = this.startOfWeek(firstOfMonth);
761
+ const end = this.endOfWeek(this.endOfMonth(firstOfMonth));
762
+ const weeks = [];
763
+ let cursor = this.cloneDate(start);
764
+ while (this.compareDate(cursor, end) <= 0) {
765
+ const row = [];
766
+ for (let col = 0; col < 7; col += 1) {
767
+ row.push(this.buildCell(cursor, month, includeRange));
768
+ cursor = this.addDays(cursor, 1);
769
+ }
770
+ weeks.push(row);
771
+ }
772
+ for (const row of weeks) {
773
+ for (let col = 0; col < row.length; col += 1) {
774
+ const cell = row[col];
775
+ if (!cell.inRange) {
776
+ continue;
777
+ }
778
+ const leftInRow = col > 0 ? row[col - 1].inRange : false;
779
+ const rightInRow = col < row.length - 1 ? row[col + 1].inRange : false;
780
+ cell.rangeLeftCap = !leftInRow;
781
+ cell.rangeRightCap = !rightInRow;
782
+ }
783
+ }
784
+ return weeks;
785
+ }
786
+ buildCell(date, visibleMonth, includeRange) {
787
+ var _a, _b, _c, _d;
788
+ const normalized = this.cloneDate(date);
789
+ const inCurrentMonth = normalized.getMonth() === visibleMonth.getMonth() && normalized.getFullYear() === visibleMonth.getFullYear();
790
+ const disabled = this.isBlocked(normalized);
791
+ const selectedSingle = this.resolvedVariant === 'single' && !!this._value && this.isSameDay(normalized, this._value);
792
+ const rangeStart = includeRange && !!((_a = this._rangeValue) === null || _a === void 0 ? void 0 : _a.start) && this.isSameDay(normalized, this._rangeValue.start);
793
+ const rangeEnd = includeRange && !!((_b = this._rangeValue) === null || _b === void 0 ? void 0 : _b.end) && this.isSameDay(normalized, this._rangeValue.end);
794
+ const inRange = includeRange &&
795
+ !!((_c = this._rangeValue) === null || _c === void 0 ? void 0 : _c.start) &&
796
+ !!((_d = this._rangeValue) === null || _d === void 0 ? void 0 : _d.end) &&
797
+ this.compareDate(normalized, this._rangeValue.start) >= 0 &&
798
+ this.compareDate(normalized, this._rangeValue.end) <= 0;
799
+ return {
800
+ date: normalized,
801
+ label: normalized.getDate(),
802
+ muted: !inCurrentMonth,
803
+ disabled,
804
+ selected: selectedSingle || rangeStart || rangeEnd,
805
+ inRange,
806
+ rangeFill: inRange,
807
+ rangeLeftCap: false,
808
+ rangeRightCap: false
809
+ };
810
+ }
811
+ getAnchorMonth() {
812
+ var _a;
813
+ if (this._month) {
814
+ return this.cloneDate(this._month);
815
+ }
816
+ if (this.resolvedVariant === 'single' && this._value) {
817
+ return this.startOfMonth(this._value);
818
+ }
819
+ if (this.resolvedVariant === 'range' && ((_a = this._rangeValue) === null || _a === void 0 ? void 0 : _a.start)) {
820
+ return this.startOfMonth(this._rangeValue.start);
821
+ }
822
+ return this.startOfMonth(DEFAULT_VIEW_MONTH);
823
+ }
824
+ setAnchorMonth(month) {
825
+ this._month = this.startOfMonth(month);
826
+ this.monthChange.emit(this.cloneDate(this._month));
827
+ }
828
+ syncVisibleMonthToDate(date) {
829
+ const nextMonth = this.startOfMonth(date);
830
+ if (!this._month || !this.isSameMonth(this._month, nextMonth)) {
831
+ this._month = nextMonth;
832
+ this.monthChange.emit(this.cloneDate(nextMonth));
833
+ }
834
+ }
835
+ isBlocked(date) {
836
+ var _a;
837
+ if (this.minDate && this.compareDate(date, this.minDate) < 0) {
838
+ return true;
839
+ }
840
+ if (this.maxDate && this.compareDate(date, this.maxDate) > 0) {
841
+ return true;
842
+ }
843
+ const blockedSet = new Set((this.disabledDates || []).map((item) => this.dateKey(item)));
844
+ if (blockedSet.has(this.dateKey(date))) {
845
+ return true;
846
+ }
847
+ return !!((_a = this.isDateDisabled) === null || _a === void 0 ? void 0 : _a.call(this, this.cloneDate(date)));
848
+ }
849
+ rangeContainsBlockedDate(start, end) {
850
+ let cursor = this.cloneDate(start);
851
+ while (this.compareDate(cursor, end) <= 0) {
852
+ if (this.isBlocked(cursor)) {
853
+ return true;
854
+ }
855
+ cursor = this.addDays(cursor, 1);
856
+ }
857
+ return false;
858
+ }
859
+ normalizeDate(value) {
860
+ if (!(value instanceof Date) || Number.isNaN(value.getTime())) {
861
+ return null;
862
+ }
863
+ return new Date(value.getFullYear(), value.getMonth(), value.getDate());
864
+ }
865
+ cloneDate(date) {
866
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate());
867
+ }
868
+ startOfMonth(date) {
869
+ return new Date(date.getFullYear(), date.getMonth(), 1);
870
+ }
871
+ endOfMonth(date) {
872
+ return new Date(date.getFullYear(), date.getMonth() + 1, 0);
873
+ }
874
+ startOfWeek(date) {
875
+ return this.addDays(date, -date.getDay());
876
+ }
877
+ endOfWeek(date) {
878
+ return this.addDays(date, 6 - date.getDay());
455
879
  }
456
- get leftMonthName() {
457
- return this.monthName(this.month - 1);
458
- }
459
- get rightMonthName() {
460
- const rightMonth = this.month % 12;
461
- return this.monthName(rightMonth);
462
- }
463
- get leftCells() {
464
- return this.buildMonthCells(this.year, this.month - 1, this.selectedDay, this.mode === 'range' ? this.rangeStartDay : undefined, this.mode === 'range' ? 31 : undefined);
465
- }
466
- get rightCells() {
467
- const rightMonth = this.month % 12;
468
- const rightYear = this.month === 12 ? this.year + 1 : this.year;
469
- return this.buildMonthCells(rightYear, rightMonth, this.mode === 'range' ? this.rangeEndDay : undefined, 1, this.mode === 'range' ? this.rangeEndDay : undefined);
470
- }
471
- monthName(monthIndex) {
472
- const safe = ((monthIndex % 12) + 12) % 12;
473
- return new Date(this.year, safe, 1).toLocaleString('en-US', { month: 'long' });
474
- }
475
- buildMonthCells(year, monthIndex, selectedDay, rangeStartDay, rangeEndDay) {
476
- const firstDay = new Date(year, monthIndex, 1);
477
- const startWeekday = firstDay.getDay();
478
- const daysInMonth = new Date(year, monthIndex + 1, 0).getDate();
479
- const cells = [];
480
- for (let i = 0; i < 42; i += 1) {
481
- const dayNumber = i - startWeekday + 1;
482
- const date = new Date(year, monthIndex, dayNumber);
483
- const outside = dayNumber < 1 || dayNumber > daysInMonth;
484
- const day = date.getDate();
485
- const selected = !outside && !!selectedDay && day === selectedDay;
486
- const inRange = !outside && !!rangeStartDay && !!rangeEndDay && day >= rangeStartDay && day <= rangeEndDay;
487
- cells.push({ date, day, outside, selected, inRange });
488
- }
489
- return cells;
880
+ addMonths(date, months) {
881
+ return new Date(date.getFullYear(), date.getMonth() + months, 1);
882
+ }
883
+ addDays(date, days) {
884
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate() + days);
885
+ }
886
+ compareDate(a, b) {
887
+ return this.dateValue(a) - this.dateValue(b);
888
+ }
889
+ dateValue(date) {
890
+ return Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()) / DAY_MS;
891
+ }
892
+ isSameDay(a, b) {
893
+ return this.compareDate(a, b) === 0;
894
+ }
895
+ isSameMonth(a, b) {
896
+ return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth();
897
+ }
898
+ dateKey(date) {
899
+ const y = date.getFullYear();
900
+ const m = String(date.getMonth() + 1).padStart(2, '0');
901
+ const d = String(date.getDate()).padStart(2, '0');
902
+ return `${y}-${m}-${d}`;
903
+ }
904
+ formatMonthShort(date) {
905
+ return date.toLocaleString('en-US', { month: 'short' });
906
+ }
907
+ formatMonthYear(date) {
908
+ return date.toLocaleString('en-US', { month: 'long', year: 'numeric' });
490
909
  }
491
910
  }
492
- PdmCalendarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmCalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
493
- PdmCalendarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmCalendarComponent, selector: "pdm-calendar", inputs: { mode: "mode", month: "month", year: "year", selectedDay: "selectedDay", rangeStartDay: "rangeStartDay", rangeEndDay: "rangeEndDay", className: "className" }, ngImport: i0, template: "<section\n [ngClass]=\"[\n 'rounded-lg border border-border bg-background p-3 shadow-sm',\n mode === 'range' ? 'w-full max-w-2xl' : 'w-full max-w-sm',\n className\n ]\"\n>\n <div [ngClass]=\"['grid gap-4', mode === 'range' ? 'grid-cols-2' : 'grid-cols-1']\">\n <div class=\"space-y-4\">\n <header class=\"flex items-center justify-between\">\n <button type=\"button\" class=\"inline-flex h-8 w-8 items-center justify-center rounded-md text-foreground hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\">\u2039</button>\n <div [ngClass]=\"['flex items-center justify-center gap-1', mode === 'range' ? 'w-full' : 'w-full']\">\n <ng-container *ngIf=\"mode === 'single'; else monthText\">\n <span class=\"inline-flex h-8 items-center rounded-md border border-border px-2 text-sm font-medium text-foreground shadow-sm\">Jun</span>\n <span class=\"inline-flex h-8 items-center rounded-md border border-border px-2 text-sm font-medium text-foreground shadow-sm\">2025</span>\n </ng-container>\n <ng-template #monthText>\n <span class=\"text-sm font-medium text-foreground\">{{ leftMonthName }} {{ year }}</span>\n </ng-template>\n </div>\n <button type=\"button\" class=\"inline-flex h-8 w-8 items-center justify-center rounded-md text-foreground hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\">{{ mode === 'range' ? '' : '\u203A' }}</button>\n </header>\n\n <div>\n <div class=\"grid grid-cols-7\">\n <span *ngFor=\"let day of weekdays\" class=\"inline-flex h-5 items-center justify-center text-xs font-normal text-muted-foreground\">{{ day }}</span>\n </div>\n <div class=\"mt-2 grid grid-cols-7 gap-y-2\">\n <button\n *ngFor=\"let cell of leftCells\"\n type=\"button\"\n [ngClass]=\"[\n 'inline-flex h-8 w-8 items-center justify-center rounded-md text-sm font-normal transition-colors hover:bg-accent hover:text-accent-foreground',\n cell.outside ? 'text-muted-foreground opacity-50' : 'text-foreground',\n cell.inRange ? 'bg-accent text-accent-foreground' : '',\n cell.selected ? 'bg-primary text-primary-foreground' : ''\n ]\"\n >\n {{ cell.day }}\n </button>\n </div>\n </div>\n </div>\n\n <div *ngIf=\"mode === 'range'\" class=\"space-y-4\">\n <header class=\"flex items-center justify-between\">\n <span class=\"text-sm font-medium text-foreground\">{{ rightMonthName }} {{ month === 12 ? year + 1 : year }}</span>\n <button type=\"button\" class=\"inline-flex h-8 w-8 items-center justify-center rounded-md text-foreground hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\">\u203A</button>\n </header>\n\n <div>\n <div class=\"grid grid-cols-7\">\n <span *ngFor=\"let day of weekdays\" class=\"inline-flex h-5 items-center justify-center text-xs font-normal text-muted-foreground\">{{ day }}</span>\n </div>\n <div class=\"mt-2 grid grid-cols-7 gap-y-2\">\n <button\n *ngFor=\"let cell of rightCells\"\n type=\"button\"\n [ngClass]=\"[\n 'inline-flex h-8 w-8 items-center justify-center rounded-md text-sm font-normal transition-colors hover:bg-accent hover:text-accent-foreground',\n cell.outside ? 'text-muted-foreground opacity-50' : 'text-foreground',\n cell.inRange ? 'bg-accent text-accent-foreground' : '',\n cell.selected ? 'bg-primary text-primary-foreground' : ''\n ]\"\n >\n {{ cell.day }}\n </button>\n </div>\n </div>\n </div>\n </div>\n</section>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
911
+ PdmCalendarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmCalendarComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
912
+ PdmCalendarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmCalendarComponent, selector: "pdm-calendar", inputs: { variant: "variant", className: "className", disabledDates: "disabledDates", minDate: "minDate", maxDate: "maxDate", isDateDisabled: "isDateDisabled", allowSameDayRange: "allowSameDayRange", readonly: "readonly", value: "value", rangeValue: "rangeValue", month: "month" }, outputs: { valueChange: "valueChange", rangeValueChange: "rangeValueChange", monthChange: "monthChange", dateClick: "dateClick", disabledDateClick: "disabledDateClick" }, ngImport: i0, template: "<div [ngClass]=\"rootClasses\" [ngStyle]=\"rootStyle\">\n <div *ngFor=\"let month of visibleMonths; let monthIndex = index; trackBy: trackByIndex\" [ngClass]=\"monthPanelClasses(monthIndex)\">\n <div [ngClass]=\"headerClasses(month)\">\n <button\n *ngIf=\"month.showPrevButton; else prevPlaceholder\"\n type=\"button\"\n [ngClass]=\"navButtonClasses()\"\n aria-label=\"Previous month\"\n (click)=\"goToPreviousMonth()\"\n [disabled]=\"readonly\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m15 18-6-6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n <ng-template #prevPlaceholder>\n <div [ngClass]=\"navPlaceholderClasses()\" aria-hidden=\"true\"></div>\n </ng-template>\n\n <ng-container *ngIf=\"month.titleStyle === 'dropdowns'; else plainTitle\">\n <div [ngClass]=\"dropdownWrapClasses()\">\n <div [ngClass]=\"dropdownClasses('w-[72px]')\">\n <select\n [ngClass]=\"dropdownSelectClasses()\"\n [ngStyle]=\"dropdownSelectStyle\"\n [value]=\"singleHeaderMonth\"\n aria-label=\"Month\"\n (change)=\"onSingleMonthChange($any($event.target).value)\"\n >\n <option *ngFor=\"let monthOption of monthOptions\" [value]=\"monthOption.value\">{{ monthOption.label }}</option>\n </select>\n <svg viewBox=\"0 0 24 24\" class=\"h-3 w-3 text-foreground\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m6 9 6 6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </div>\n <div [ngClass]=\"dropdownClasses('w-[82px]')\">\n <select\n [ngClass]=\"dropdownSelectClasses()\"\n [ngStyle]=\"dropdownSelectStyle\"\n [value]=\"singleHeaderYear\"\n aria-label=\"Year\"\n (change)=\"onSingleYearChange($any($event.target).value)\"\n >\n <option *ngFor=\"let year of yearOptions\" [value]=\"year\">{{ year }}</option>\n </select>\n <svg viewBox=\"0 0 24 24\" class=\"h-3 w-3 text-foreground\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m6 9 6 6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </div>\n </div>\n </ng-container>\n\n <ng-template #plainTitle>\n <div class=\"flex min-w-0 flex-1 items-center justify-center\">\n <p class=\"text-foreground text-center text-sm font-medium leading-5\">\n {{ month.title }}\n </p>\n </div>\n </ng-template>\n\n <button\n *ngIf=\"month.showNextButton; else nextPlaceholder\"\n type=\"button\"\n [ngClass]=\"navButtonClasses()\"\n aria-label=\"Next month\"\n (click)=\"goToNextMonth()\"\n [disabled]=\"readonly\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m9 18 6-6-6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n <ng-template #nextPlaceholder>\n <div [ngClass]=\"navPlaceholderClasses()\" aria-hidden=\"true\"></div>\n </ng-template>\n </div>\n\n <div [ngClass]=\"calendarGridWrapClasses()\">\n <div [ngClass]=\"weekdayRowClasses()\">\n <div *ngFor=\"let day of weekdays; trackBy: trackByIndex\" [ngClass]=\"weekdayCellClasses()\">\n <span>{{ day }}</span>\n </div>\n </div>\n\n <div *ngFor=\"let week of month.weeks; trackBy: trackByIndex\" [ngClass]=\"weekRowClasses()\">\n <div *ngFor=\"let cell of week; trackBy: trackByDate\" [ngClass]=\"dayCellClasses(cell)\">\n <button\n type=\"button\"\n [ngClass]=\"dayButtonClasses(cell)\"\n [disabled]=\"readonly\"\n [attr.aria-selected]=\"cell.selected\"\n [attr.aria-disabled]=\"cell.disabled || readonly\"\n [attr.title]=\"cell.date | date : 'yyyy-MM-dd'\"\n (click)=\"onDatePressed(cell)\"\n >\n <span [ngClass]=\"dayLabelClasses(cell)\">{{ cell.label }}</span>\n </button>\n </div>\n </div>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i1.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
494
913
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmCalendarComponent, decorators: [{
495
914
  type: Component,
496
- args: [{ selector: 'pdm-calendar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<section\n [ngClass]=\"[\n 'rounded-lg border border-border bg-background p-3 shadow-sm',\n mode === 'range' ? 'w-full max-w-2xl' : 'w-full max-w-sm',\n className\n ]\"\n>\n <div [ngClass]=\"['grid gap-4', mode === 'range' ? 'grid-cols-2' : 'grid-cols-1']\">\n <div class=\"space-y-4\">\n <header class=\"flex items-center justify-between\">\n <button type=\"button\" class=\"inline-flex h-8 w-8 items-center justify-center rounded-md text-foreground hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\">\u2039</button>\n <div [ngClass]=\"['flex items-center justify-center gap-1', mode === 'range' ? 'w-full' : 'w-full']\">\n <ng-container *ngIf=\"mode === 'single'; else monthText\">\n <span class=\"inline-flex h-8 items-center rounded-md border border-border px-2 text-sm font-medium text-foreground shadow-sm\">Jun</span>\n <span class=\"inline-flex h-8 items-center rounded-md border border-border px-2 text-sm font-medium text-foreground shadow-sm\">2025</span>\n </ng-container>\n <ng-template #monthText>\n <span class=\"text-sm font-medium text-foreground\">{{ leftMonthName }} {{ year }}</span>\n </ng-template>\n </div>\n <button type=\"button\" class=\"inline-flex h-8 w-8 items-center justify-center rounded-md text-foreground hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\">{{ mode === 'range' ? '' : '\u203A' }}</button>\n </header>\n\n <div>\n <div class=\"grid grid-cols-7\">\n <span *ngFor=\"let day of weekdays\" class=\"inline-flex h-5 items-center justify-center text-xs font-normal text-muted-foreground\">{{ day }}</span>\n </div>\n <div class=\"mt-2 grid grid-cols-7 gap-y-2\">\n <button\n *ngFor=\"let cell of leftCells\"\n type=\"button\"\n [ngClass]=\"[\n 'inline-flex h-8 w-8 items-center justify-center rounded-md text-sm font-normal transition-colors hover:bg-accent hover:text-accent-foreground',\n cell.outside ? 'text-muted-foreground opacity-50' : 'text-foreground',\n cell.inRange ? 'bg-accent text-accent-foreground' : '',\n cell.selected ? 'bg-primary text-primary-foreground' : ''\n ]\"\n >\n {{ cell.day }}\n </button>\n </div>\n </div>\n </div>\n\n <div *ngIf=\"mode === 'range'\" class=\"space-y-4\">\n <header class=\"flex items-center justify-between\">\n <span class=\"text-sm font-medium text-foreground\">{{ rightMonthName }} {{ month === 12 ? year + 1 : year }}</span>\n <button type=\"button\" class=\"inline-flex h-8 w-8 items-center justify-center rounded-md text-foreground hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\">\u203A</button>\n </header>\n\n <div>\n <div class=\"grid grid-cols-7\">\n <span *ngFor=\"let day of weekdays\" class=\"inline-flex h-5 items-center justify-center text-xs font-normal text-muted-foreground\">{{ day }}</span>\n </div>\n <div class=\"mt-2 grid grid-cols-7 gap-y-2\">\n <button\n *ngFor=\"let cell of rightCells\"\n type=\"button\"\n [ngClass]=\"[\n 'inline-flex h-8 w-8 items-center justify-center rounded-md text-sm font-normal transition-colors hover:bg-accent hover:text-accent-foreground',\n cell.outside ? 'text-muted-foreground opacity-50' : 'text-foreground',\n cell.inRange ? 'bg-accent text-accent-foreground' : '',\n cell.selected ? 'bg-primary text-primary-foreground' : ''\n ]\"\n >\n {{ cell.day }}\n </button>\n </div>\n </div>\n </div>\n </div>\n</section>\n" }]
497
- }], propDecorators: { mode: [{
915
+ args: [{ selector: 'pdm-calendar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"rootClasses\" [ngStyle]=\"rootStyle\">\n <div *ngFor=\"let month of visibleMonths; let monthIndex = index; trackBy: trackByIndex\" [ngClass]=\"monthPanelClasses(monthIndex)\">\n <div [ngClass]=\"headerClasses(month)\">\n <button\n *ngIf=\"month.showPrevButton; else prevPlaceholder\"\n type=\"button\"\n [ngClass]=\"navButtonClasses()\"\n aria-label=\"Previous month\"\n (click)=\"goToPreviousMonth()\"\n [disabled]=\"readonly\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m15 18-6-6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n <ng-template #prevPlaceholder>\n <div [ngClass]=\"navPlaceholderClasses()\" aria-hidden=\"true\"></div>\n </ng-template>\n\n <ng-container *ngIf=\"month.titleStyle === 'dropdowns'; else plainTitle\">\n <div [ngClass]=\"dropdownWrapClasses()\">\n <div [ngClass]=\"dropdownClasses('w-[72px]')\">\n <select\n [ngClass]=\"dropdownSelectClasses()\"\n [ngStyle]=\"dropdownSelectStyle\"\n [value]=\"singleHeaderMonth\"\n aria-label=\"Month\"\n (change)=\"onSingleMonthChange($any($event.target).value)\"\n >\n <option *ngFor=\"let monthOption of monthOptions\" [value]=\"monthOption.value\">{{ monthOption.label }}</option>\n </select>\n <svg viewBox=\"0 0 24 24\" class=\"h-3 w-3 text-foreground\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m6 9 6 6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </div>\n <div [ngClass]=\"dropdownClasses('w-[82px]')\">\n <select\n [ngClass]=\"dropdownSelectClasses()\"\n [ngStyle]=\"dropdownSelectStyle\"\n [value]=\"singleHeaderYear\"\n aria-label=\"Year\"\n (change)=\"onSingleYearChange($any($event.target).value)\"\n >\n <option *ngFor=\"let year of yearOptions\" [value]=\"year\">{{ year }}</option>\n </select>\n <svg viewBox=\"0 0 24 24\" class=\"h-3 w-3 text-foreground\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m6 9 6 6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </div>\n </div>\n </ng-container>\n\n <ng-template #plainTitle>\n <div class=\"flex min-w-0 flex-1 items-center justify-center\">\n <p class=\"text-foreground text-center text-sm font-medium leading-5\">\n {{ month.title }}\n </p>\n </div>\n </ng-template>\n\n <button\n *ngIf=\"month.showNextButton; else nextPlaceholder\"\n type=\"button\"\n [ngClass]=\"navButtonClasses()\"\n aria-label=\"Next month\"\n (click)=\"goToNextMonth()\"\n [disabled]=\"readonly\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m9 18 6-6-6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n <ng-template #nextPlaceholder>\n <div [ngClass]=\"navPlaceholderClasses()\" aria-hidden=\"true\"></div>\n </ng-template>\n </div>\n\n <div [ngClass]=\"calendarGridWrapClasses()\">\n <div [ngClass]=\"weekdayRowClasses()\">\n <div *ngFor=\"let day of weekdays; trackBy: trackByIndex\" [ngClass]=\"weekdayCellClasses()\">\n <span>{{ day }}</span>\n </div>\n </div>\n\n <div *ngFor=\"let week of month.weeks; trackBy: trackByIndex\" [ngClass]=\"weekRowClasses()\">\n <div *ngFor=\"let cell of week; trackBy: trackByDate\" [ngClass]=\"dayCellClasses(cell)\">\n <button\n type=\"button\"\n [ngClass]=\"dayButtonClasses(cell)\"\n [disabled]=\"readonly\"\n [attr.aria-selected]=\"cell.selected\"\n [attr.aria-disabled]=\"cell.disabled || readonly\"\n [attr.title]=\"cell.date | date : 'yyyy-MM-dd'\"\n (click)=\"onDatePressed(cell)\"\n >\n <span [ngClass]=\"dayLabelClasses(cell)\">{{ cell.label }}</span>\n </button>\n </div>\n </div>\n </div>\n </div>\n</div>\n" }]
916
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { variant: [{
498
917
  type: Input
499
- }], month: [{
918
+ }], className: [{
500
919
  type: Input
501
- }], year: [{
920
+ }], disabledDates: [{
502
921
  type: Input
503
- }], selectedDay: [{
922
+ }], minDate: [{
504
923
  type: Input
505
- }], rangeStartDay: [{
924
+ }], maxDate: [{
506
925
  type: Input
507
- }], rangeEndDay: [{
926
+ }], isDateDisabled: [{
508
927
  type: Input
509
- }], className: [{
928
+ }], allowSameDayRange: [{
929
+ type: Input
930
+ }], readonly: [{
931
+ type: Input
932
+ }], valueChange: [{
933
+ type: Output
934
+ }], rangeValueChange: [{
935
+ type: Output
936
+ }], monthChange: [{
937
+ type: Output
938
+ }], dateClick: [{
939
+ type: Output
940
+ }], disabledDateClick: [{
941
+ type: Output
942
+ }], value: [{
943
+ type: Input
944
+ }], rangeValue: [{
945
+ type: Input
946
+ }], month: [{
510
947
  type: Input
511
948
  }] } });
512
949
 
@@ -1098,10 +1535,10 @@ class PdmIconComponent {
1098
1535
  }
1099
1536
  }
1100
1537
  PdmIconComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmIconComponent, deps: [{ token: i1$1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component });
1101
- PdmIconComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmIconComponent, selector: "pdm-icon", inputs: { name: "name", library: "library", assetUrl: "assetUrl", size: "size", strokeWidth: "strokeWidth", className: "className", ariaLabel: "ariaLabel", decorative: "decorative" }, ngImport: i0, template: "<ng-container *ngIf=\"assetUrl; else inlineIcon\">\n <img\n [src]=\"assetUrl\"\n [style.width.px]=\"resolvedSize\"\n [style.height.px]=\"resolvedSize\"\n [ngClass]=\"className\"\n [attr.role]=\"decorative ? null : 'img'\"\n [attr.aria-hidden]=\"decorative ? 'true' : null\"\n [attr.aria-label]=\"!decorative ? ariaLabel || name : null\"\n alt=\"\"\n />\n</ng-container>\n\n<ng-template #inlineIcon>\n <span\n [ngClass]=\"className\"\n [style.display]=\"'inline-flex'\"\n [style.align-items]=\"'center'\"\n [style.justify-content]=\"'center'\"\n [style.line-height]=\"0\"\n [style.width.px]=\"resolvedSize\"\n [style.height.px]=\"resolvedSize\"\n [attr.role]=\"decorative ? null : 'img'\"\n [attr.aria-hidden]=\"decorative ? 'true' : null\"\n [attr.aria-label]=\"!decorative ? ariaLabel || name : null\"\n [innerHTML]=\"svgMarkup\"\n ></span>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1538
+ PdmIconComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmIconComponent, selector: "pdm-icon", inputs: { name: "name", library: "library", assetUrl: "assetUrl", size: "size", strokeWidth: "strokeWidth", className: "className", ariaLabel: "ariaLabel", decorative: "decorative" }, ngImport: i0, template: "<ng-container *ngIf=\"assetUrl; else inlineIcon\">\n <img\n [src]=\"assetUrl\"\n [style.width.px]=\"resolvedSize\"\n [style.height.px]=\"resolvedSize\"\n [ngClass]=\"className\"\n [attr.role]=\"decorative ? null : 'img'\"\n [attr.aria-hidden]=\"decorative ? 'true' : null\"\n [attr.aria-label]=\"!decorative ? ariaLabel || name : null\"\n alt=\"\"\n />\n</ng-container>\n\n<ng-template #inlineIcon>\n <span\n [ngClass]=\"className\"\n [style.display]=\"'inline-flex'\"\n [style.align-items]=\"'center'\"\n [style.justify-content]=\"'center'\"\n [style.line-height]=\"0\"\n [style.width.px]=\"resolvedSize\"\n [style.height.px]=\"resolvedSize\"\n [attr.role]=\"decorative ? null : 'img'\"\n [attr.aria-hidden]=\"decorative ? 'true' : null\"\n [attr.aria-label]=\"!decorative ? ariaLabel || name : null\"\n [innerHTML]=\"svgMarkup\"\n ></span>\n</ng-template>\n", styles: [":host{display:inline-flex;align-items:center;justify-content:center;line-height:0;flex-shrink:0}:host svg{display:block}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1102
1539
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmIconComponent, decorators: [{
1103
1540
  type: Component,
1104
- args: [{ selector: 'pdm-icon', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"assetUrl; else inlineIcon\">\n <img\n [src]=\"assetUrl\"\n [style.width.px]=\"resolvedSize\"\n [style.height.px]=\"resolvedSize\"\n [ngClass]=\"className\"\n [attr.role]=\"decorative ? null : 'img'\"\n [attr.aria-hidden]=\"decorative ? 'true' : null\"\n [attr.aria-label]=\"!decorative ? ariaLabel || name : null\"\n alt=\"\"\n />\n</ng-container>\n\n<ng-template #inlineIcon>\n <span\n [ngClass]=\"className\"\n [style.display]=\"'inline-flex'\"\n [style.align-items]=\"'center'\"\n [style.justify-content]=\"'center'\"\n [style.line-height]=\"0\"\n [style.width.px]=\"resolvedSize\"\n [style.height.px]=\"resolvedSize\"\n [attr.role]=\"decorative ? null : 'img'\"\n [attr.aria-hidden]=\"decorative ? 'true' : null\"\n [attr.aria-label]=\"!decorative ? ariaLabel || name : null\"\n [innerHTML]=\"svgMarkup\"\n ></span>\n</ng-template>\n" }]
1541
+ args: [{ selector: 'pdm-icon', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"assetUrl; else inlineIcon\">\n <img\n [src]=\"assetUrl\"\n [style.width.px]=\"resolvedSize\"\n [style.height.px]=\"resolvedSize\"\n [ngClass]=\"className\"\n [attr.role]=\"decorative ? null : 'img'\"\n [attr.aria-hidden]=\"decorative ? 'true' : null\"\n [attr.aria-label]=\"!decorative ? ariaLabel || name : null\"\n alt=\"\"\n />\n</ng-container>\n\n<ng-template #inlineIcon>\n <span\n [ngClass]=\"className\"\n [style.display]=\"'inline-flex'\"\n [style.align-items]=\"'center'\"\n [style.justify-content]=\"'center'\"\n [style.line-height]=\"0\"\n [style.width.px]=\"resolvedSize\"\n [style.height.px]=\"resolvedSize\"\n [attr.role]=\"decorative ? null : 'img'\"\n [attr.aria-hidden]=\"decorative ? 'true' : null\"\n [attr.aria-label]=\"!decorative ? ariaLabel || name : null\"\n [innerHTML]=\"svgMarkup\"\n ></span>\n</ng-template>\n", styles: [":host{display:inline-flex;align-items:center;justify-content:center;line-height:0;flex-shrink:0}:host svg{display:block}\n"] }]
1105
1542
  }], ctorParameters: function () { return [{ type: i1$1.DomSanitizer }]; }, propDecorators: { name: [{
1106
1543
  type: Input
1107
1544
  }], library: [{
@@ -1365,63 +1802,302 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
1365
1802
  type: Output
1366
1803
  }] } });
1367
1804
 
1368
- class PdmDatePickerComponent {
1805
+ class PdmLabelComponent {
1369
1806
  constructor() {
1370
- this.variant = 'default';
1807
+ this.forId = '';
1808
+ this.required = false;
1371
1809
  this.className = '';
1372
- this.open = false;
1373
- this.label = 'Date of Birth';
1374
- this.value = 'Select a date';
1375
- this.month = 6;
1376
- this.year = 2025;
1377
- this.selectedDay = 25;
1378
- this.time = '10:30:00';
1379
- this.naturalLanguageValue = 'In 2 days';
1380
- this.naturalLanguageHint = 'Your post will be published on June 21, 2025.';
1381
- this.openChange = new EventEmitter();
1810
+ }
1811
+ }
1812
+ PdmLabelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmLabelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1813
+ PdmLabelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmLabelComponent, selector: "pdm-label", inputs: { forId: "forId", required: "required", className: "className" }, ngImport: i0, template: "<label\n [attr.for]=\"forId\"\n [ngClass]=\"['text-sm font-medium leading-none text-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-70', className]\"\n>\n <ng-content></ng-content>\n <span *ngIf=\"required\" class=\"ml-1 text-destructive\">*</span>\n</label>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1814
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmLabelComponent, decorators: [{
1815
+ type: Component,
1816
+ args: [{ selector: 'pdm-label', changeDetection: ChangeDetectionStrategy.OnPush, template: "<label\n [attr.for]=\"forId\"\n [ngClass]=\"['text-sm font-medium leading-none text-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-70', className]\"\n>\n <ng-content></ng-content>\n <span *ngIf=\"required\" class=\"ml-1 text-destructive\">*</span>\n</label>\n" }]
1817
+ }], propDecorators: { forId: [{
1818
+ type: Input
1819
+ }], required: [{
1820
+ type: Input
1821
+ }], className: [{
1822
+ type: Input
1823
+ }] } });
1824
+
1825
+ let nextDatePickerId = 0;
1826
+ class PdmDatePickerComponent {
1827
+ constructor(elementRef, cdr) {
1828
+ this.elementRef = elementRef;
1829
+ this.cdr = cdr;
1830
+ this._value = null;
1831
+ this._rangeValue = null;
1832
+ this._open = false;
1833
+ this.instanceId = `pdm-date-picker-${++nextDatePickerId}`;
1834
+ this.triggerFocused = false;
1835
+ this.id = '';
1836
+ this.variant = 'single';
1837
+ this.label = '';
1838
+ this.labelClassName = '';
1839
+ this.className = '';
1840
+ this.triggerClassName = '';
1841
+ this.panelClassName = '';
1842
+ this.placeholder = 'Pick a date';
1843
+ this.rangePlaceholder = 'Pick a date range';
1844
+ this.format = 'MMM d, yyyy';
1845
+ this.disabled = false;
1846
+ this.readonly = false;
1847
+ this.required = false;
1848
+ this.invalid = false;
1849
+ this.allowSameDayRange = true;
1850
+ this.closeOnSelect = true;
1851
+ this.minDate = null;
1852
+ this.maxDate = null;
1853
+ this.disabledDates = [];
1854
+ this.isDateDisabled = null;
1382
1855
  this.valueChange = new EventEmitter();
1856
+ this.rangeValueChange = new EventEmitter();
1857
+ this.openChange = new EventEmitter();
1858
+ this.monthChange = new EventEmitter();
1383
1859
  }
1384
- toggle() {
1385
- this.openChange.emit(!this.open);
1860
+ set open(value) {
1861
+ this._open = !!value;
1862
+ this.cdr.markForCheck();
1386
1863
  }
1387
- selectPreset(value) {
1388
- this.valueChange.emit(value);
1864
+ get open() {
1865
+ return this._open;
1866
+ }
1867
+ set value(value) {
1868
+ this._value = this.normalizeDate(value);
1869
+ this.cdr.markForCheck();
1870
+ }
1871
+ get value() {
1872
+ return this._value;
1873
+ }
1874
+ set rangeValue(value) {
1875
+ this._rangeValue = value
1876
+ ? {
1877
+ start: this.normalizeDate(value.start),
1878
+ end: this.normalizeDate(value.end)
1879
+ }
1880
+ : null;
1881
+ this.cdr.markForCheck();
1882
+ }
1883
+ get rangeValue() {
1884
+ return this._rangeValue;
1885
+ }
1886
+ get resolvedVariant() {
1887
+ return this.variant === 'range' ? 'range' : 'single';
1888
+ }
1889
+ get triggerId() {
1890
+ return this.id || `${this.instanceId}-trigger`;
1891
+ }
1892
+ get panelId() {
1893
+ return `${this.id || this.instanceId}-panel`;
1894
+ }
1895
+ get hasSingleValue() {
1896
+ return this.resolvedVariant === 'single' && !!this._value;
1897
+ }
1898
+ get hasRangeValue() {
1899
+ var _a;
1900
+ return this.resolvedVariant === 'range' && !!((_a = this._rangeValue) === null || _a === void 0 ? void 0 : _a.start);
1389
1901
  }
1390
- get monthLabel() {
1391
- return new Date(this.year, this.month - 1, 1).toLocaleString('en-US', { month: 'short' });
1902
+ get displayText() {
1903
+ var _a, _b, _c, _d;
1904
+ if (this.resolvedVariant === 'single') {
1905
+ return this._value ? this.formatDate(this._value) : this.placeholder;
1906
+ }
1907
+ const start = (_b = (_a = this._rangeValue) === null || _a === void 0 ? void 0 : _a.start) !== null && _b !== void 0 ? _b : null;
1908
+ const end = (_d = (_c = this._rangeValue) === null || _c === void 0 ? void 0 : _c.end) !== null && _d !== void 0 ? _d : null;
1909
+ if (!start) {
1910
+ return this.rangePlaceholder;
1911
+ }
1912
+ if (!end) {
1913
+ return `${this.formatDate(start)} -`;
1914
+ }
1915
+ return `${this.formatDate(start)} - ${this.formatDate(end)}`;
1916
+ }
1917
+ get textClasses() {
1918
+ const hasValue = this.resolvedVariant === 'single' ? this.hasSingleValue : this.hasRangeValue;
1919
+ return [
1920
+ 'min-w-0 flex-1 truncate text-left text-sm leading-5',
1921
+ hasValue ? 'text-foreground' : 'text-muted-foreground'
1922
+ ];
1923
+ }
1924
+ get rootClasses() {
1925
+ return [
1926
+ 'grid gap-2',
1927
+ this.resolvedVariant === 'range' ? 'w-[280px]' : 'w-[197px]',
1928
+ this.className
1929
+ ];
1930
+ }
1931
+ get triggerClasses() {
1932
+ const focusStyle = this.open || this.triggerFocused;
1933
+ return [
1934
+ 'relative flex w-full items-center gap-2 overflow-hidden rounded-lg border px-3 py-[7.5px] text-left shadow-xs outline-none transition-colors',
1935
+ 'min-h-[36px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50',
1936
+ focusStyle
1937
+ ? 'bg-accent border-neutral-400 ring-3 ring-neutral-300'
1938
+ : 'bg-input border-input',
1939
+ this.invalid ? 'border-destructive ring-destructive/20' : '',
1940
+ this.triggerClassName
1941
+ ];
1942
+ }
1943
+ get panelClasses() {
1944
+ return [
1945
+ 'absolute left-0 top-full z-30 mt-2',
1946
+ this.panelClassName
1947
+ ];
1948
+ }
1949
+ toggleOpen() {
1950
+ if (this.disabled || this.readonly) {
1951
+ return;
1952
+ }
1953
+ this.setOpen(!this.open);
1954
+ }
1955
+ onTriggerFocus() {
1956
+ this.triggerFocused = true;
1957
+ this.cdr.markForCheck();
1958
+ }
1959
+ onTriggerBlur() {
1960
+ this.triggerFocused = false;
1961
+ this.cdr.markForCheck();
1962
+ }
1963
+ onCalendarValueChange(value) {
1964
+ this._value = this.normalizeDate(value);
1965
+ this.valueChange.emit(this._value ? this.cloneDate(this._value) : null);
1966
+ if (this.closeOnSelect && this._value) {
1967
+ this.setOpen(false);
1968
+ }
1969
+ else {
1970
+ this.cdr.markForCheck();
1971
+ }
1972
+ }
1973
+ onCalendarRangeValueChange(value) {
1974
+ var _a, _b;
1975
+ this._rangeValue = value
1976
+ ? {
1977
+ start: this.normalizeDate(value.start),
1978
+ end: this.normalizeDate(value.end)
1979
+ }
1980
+ : null;
1981
+ this.rangeValueChange.emit(this._rangeValue
1982
+ ? {
1983
+ start: this._rangeValue.start ? this.cloneDate(this._rangeValue.start) : null,
1984
+ end: this._rangeValue.end ? this.cloneDate(this._rangeValue.end) : null
1985
+ }
1986
+ : null);
1987
+ if (this.closeOnSelect && ((_a = this._rangeValue) === null || _a === void 0 ? void 0 : _a.start) && ((_b = this._rangeValue) === null || _b === void 0 ? void 0 : _b.end)) {
1988
+ this.setOpen(false);
1989
+ return;
1990
+ }
1991
+ this.cdr.markForCheck();
1992
+ }
1993
+ onCalendarMonthChange(month) {
1994
+ this.monthChange.emit(this.cloneDate(month));
1995
+ }
1996
+ onEscape() {
1997
+ if (this.open) {
1998
+ this.setOpen(false);
1999
+ }
2000
+ }
2001
+ onDocumentClick(event) {
2002
+ if (!this.open) {
2003
+ return;
2004
+ }
2005
+ const target = event.target;
2006
+ if (target && !this.elementRef.nativeElement.contains(target)) {
2007
+ this.setOpen(false);
2008
+ }
2009
+ }
2010
+ setOpen(nextOpen) {
2011
+ if (this._open === nextOpen) {
2012
+ return;
2013
+ }
2014
+ this._open = nextOpen;
2015
+ this.openChange.emit(this._open);
2016
+ this.cdr.markForCheck();
2017
+ }
2018
+ formatDate(date) {
2019
+ try {
2020
+ return format(date, this.format || 'MMM d, yyyy');
2021
+ }
2022
+ catch (_a) {
2023
+ return format(date, 'MMM d, yyyy');
2024
+ }
2025
+ }
2026
+ normalizeDate(value) {
2027
+ if (!(value instanceof Date) || Number.isNaN(value.getTime())) {
2028
+ return null;
2029
+ }
2030
+ return new Date(value.getFullYear(), value.getMonth(), value.getDate());
2031
+ }
2032
+ cloneDate(date) {
2033
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate());
1392
2034
  }
1393
2035
  }
1394
- PdmDatePickerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDatePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1395
- PdmDatePickerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmDatePickerComponent, selector: "pdm-date-picker", inputs: { variant: "variant", className: "className", open: "open", label: "label", value: "value", month: "month", year: "year", selectedDay: "selectedDay", time: "time", naturalLanguageValue: "naturalLanguageValue", naturalLanguageHint: "naturalLanguageHint" }, outputs: { openChange: "openChange", valueChange: "valueChange" }, ngImport: i0, template: "<section [ngClass]=\"['flex flex-col gap-3', className]\" class=\"w-full max-w-sm\">\n <label class=\"text-sm font-medium text-foreground\">{{ label }}</label>\n\n <div class=\"flex items-center gap-2\" *ngIf=\"variant === 'date-time'\">\n <button type=\"button\" class=\"flex h-9 flex-1 items-center justify-between rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm\" (click)=\"toggle()\">\n <span class=\"truncate text-xs text-foreground\">{{ value }}</span>\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4 text-foreground\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M7 10L12 15L17 10\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path></svg>\n </button>\n <div class=\"flex h-9 w-24 items-center rounded-md border border-input bg-transparent px-3 py-1 text-xs text-foreground shadow-sm\">{{ time }}</div>\n </div>\n\n <div *ngIf=\"variant !== 'date-time'\" class=\"flex flex-col gap-2\">\n <button type=\"button\" class=\"flex h-9 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm\" (click)=\"toggle()\">\n <span class=\"truncate text-sm text-foreground\">{{ variant === 'natural-language' ? naturalLanguageValue : value }}</span>\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4 text-foreground\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M7 10L12 15L17 10\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path></svg>\n </button>\n\n <p *ngIf=\"variant === 'natural-language'\" class=\"text-xs text-muted-foreground\">{{ naturalLanguageHint }}</p>\n </div>\n\n <div *ngIf=\"open\" class=\"w-full rounded-lg border border-border bg-background p-3 shadow-sm\">\n <div class=\"mb-4 flex items-center justify-between\">\n <button type=\"button\" class=\"h-8 w-8 rounded-md text-foreground hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\">\u2039</button>\n <div class=\"flex items-center gap-1.5\">\n <button type=\"button\" class=\"inline-flex h-8 items-center gap-1 rounded-md border border-input px-2 text-sm font-medium text-foreground shadow-sm\">{{ monthLabel }} <span>\u02C5</span></button>\n <button type=\"button\" class=\"inline-flex h-8 items-center gap-1 rounded-md border border-input px-2 text-sm font-medium text-foreground shadow-sm\">{{ year }} <span>\u02C5</span></button>\n </div>\n <button type=\"button\" class=\"h-8 w-8 rounded-md text-foreground hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\">\u203A</button>\n </div>\n\n <pdm-calendar [month]=\"month\" [year]=\"year\" [selectedDay]=\"selectedDay\" mode=\"single\"></pdm-calendar>\n\n <div *ngIf=\"variant === 'with-input' || variant === 'natural-language'\" class=\"mt-3 flex gap-2\">\n <button type=\"button\" class=\"h-8 rounded-md border border-input px-3 text-xs text-foreground\" (click)=\"selectPreset('Today')\">Today</button>\n <button type=\"button\" class=\"h-8 rounded-md border border-input px-3 text-xs text-foreground\" (click)=\"selectPreset('Tomorrow')\">Tomorrow</button>\n </div>\n </div>\n</section>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: PdmCalendarComponent, selector: "pdm-calendar", inputs: ["mode", "month", "year", "selectedDay", "rangeStartDay", "rangeEndDay", "className"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2036
+ PdmDatePickerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDatePickerComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
2037
+ PdmDatePickerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmDatePickerComponent, selector: "pdm-date-picker", inputs: { id: "id", variant: "variant", label: "label", labelClassName: "labelClassName", className: "className", triggerClassName: "triggerClassName", panelClassName: "panelClassName", placeholder: "placeholder", rangePlaceholder: "rangePlaceholder", format: "format", disabled: "disabled", readonly: "readonly", required: "required", invalid: "invalid", allowSameDayRange: "allowSameDayRange", closeOnSelect: "closeOnSelect", minDate: "minDate", maxDate: "maxDate", disabledDates: "disabledDates", isDateDisabled: "isDateDisabled", open: "open", value: "value", rangeValue: "rangeValue" }, outputs: { valueChange: "valueChange", rangeValueChange: "rangeValueChange", openChange: "openChange", monthChange: "monthChange" }, host: { listeners: { "document:keydown.escape": "onEscape()", "document:click": "onDocumentClick($event)" } }, ngImport: i0, template: "<div [ngClass]=\"rootClasses\">\n <pdm-label *ngIf=\"label\" [forId]=\"triggerId\" [required]=\"required\" [className]=\"labelClassName\">\n {{ label }}\n </pdm-label>\n\n <div class=\"relative inline-block w-full\">\n <button\n type=\"button\"\n [id]=\"triggerId\"\n [disabled]=\"disabled\"\n [attr.aria-expanded]=\"open\"\n [attr.aria-controls]=\"panelId\"\n [attr.aria-haspopup]=\"'dialog'\"\n [attr.aria-invalid]=\"invalid\"\n [ngClass]=\"triggerClasses\"\n [attr.title]=\"displayText\"\n (click)=\"toggleOpen()\"\n (focus)=\"onTriggerFocus()\"\n (blur)=\"onTriggerBlur()\"\n >\n <span class=\"flex h-5 w-5 shrink-0 items-center justify-center p-0.5 text-muted-foreground\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\">\n <path d=\"M8 2v4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n <path d=\"M16 2v4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n <rect x=\"3\" y=\"4.5\" width=\"18\" height=\"16.5\" rx=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></rect>\n <path d=\"M3 9.5h18\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </span>\n\n <span [ngClass]=\"textClasses\">{{ displayText }}</span>\n </button>\n\n <div *ngIf=\"open\" [id]=\"panelId\" [ngClass]=\"panelClasses\" role=\"dialog\" [attr.aria-labelledby]=\"label ? triggerId : null\">\n <pdm-calendar\n [variant]=\"resolvedVariant\"\n [value]=\"value\"\n [rangeValue]=\"rangeValue\"\n [readonly]=\"readonly\"\n [allowSameDayRange]=\"allowSameDayRange\"\n [minDate]=\"minDate\"\n [maxDate]=\"maxDate\"\n [disabledDates]=\"disabledDates\"\n [isDateDisabled]=\"isDateDisabled\"\n (valueChange)=\"onCalendarValueChange($event)\"\n (rangeValueChange)=\"onCalendarRangeValueChange($event)\"\n (monthChange)=\"onCalendarMonthChange($event)\"\n ></pdm-calendar>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: PdmCalendarComponent, selector: "pdm-calendar", inputs: ["variant", "className", "disabledDates", "minDate", "maxDate", "isDateDisabled", "allowSameDayRange", "readonly", "value", "rangeValue", "month"], outputs: ["valueChange", "rangeValueChange", "monthChange", "dateClick", "disabledDateClick"] }, { kind: "component", type: PdmLabelComponent, selector: "pdm-label", inputs: ["forId", "required", "className"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1396
2038
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDatePickerComponent, decorators: [{
1397
2039
  type: Component,
1398
- args: [{ selector: 'pdm-date-picker', changeDetection: ChangeDetectionStrategy.OnPush, template: "<section [ngClass]=\"['flex flex-col gap-3', className]\" class=\"w-full max-w-sm\">\n <label class=\"text-sm font-medium text-foreground\">{{ label }}</label>\n\n <div class=\"flex items-center gap-2\" *ngIf=\"variant === 'date-time'\">\n <button type=\"button\" class=\"flex h-9 flex-1 items-center justify-between rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm\" (click)=\"toggle()\">\n <span class=\"truncate text-xs text-foreground\">{{ value }}</span>\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4 text-foreground\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M7 10L12 15L17 10\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path></svg>\n </button>\n <div class=\"flex h-9 w-24 items-center rounded-md border border-input bg-transparent px-3 py-1 text-xs text-foreground shadow-sm\">{{ time }}</div>\n </div>\n\n <div *ngIf=\"variant !== 'date-time'\" class=\"flex flex-col gap-2\">\n <button type=\"button\" class=\"flex h-9 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm\" (click)=\"toggle()\">\n <span class=\"truncate text-sm text-foreground\">{{ variant === 'natural-language' ? naturalLanguageValue : value }}</span>\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4 text-foreground\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M7 10L12 15L17 10\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path></svg>\n </button>\n\n <p *ngIf=\"variant === 'natural-language'\" class=\"text-xs text-muted-foreground\">{{ naturalLanguageHint }}</p>\n </div>\n\n <div *ngIf=\"open\" class=\"w-full rounded-lg border border-border bg-background p-3 shadow-sm\">\n <div class=\"mb-4 flex items-center justify-between\">\n <button type=\"button\" class=\"h-8 w-8 rounded-md text-foreground hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\">\u2039</button>\n <div class=\"flex items-center gap-1.5\">\n <button type=\"button\" class=\"inline-flex h-8 items-center gap-1 rounded-md border border-input px-2 text-sm font-medium text-foreground shadow-sm\">{{ monthLabel }} <span>\u02C5</span></button>\n <button type=\"button\" class=\"inline-flex h-8 items-center gap-1 rounded-md border border-input px-2 text-sm font-medium text-foreground shadow-sm\">{{ year }} <span>\u02C5</span></button>\n </div>\n <button type=\"button\" class=\"h-8 w-8 rounded-md text-foreground hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\">\u203A</button>\n </div>\n\n <pdm-calendar [month]=\"month\" [year]=\"year\" [selectedDay]=\"selectedDay\" mode=\"single\"></pdm-calendar>\n\n <div *ngIf=\"variant === 'with-input' || variant === 'natural-language'\" class=\"mt-3 flex gap-2\">\n <button type=\"button\" class=\"h-8 rounded-md border border-input px-3 text-xs text-foreground\" (click)=\"selectPreset('Today')\">Today</button>\n <button type=\"button\" class=\"h-8 rounded-md border border-input px-3 text-xs text-foreground\" (click)=\"selectPreset('Tomorrow')\">Tomorrow</button>\n </div>\n </div>\n</section>\n" }]
1399
- }], propDecorators: { variant: [{
2040
+ args: [{ selector: 'pdm-date-picker', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"rootClasses\">\n <pdm-label *ngIf=\"label\" [forId]=\"triggerId\" [required]=\"required\" [className]=\"labelClassName\">\n {{ label }}\n </pdm-label>\n\n <div class=\"relative inline-block w-full\">\n <button\n type=\"button\"\n [id]=\"triggerId\"\n [disabled]=\"disabled\"\n [attr.aria-expanded]=\"open\"\n [attr.aria-controls]=\"panelId\"\n [attr.aria-haspopup]=\"'dialog'\"\n [attr.aria-invalid]=\"invalid\"\n [ngClass]=\"triggerClasses\"\n [attr.title]=\"displayText\"\n (click)=\"toggleOpen()\"\n (focus)=\"onTriggerFocus()\"\n (blur)=\"onTriggerBlur()\"\n >\n <span class=\"flex h-5 w-5 shrink-0 items-center justify-center p-0.5 text-muted-foreground\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\">\n <path d=\"M8 2v4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n <path d=\"M16 2v4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n <rect x=\"3\" y=\"4.5\" width=\"18\" height=\"16.5\" rx=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></rect>\n <path d=\"M3 9.5h18\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </span>\n\n <span [ngClass]=\"textClasses\">{{ displayText }}</span>\n </button>\n\n <div *ngIf=\"open\" [id]=\"panelId\" [ngClass]=\"panelClasses\" role=\"dialog\" [attr.aria-labelledby]=\"label ? triggerId : null\">\n <pdm-calendar\n [variant]=\"resolvedVariant\"\n [value]=\"value\"\n [rangeValue]=\"rangeValue\"\n [readonly]=\"readonly\"\n [allowSameDayRange]=\"allowSameDayRange\"\n [minDate]=\"minDate\"\n [maxDate]=\"maxDate\"\n [disabledDates]=\"disabledDates\"\n [isDateDisabled]=\"isDateDisabled\"\n (valueChange)=\"onCalendarValueChange($event)\"\n (rangeValueChange)=\"onCalendarRangeValueChange($event)\"\n (monthChange)=\"onCalendarMonthChange($event)\"\n ></pdm-calendar>\n </div>\n </div>\n</div>\n" }]
2041
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { id: [{
2042
+ type: Input
2043
+ }], variant: [{
2044
+ type: Input
2045
+ }], label: [{
2046
+ type: Input
2047
+ }], labelClassName: [{
1400
2048
  type: Input
1401
2049
  }], className: [{
1402
2050
  type: Input
1403
- }], open: [{
2051
+ }], triggerClassName: [{
1404
2052
  type: Input
1405
- }], label: [{
2053
+ }], panelClassName: [{
1406
2054
  type: Input
1407
- }], value: [{
2055
+ }], placeholder: [{
1408
2056
  type: Input
1409
- }], month: [{
2057
+ }], rangePlaceholder: [{
1410
2058
  type: Input
1411
- }], year: [{
2059
+ }], format: [{
1412
2060
  type: Input
1413
- }], selectedDay: [{
2061
+ }], disabled: [{
1414
2062
  type: Input
1415
- }], time: [{
2063
+ }], readonly: [{
1416
2064
  type: Input
1417
- }], naturalLanguageValue: [{
2065
+ }], required: [{
1418
2066
  type: Input
1419
- }], naturalLanguageHint: [{
2067
+ }], invalid: [{
2068
+ type: Input
2069
+ }], allowSameDayRange: [{
2070
+ type: Input
2071
+ }], closeOnSelect: [{
1420
2072
  type: Input
2073
+ }], minDate: [{
2074
+ type: Input
2075
+ }], maxDate: [{
2076
+ type: Input
2077
+ }], disabledDates: [{
2078
+ type: Input
2079
+ }], isDateDisabled: [{
2080
+ type: Input
2081
+ }], valueChange: [{
2082
+ type: Output
2083
+ }], rangeValueChange: [{
2084
+ type: Output
1421
2085
  }], openChange: [{
1422
2086
  type: Output
1423
- }], valueChange: [{
2087
+ }], monthChange: [{
1424
2088
  type: Output
2089
+ }], open: [{
2090
+ type: Input
2091
+ }], value: [{
2092
+ type: Input
2093
+ }], rangeValue: [{
2094
+ type: Input
2095
+ }], onEscape: [{
2096
+ type: HostListener,
2097
+ args: ['document:keydown.escape']
2098
+ }], onDocumentClick: [{
2099
+ type: HostListener,
2100
+ args: ['document:click', ['$event']]
1425
2101
  }] } });
1426
2102
 
1427
2103
  class PdmDialogComponent {
@@ -2243,26 +2919,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
2243
2919
  type: Input
2244
2920
  }] } });
2245
2921
 
2246
- class PdmLabelComponent {
2247
- constructor() {
2248
- this.forId = '';
2249
- this.required = false;
2250
- this.className = '';
2251
- }
2252
- }
2253
- PdmLabelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmLabelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2254
- PdmLabelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmLabelComponent, selector: "pdm-label", inputs: { forId: "forId", required: "required", className: "className" }, ngImport: i0, template: "<label\n [attr.for]=\"forId\"\n [ngClass]=\"['text-sm font-medium leading-none text-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-70', className]\"\n>\n <ng-content></ng-content>\n <span *ngIf=\"required\" class=\"ml-1 text-destructive\">*</span>\n</label>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2255
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmLabelComponent, decorators: [{
2256
- type: Component,
2257
- args: [{ selector: 'pdm-label', changeDetection: ChangeDetectionStrategy.OnPush, template: "<label\n [attr.for]=\"forId\"\n [ngClass]=\"['text-sm font-medium leading-none text-foreground peer-disabled:cursor-not-allowed peer-disabled:opacity-70', className]\"\n>\n <ng-content></ng-content>\n <span *ngIf=\"required\" class=\"ml-1 text-destructive\">*</span>\n</label>\n" }]
2258
- }], propDecorators: { forId: [{
2259
- type: Input
2260
- }], required: [{
2261
- type: Input
2262
- }], className: [{
2263
- type: Input
2264
- }] } });
2265
-
2266
2922
  class PdmMenubarComponent {
2267
2923
  constructor() {
2268
2924
  this.menus = [];