pdm-ui-kit 0.1.32 → 0.1.34

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,7 +1,7 @@
1
1
  import * as i1 from '@angular/common';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
- import { EventEmitter, Component, ChangeDetectionStrategy, Input, Output, HostListener, ViewChildren, ViewChild, NgModule } from '@angular/core';
4
+ import { EventEmitter, Component, ChangeDetectionStrategy, Input, Output, HostListener, ViewChild, ViewChildren, NgModule } from '@angular/core';
5
5
  import { icons } from 'lucide';
6
6
  import * as i1$1 from '@angular/platform-browser';
7
7
  import { format } from 'date-fns';
@@ -313,7 +313,6 @@ class PdmButtonGroupComponent {
313
313
  '[&>pdm-button>button]:!rounded-none',
314
314
  '[&>pdm-button:first-child>button]:!rounded-l-md',
315
315
  '[&>pdm-button:last-child>button]:!rounded-r-md',
316
- '[&>pdm-button:not(:first-child)>button]:!border-l-0',
317
316
  '[&>pdm-input>div>input]:!rounded-none',
318
317
  '[&>pdm-input:first-child>div>input]:!rounded-l-md',
319
318
  '[&>pdm-input:last-child>div>input]:!rounded-r-md',
@@ -331,12 +330,10 @@ class PdmButtonGroupComponent {
331
330
  '[&>pdm-tooltip>span>pdm-button>button]:!rounded-none',
332
331
  '[&>pdm-tooltip:first-child>span>pdm-button>button]:!rounded-l-md',
333
332
  '[&>pdm-tooltip:last-child>span>pdm-button>button]:!rounded-r-md',
334
- '[&>pdm-tooltip:not(:first-child)>span>pdm-button>button]:!border-l-0',
335
333
  '[&>pdm-tooltip>span>pdm-button>button]:shadow-none',
336
334
  '[&>pdm-tooltip>span>button]:!rounded-none',
337
335
  '[&>pdm-tooltip:first-child>span>button]:!rounded-l-md',
338
336
  '[&>pdm-tooltip:last-child>span>button]:!rounded-r-md',
339
- '[&>pdm-tooltip:not(:first-child)>span>button]:!border-l-0',
340
337
  '[&>pdm-tooltip>span>button]:shadow-none',
341
338
  '[&>pdm-tooltip>span>pdm-input>div>input]:!rounded-none',
342
339
  '[&>pdm-tooltip:first-child>span>pdm-input>div>input]:!rounded-l-md',
@@ -396,7 +393,6 @@ class PdmButtonGroupComponent {
396
393
  '[&>pdm-input>div>input]:bg-background',
397
394
  '[&>pdm-input>div>input]:shadow-none',
398
395
  '[&>pdm-button>button]:shadow-none',
399
- '[&>pdm-button:not(:first-child)>button]:!border-t-0',
400
396
  '[&>pdm-tooltip>span>*]:rounded-none',
401
397
  '[&>pdm-tooltip:first-child>span>*]:rounded-t-md',
402
398
  '[&>pdm-tooltip:last-child>span>*]:rounded-b-md',
@@ -404,12 +400,10 @@ class PdmButtonGroupComponent {
404
400
  '[&>pdm-tooltip>span>pdm-button>button]:!rounded-none',
405
401
  '[&>pdm-tooltip:first-child>span>pdm-button>button]:!rounded-t-md',
406
402
  '[&>pdm-tooltip:last-child>span>pdm-button>button]:!rounded-b-md',
407
- '[&>pdm-tooltip:not(:first-child)>span>pdm-button>button]:!border-t-0',
408
403
  '[&>pdm-tooltip>span>pdm-button>button]:shadow-none',
409
404
  '[&>pdm-tooltip>span>button]:!rounded-none',
410
405
  '[&>pdm-tooltip:first-child>span>button]:!rounded-t-md',
411
406
  '[&>pdm-tooltip:last-child>span>button]:!rounded-b-md',
412
- '[&>pdm-tooltip:not(:first-child)>span>button]:!border-t-0',
413
407
  '[&>pdm-tooltip>span>button]:shadow-none',
414
408
  '[&>pdm-tooltip>span>pdm-input>div>input]:!rounded-none',
415
409
  '[&>pdm-tooltip:first-child>span>pdm-input>div>input]:!rounded-t-md',
@@ -797,8 +791,12 @@ class PdmCalendarComponent {
797
791
  }
798
792
  dayButtonClasses(cell) {
799
793
  return [
800
- 'relative z-10 flex h-8 w-8 appearance-none items-center justify-center rounded-md border-0 bg-transparent p-0 text-sm leading-5',
801
- cell.selected ? 'bg-primary text-primary-foreground' : cell.rangeFill ? 'text-accent-foreground' : 'text-foreground',
794
+ 'relative z-10 flex h-8 w-8 appearance-none items-center justify-center rounded-md border-0 p-0 text-sm leading-5',
795
+ cell.selected
796
+ ? 'bg-primary text-primary-foreground'
797
+ : cell.rangeFill
798
+ ? 'bg-transparent text-accent-foreground'
799
+ : 'bg-transparent text-foreground',
802
800
  cell.muted && !cell.rangeFill ? 'opacity-50' : '',
803
801
  cell.disabled ? 'cursor-not-allowed opacity-40' : '',
804
802
  !cell.disabled && !this.readonly && !cell.selected ? 'hover:bg-accent/70' : ''
@@ -1961,6 +1959,7 @@ class PdmDatePickerComponent {
1961
1959
  this._open = false;
1962
1960
  this.instanceId = `pdm-date-picker-${++nextDatePickerId}`;
1963
1961
  this.triggerFocused = false;
1962
+ this.panelPlacement = 'bottom';
1964
1963
  this.id = '';
1965
1964
  this.variant = 'single';
1966
1965
  this.label = '';
@@ -1990,6 +1989,12 @@ class PdmDatePickerComponent {
1990
1989
  }
1991
1990
  set open(value) {
1992
1991
  this._open = !!value;
1992
+ if (this._open) {
1993
+ this.schedulePanelPlacementUpdate();
1994
+ }
1995
+ else {
1996
+ this.panelPlacement = 'bottom';
1997
+ }
1993
1998
  this.cdr.markForCheck();
1994
1999
  }
1995
2000
  get open() {
@@ -2071,7 +2076,9 @@ class PdmDatePickerComponent {
2071
2076
  }
2072
2077
  get panelClasses() {
2073
2078
  return [
2074
- 'absolute left-0 top-full z-30 mt-2',
2079
+ this.panelPlacement === 'top'
2080
+ ? 'absolute bottom-full left-0 z-30 mb-2'
2081
+ : 'absolute left-0 top-full z-30 mt-2',
2075
2082
  this.panelClassName
2076
2083
  ];
2077
2084
  }
@@ -2135,14 +2142,47 @@ class PdmDatePickerComponent {
2135
2142
  this.setOpen(false);
2136
2143
  }
2137
2144
  }
2145
+ onViewportChange() {
2146
+ this.updatePanelPlacement();
2147
+ }
2138
2148
  setOpen(nextOpen) {
2139
2149
  if (this._open === nextOpen) {
2140
2150
  return;
2141
2151
  }
2142
2152
  this._open = nextOpen;
2143
2153
  this.openChange.emit(this._open);
2154
+ if (this._open) {
2155
+ this.schedulePanelPlacementUpdate();
2156
+ }
2157
+ else {
2158
+ this.panelPlacement = 'bottom';
2159
+ }
2144
2160
  this.cdr.markForCheck();
2145
2161
  }
2162
+ schedulePanelPlacementUpdate() {
2163
+ setTimeout(() => this.updatePanelPlacement());
2164
+ }
2165
+ updatePanelPlacement() {
2166
+ if (!this._open) {
2167
+ return;
2168
+ }
2169
+ const triggerEl = this.triggerRef?.nativeElement;
2170
+ const panelEl = this.panelRef?.nativeElement;
2171
+ if (!triggerEl || !panelEl || typeof window === 'undefined') {
2172
+ return;
2173
+ }
2174
+ const viewportHeight = window.innerHeight;
2175
+ const gap = 8;
2176
+ const triggerRect = triggerEl.getBoundingClientRect();
2177
+ const panelHeight = panelEl.offsetHeight;
2178
+ const spaceBelow = Math.max(0, viewportHeight - triggerRect.bottom - gap);
2179
+ const spaceAbove = Math.max(0, triggerRect.top - gap);
2180
+ const nextPlacement = spaceBelow < panelHeight && spaceAbove > spaceBelow ? 'top' : 'bottom';
2181
+ if (this.panelPlacement !== nextPlacement) {
2182
+ this.panelPlacement = nextPlacement;
2183
+ this.cdr.markForCheck();
2184
+ }
2185
+ }
2146
2186
  formatDate(date) {
2147
2187
  try {
2148
2188
  return format(date, this.format || 'MMM d, yyyy');
@@ -2162,11 +2202,17 @@ class PdmDatePickerComponent {
2162
2202
  }
2163
2203
  }
2164
2204
  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 });
2165
- 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", minYear: "minYear", maxYear: "maxYear", 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 [minYear]=\"minYear\"\n [maxYear]=\"maxYear\"\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", "minYear", "maxYear", "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 });
2205
+ 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", minYear: "minYear", maxYear: "maxYear", 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)", "window:resize": "onViewportChange()", "window:scroll": "onViewportChange()" } }, viewQueries: [{ propertyName: "triggerRef", first: true, predicate: ["triggerEl"], descendants: true }, { propertyName: "panelRef", first: true, predicate: ["panelEl"], descendants: true }], 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 #triggerEl\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\" #panelEl [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 [minYear]=\"minYear\"\n [maxYear]=\"maxYear\"\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", "minYear", "maxYear", "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 });
2166
2206
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDatePickerComponent, decorators: [{
2167
2207
  type: Component,
2168
- 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 [minYear]=\"minYear\"\n [maxYear]=\"maxYear\"\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" }]
2169
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { id: [{
2208
+ 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 #triggerEl\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\" #panelEl [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 [minYear]=\"minYear\"\n [maxYear]=\"maxYear\"\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" }]
2209
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { triggerRef: [{
2210
+ type: ViewChild,
2211
+ args: ['triggerEl']
2212
+ }], panelRef: [{
2213
+ type: ViewChild,
2214
+ args: ['panelEl']
2215
+ }], id: [{
2170
2216
  type: Input
2171
2217
  }], variant: [{
2172
2218
  type: Input
@@ -2230,6 +2276,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
2230
2276
  }], onDocumentClick: [{
2231
2277
  type: HostListener,
2232
2278
  args: ['document:click', ['$event']]
2279
+ }], onViewportChange: [{
2280
+ type: HostListener,
2281
+ args: ['window:resize']
2282
+ }, {
2283
+ type: HostListener,
2284
+ args: ['window:scroll']
2233
2285
  }] } });
2234
2286
 
2235
2287
  class PdmDialogComponent {
@@ -3140,8 +3192,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
3140
3192
  }] } });
3141
3193
 
3142
3194
  class PdmSelectComponent {
3143
- constructor(elementRef) {
3195
+ constructor(elementRef, cdr) {
3144
3196
  this.elementRef = elementRef;
3197
+ this.cdr = cdr;
3145
3198
  this.id = '';
3146
3199
  this.value = '';
3147
3200
  this.options = [];
@@ -3150,6 +3203,8 @@ class PdmSelectComponent {
3150
3203
  this.className = '';
3151
3204
  this.placeholder = 'Select an option';
3152
3205
  this.open = false;
3206
+ this.panelPlacement = 'bottom';
3207
+ this.panelMaxHeightPx = null;
3153
3208
  this.valueChange = new EventEmitter();
3154
3209
  }
3155
3210
  get selectedOption() {
@@ -3158,10 +3213,22 @@ class PdmSelectComponent {
3158
3213
  get selectedLabel() {
3159
3214
  return this.selectedOption?.label || this.placeholder;
3160
3215
  }
3216
+ get panelClasses() {
3217
+ return [
3218
+ 'absolute left-0 z-50 w-full overflow-y-auto rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md',
3219
+ this.panelPlacement === 'top' ? 'bottom-[calc(100%+4px)]' : 'top-[calc(100%+4px)]'
3220
+ ];
3221
+ }
3161
3222
  toggle() {
3162
3223
  if (this.disabled)
3163
3224
  return;
3164
3225
  this.open = !this.open;
3226
+ if (this.open) {
3227
+ this.schedulePanelPlacementUpdate();
3228
+ return;
3229
+ }
3230
+ this.panelPlacement = 'bottom';
3231
+ this.panelMaxHeightPx = null;
3165
3232
  }
3166
3233
  onChange(event) {
3167
3234
  this.valueChange.emit(event.target.value);
@@ -3182,13 +3249,39 @@ class PdmSelectComponent {
3182
3249
  onEscape() {
3183
3250
  this.open = false;
3184
3251
  }
3252
+ onViewportChange() {
3253
+ this.updatePanelPlacement();
3254
+ }
3255
+ schedulePanelPlacementUpdate() {
3256
+ setTimeout(() => this.updatePanelPlacement());
3257
+ }
3258
+ updatePanelPlacement() {
3259
+ if (!this.open)
3260
+ return;
3261
+ const triggerEl = this.triggerRef?.nativeElement;
3262
+ const panelEl = this.panelRef?.nativeElement;
3263
+ if (!triggerEl || !panelEl || typeof window === 'undefined') {
3264
+ return;
3265
+ }
3266
+ const viewportHeight = window.innerHeight;
3267
+ const gap = 4;
3268
+ const triggerRect = triggerEl.getBoundingClientRect();
3269
+ const panelHeight = panelEl.offsetHeight;
3270
+ const spaceBelow = Math.max(0, viewportHeight - triggerRect.bottom - gap);
3271
+ const spaceAbove = Math.max(0, triggerRect.top - gap);
3272
+ const nextPlacement = spaceBelow < panelHeight && spaceAbove > spaceBelow ? 'top' : 'bottom';
3273
+ const availableHeight = nextPlacement === 'top' ? spaceAbove : spaceBelow;
3274
+ this.panelPlacement = nextPlacement;
3275
+ this.panelMaxHeightPx = Math.max(120, Math.min(384, Math.floor(availableHeight)));
3276
+ this.cdr.markForCheck();
3277
+ }
3185
3278
  }
3186
- PdmSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmSelectComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
3187
- PdmSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmSelectComponent, selector: "pdm-select", inputs: { id: "id", value: "value", options: "options", disabled: "disabled", invalid: "invalid", className: "className", placeholder: "placeholder" }, outputs: { valueChange: "valueChange" }, host: { listeners: { "document:click": "onDocumentClick($event)", "document:keydown.escape": "onEscape()" } }, ngImport: i0, template: "<div [ngClass]=\"['relative', className || 'w-full']\">\n <button\n type=\"button\"\n [id]=\"id\"\n [disabled]=\"disabled\"\n [attr.aria-invalid]=\"invalid\"\n [attr.aria-expanded]=\"open\"\n [attr.data-state]=\"open ? 'open' : 'closed'\"\n aria-haspopup=\"listbox\"\n (click)=\"toggle()\"\n [ngClass]=\"[\n 'border-input focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/50 aria-invalid:ring-2 aria-invalid:ring-destructive aria-invalid:border-destructive flex h-9 w-full appearance-none items-center justify-between rounded-md border bg-background px-3 py-2 text-sm shadow-sm outline-none disabled:cursor-not-allowed disabled:opacity-50',\n ]\"\n >\n <span\n [ngClass]=\"[\n 'min-w-0 flex-1 truncate text-left leading-5',\n selectedOption\n ? 'font-medium text-foreground'\n : 'font-normal text-muted-foreground',\n ]\"\n >\n {{ selectedLabel }}\n </span>\n <pdm-icon\n name=\"chevron-down\"\n [size]=\"16\"\n className=\"shrink-0 text-muted-foreground\"\n ></pdm-icon>\n </button>\n\n <div\n *ngIf=\"open\"\n role=\"listbox\"\n [attr.aria-labelledby]=\"id || null\"\n class=\"absolute left-0 top-[calc(100%+4px)] z-50 max-h-96 w-full overflow-y-auto rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md\"\n >\n <button\n *ngFor=\"let option of options\"\n type=\"button\"\n role=\"option\"\n [attr.aria-selected]=\"option.value === value\"\n [disabled]=\"option.disabled\"\n (click)=\"selectOption(option)\"\n [ngClass]=\"[\n 'flex w-full appearance-none items-center justify-between rounded-sm border-0 bg-transparent px-2 py-1.5 text-left text-sm outline-none transition-colors',\n option.disabled\n ? 'cursor-not-allowed opacity-50'\n : 'hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground',\n option.value === value ? 'text-foreground' : '',\n ]\"\n >\n <span class=\"min-w-0 flex-1 truncate leading-5\">{{ option.label }}</span>\n <span\n *ngIf=\"option.value === value\"\n class=\"ml-2 flex shrink-0 items-center justify-end\"\n >\n <pdm-icon\n name=\"check\"\n [size]=\"16\"\n className=\"shrink-0 text-current\"\n ></pdm-icon>\n </span>\n </button>\n </div>\n\n <select\n class=\"sr-only\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n [value]=\"value\"\n (change)=\"onChange($event)\"\n >\n <option\n *ngFor=\"let option of options\"\n [value]=\"option.value\"\n [disabled]=\"option.disabled\"\n >\n {{ option.label }}\n </option>\n </select>\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: "component", type: PdmIconComponent, selector: "pdm-icon", inputs: ["name", "library", "assetUrl", "size", "strokeWidth", "className", "ariaLabel", "decorative"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3279
+ PdmSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmSelectComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3280
+ PdmSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmSelectComponent, selector: "pdm-select", inputs: { id: "id", value: "value", options: "options", disabled: "disabled", invalid: "invalid", className: "className", placeholder: "placeholder" }, outputs: { valueChange: "valueChange" }, host: { listeners: { "document:click": "onDocumentClick($event)", "document:keydown.escape": "onEscape()", "window:resize": "onViewportChange()", "window:scroll": "onViewportChange()" } }, viewQueries: [{ propertyName: "triggerRef", first: true, predicate: ["triggerEl"], descendants: true }, { propertyName: "panelRef", first: true, predicate: ["panelEl"], descendants: true }], ngImport: i0, template: "<div [ngClass]=\"['relative', className || 'w-full']\">\n <button\n #triggerEl\n type=\"button\"\n [id]=\"id\"\n [disabled]=\"disabled\"\n [attr.aria-invalid]=\"invalid\"\n [attr.aria-expanded]=\"open\"\n [attr.data-state]=\"open ? 'open' : 'closed'\"\n aria-haspopup=\"listbox\"\n (click)=\"toggle()\"\n [ngClass]=\"[\n 'border-input focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/50 aria-invalid:ring-2 aria-invalid:ring-destructive aria-invalid:border-destructive flex h-9 w-full appearance-none items-center justify-between rounded-md border bg-background px-3 py-2 text-sm shadow-sm outline-none disabled:cursor-not-allowed disabled:opacity-50',\n ]\"\n >\n <span\n [ngClass]=\"[\n 'min-w-0 flex-1 truncate text-left leading-5',\n selectedOption\n ? 'font-medium text-foreground'\n : 'font-normal text-muted-foreground',\n ]\"\n >\n {{ selectedLabel }}\n </span>\n <pdm-icon\n name=\"chevron-down\"\n [size]=\"16\"\n className=\"shrink-0 text-muted-foreground\"\n ></pdm-icon>\n </button>\n\n <div\n *ngIf=\"open\"\n #panelEl\n role=\"listbox\"\n [attr.aria-labelledby]=\"id || null\"\n [ngClass]=\"panelClasses\"\n [style.max-height.px]=\"panelMaxHeightPx\"\n >\n <button\n *ngFor=\"let option of options\"\n type=\"button\"\n role=\"option\"\n [attr.aria-selected]=\"option.value === value\"\n [disabled]=\"option.disabled\"\n (click)=\"selectOption(option)\"\n [ngClass]=\"[\n 'flex w-full appearance-none items-center justify-between rounded-sm border-0 bg-transparent px-2 py-1.5 text-left text-sm outline-none transition-colors',\n option.disabled\n ? 'cursor-not-allowed opacity-50'\n : 'hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground',\n option.value === value ? 'text-foreground' : '',\n ]\"\n >\n <span class=\"min-w-0 flex-1 truncate leading-5\">{{ option.label }}</span>\n <span\n *ngIf=\"option.value === value\"\n class=\"ml-2 flex shrink-0 items-center justify-end\"\n >\n <pdm-icon\n name=\"check\"\n [size]=\"16\"\n className=\"shrink-0 text-current\"\n ></pdm-icon>\n </span>\n </button>\n </div>\n\n <select\n class=\"sr-only\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n [value]=\"value\"\n (change)=\"onChange($event)\"\n >\n <option\n *ngFor=\"let option of options\"\n [value]=\"option.value\"\n [disabled]=\"option.disabled\"\n >\n {{ option.label }}\n </option>\n </select>\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: "component", type: PdmIconComponent, selector: "pdm-icon", inputs: ["name", "library", "assetUrl", "size", "strokeWidth", "className", "ariaLabel", "decorative"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3188
3281
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmSelectComponent, decorators: [{
3189
3282
  type: Component,
3190
- args: [{ selector: 'pdm-select', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"['relative', className || 'w-full']\">\n <button\n type=\"button\"\n [id]=\"id\"\n [disabled]=\"disabled\"\n [attr.aria-invalid]=\"invalid\"\n [attr.aria-expanded]=\"open\"\n [attr.data-state]=\"open ? 'open' : 'closed'\"\n aria-haspopup=\"listbox\"\n (click)=\"toggle()\"\n [ngClass]=\"[\n 'border-input focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/50 aria-invalid:ring-2 aria-invalid:ring-destructive aria-invalid:border-destructive flex h-9 w-full appearance-none items-center justify-between rounded-md border bg-background px-3 py-2 text-sm shadow-sm outline-none disabled:cursor-not-allowed disabled:opacity-50',\n ]\"\n >\n <span\n [ngClass]=\"[\n 'min-w-0 flex-1 truncate text-left leading-5',\n selectedOption\n ? 'font-medium text-foreground'\n : 'font-normal text-muted-foreground',\n ]\"\n >\n {{ selectedLabel }}\n </span>\n <pdm-icon\n name=\"chevron-down\"\n [size]=\"16\"\n className=\"shrink-0 text-muted-foreground\"\n ></pdm-icon>\n </button>\n\n <div\n *ngIf=\"open\"\n role=\"listbox\"\n [attr.aria-labelledby]=\"id || null\"\n class=\"absolute left-0 top-[calc(100%+4px)] z-50 max-h-96 w-full overflow-y-auto rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md\"\n >\n <button\n *ngFor=\"let option of options\"\n type=\"button\"\n role=\"option\"\n [attr.aria-selected]=\"option.value === value\"\n [disabled]=\"option.disabled\"\n (click)=\"selectOption(option)\"\n [ngClass]=\"[\n 'flex w-full appearance-none items-center justify-between rounded-sm border-0 bg-transparent px-2 py-1.5 text-left text-sm outline-none transition-colors',\n option.disabled\n ? 'cursor-not-allowed opacity-50'\n : 'hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground',\n option.value === value ? 'text-foreground' : '',\n ]\"\n >\n <span class=\"min-w-0 flex-1 truncate leading-5\">{{ option.label }}</span>\n <span\n *ngIf=\"option.value === value\"\n class=\"ml-2 flex shrink-0 items-center justify-end\"\n >\n <pdm-icon\n name=\"check\"\n [size]=\"16\"\n className=\"shrink-0 text-current\"\n ></pdm-icon>\n </span>\n </button>\n </div>\n\n <select\n class=\"sr-only\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n [value]=\"value\"\n (change)=\"onChange($event)\"\n >\n <option\n *ngFor=\"let option of options\"\n [value]=\"option.value\"\n [disabled]=\"option.disabled\"\n >\n {{ option.label }}\n </option>\n </select>\n</div>\n" }]
3191
- }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { id: [{
3283
+ args: [{ selector: 'pdm-select', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"['relative', className || 'w-full']\">\n <button\n #triggerEl\n type=\"button\"\n [id]=\"id\"\n [disabled]=\"disabled\"\n [attr.aria-invalid]=\"invalid\"\n [attr.aria-expanded]=\"open\"\n [attr.data-state]=\"open ? 'open' : 'closed'\"\n aria-haspopup=\"listbox\"\n (click)=\"toggle()\"\n [ngClass]=\"[\n 'border-input focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/50 aria-invalid:ring-2 aria-invalid:ring-destructive aria-invalid:border-destructive flex h-9 w-full appearance-none items-center justify-between rounded-md border bg-background px-3 py-2 text-sm shadow-sm outline-none disabled:cursor-not-allowed disabled:opacity-50',\n ]\"\n >\n <span\n [ngClass]=\"[\n 'min-w-0 flex-1 truncate text-left leading-5',\n selectedOption\n ? 'font-medium text-foreground'\n : 'font-normal text-muted-foreground',\n ]\"\n >\n {{ selectedLabel }}\n </span>\n <pdm-icon\n name=\"chevron-down\"\n [size]=\"16\"\n className=\"shrink-0 text-muted-foreground\"\n ></pdm-icon>\n </button>\n\n <div\n *ngIf=\"open\"\n #panelEl\n role=\"listbox\"\n [attr.aria-labelledby]=\"id || null\"\n [ngClass]=\"panelClasses\"\n [style.max-height.px]=\"panelMaxHeightPx\"\n >\n <button\n *ngFor=\"let option of options\"\n type=\"button\"\n role=\"option\"\n [attr.aria-selected]=\"option.value === value\"\n [disabled]=\"option.disabled\"\n (click)=\"selectOption(option)\"\n [ngClass]=\"[\n 'flex w-full appearance-none items-center justify-between rounded-sm border-0 bg-transparent px-2 py-1.5 text-left text-sm outline-none transition-colors',\n option.disabled\n ? 'cursor-not-allowed opacity-50'\n : 'hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground',\n option.value === value ? 'text-foreground' : '',\n ]\"\n >\n <span class=\"min-w-0 flex-1 truncate leading-5\">{{ option.label }}</span>\n <span\n *ngIf=\"option.value === value\"\n class=\"ml-2 flex shrink-0 items-center justify-end\"\n >\n <pdm-icon\n name=\"check\"\n [size]=\"16\"\n className=\"shrink-0 text-current\"\n ></pdm-icon>\n </span>\n </button>\n </div>\n\n <select\n class=\"sr-only\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n [value]=\"value\"\n (change)=\"onChange($event)\"\n >\n <option\n *ngFor=\"let option of options\"\n [value]=\"option.value\"\n [disabled]=\"option.disabled\"\n >\n {{ option.label }}\n </option>\n </select>\n</div>\n" }]
3284
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { id: [{
3192
3285
  type: Input
3193
3286
  }], value: [{
3194
3287
  type: Input
@@ -3204,12 +3297,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
3204
3297
  type: Input
3205
3298
  }], valueChange: [{
3206
3299
  type: Output
3300
+ }], triggerRef: [{
3301
+ type: ViewChild,
3302
+ args: ['triggerEl']
3303
+ }], panelRef: [{
3304
+ type: ViewChild,
3305
+ args: ['panelEl']
3207
3306
  }], onDocumentClick: [{
3208
3307
  type: HostListener,
3209
3308
  args: ['document:click', ['$event']]
3210
3309
  }], onEscape: [{
3211
3310
  type: HostListener,
3212
3311
  args: ['document:keydown.escape']
3312
+ }], onViewportChange: [{
3313
+ type: HostListener,
3314
+ args: ['window:resize']
3315
+ }, {
3316
+ type: HostListener,
3317
+ args: ['window:scroll']
3213
3318
  }] } });
3214
3319
 
3215
3320
  class PdmPaginationComponent {
@@ -3280,14 +3385,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
3280
3385
  }] } });
3281
3386
 
3282
3387
  class PdmPopoverComponent {
3283
- constructor(elementRef) {
3388
+ constructor(elementRef, cdr) {
3284
3389
  this.elementRef = elementRef;
3285
- this.open = false;
3390
+ this.cdr = cdr;
3391
+ this._open = false;
3286
3392
  this.triggerText = 'Open';
3287
3393
  this.className = '';
3288
3394
  this.panelClassName = '';
3289
3395
  this.showTrigger = true;
3290
3396
  this.openChange = new EventEmitter();
3397
+ this.panelPlacement = 'bottom';
3398
+ }
3399
+ set open(value) {
3400
+ this._open = !!value;
3401
+ if (this._open) {
3402
+ this.schedulePanelPlacementUpdate();
3403
+ }
3404
+ else {
3405
+ this.panelPlacement = 'bottom';
3406
+ }
3407
+ this.cdr.markForCheck();
3408
+ }
3409
+ get open() {
3410
+ return this._open;
3411
+ }
3412
+ get panelClasses() {
3413
+ return [
3414
+ this.panelPlacement === 'top'
3415
+ ? 'absolute bottom-full left-0 z-30 mb-2 min-w-80 rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md'
3416
+ : 'absolute left-0 top-full z-30 mt-2 min-w-80 rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md',
3417
+ this.panelClassName
3418
+ ];
3291
3419
  }
3292
3420
  toggle() {
3293
3421
  this.open = !this.open;
@@ -3308,15 +3436,39 @@ class PdmPopoverComponent {
3308
3436
  this.openChange.emit(false);
3309
3437
  }
3310
3438
  }
3439
+ onViewportChange() {
3440
+ this.updatePanelPlacement();
3441
+ }
3442
+ schedulePanelPlacementUpdate() {
3443
+ setTimeout(() => this.updatePanelPlacement());
3444
+ }
3445
+ updatePanelPlacement() {
3446
+ if (!this.open)
3447
+ return;
3448
+ const anchorEl = this.triggerRef?.nativeElement || this.anchorRef?.nativeElement;
3449
+ const panelEl = this.panelRef?.nativeElement;
3450
+ if (!anchorEl || !panelEl || typeof window === 'undefined') {
3451
+ return;
3452
+ }
3453
+ const viewportHeight = window.innerHeight;
3454
+ const gap = 8;
3455
+ const anchorRect = anchorEl.getBoundingClientRect();
3456
+ const panelHeight = panelEl.offsetHeight;
3457
+ const spaceBelow = Math.max(0, viewportHeight - anchorRect.bottom - gap);
3458
+ const spaceAbove = Math.max(0, anchorRect.top - gap);
3459
+ const nextPlacement = spaceBelow < panelHeight && spaceAbove > spaceBelow ? 'top' : 'bottom';
3460
+ if (this.panelPlacement !== nextPlacement) {
3461
+ this.panelPlacement = nextPlacement;
3462
+ this.cdr.markForCheck();
3463
+ }
3464
+ }
3311
3465
  }
3312
- PdmPopoverComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmPopoverComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
3313
- PdmPopoverComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmPopoverComponent, selector: "pdm-popover", inputs: { open: "open", triggerText: "triggerText", className: "className", panelClassName: "panelClassName", showTrigger: "showTrigger" }, outputs: { openChange: "openChange" }, host: { listeners: { "document:keydown.escape": "onEsc()", "document:click": "onDocumentClick($event)" } }, ngImport: i0, template: "<div class=\"relative inline-block\" [ngClass]=\"className\">\n <button *ngIf=\"showTrigger\" type=\"button\" class=\"inline-flex h-9 appearance-none items-center justify-center rounded-md border border-input bg-background px-3 text-sm font-medium text-foreground shadow-sm\" [attr.aria-expanded]=\"open\" (click)=\"toggle()\">{{ triggerText }}</button>\n <div *ngIf=\"open || !showTrigger\" [ngClass]=\"['absolute left-0 top-full z-30 mt-2 min-w-80 rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md', panelClassName]\">\n <ng-content></ng-content>\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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3466
+ PdmPopoverComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmPopoverComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3467
+ PdmPopoverComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmPopoverComponent, selector: "pdm-popover", inputs: { triggerText: "triggerText", className: "className", panelClassName: "panelClassName", showTrigger: "showTrigger", open: "open" }, outputs: { openChange: "openChange" }, host: { listeners: { "document:keydown.escape": "onEsc()", "document:click": "onDocumentClick($event)", "window:resize": "onViewportChange()", "window:scroll": "onViewportChange()" } }, viewQueries: [{ propertyName: "anchorRef", first: true, predicate: ["anchorEl"], descendants: true }, { propertyName: "triggerRef", first: true, predicate: ["triggerEl"], descendants: true }, { propertyName: "panelRef", first: true, predicate: ["panelEl"], descendants: true }], ngImport: i0, template: "<div #anchorEl class=\"relative inline-block\" [ngClass]=\"className\">\n <button #triggerEl *ngIf=\"showTrigger\" type=\"button\" class=\"inline-flex h-9 appearance-none items-center justify-center rounded-md border border-input bg-background px-3 text-sm font-medium text-foreground shadow-sm\" [attr.aria-expanded]=\"open\" (click)=\"toggle()\">{{ triggerText }}</button>\n <div #panelEl *ngIf=\"open || !showTrigger\" [ngClass]=\"panelClasses\">\n <ng-content></ng-content>\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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
3314
3468
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmPopoverComponent, decorators: [{
3315
3469
  type: Component,
3316
- args: [{ selector: 'pdm-popover', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"relative inline-block\" [ngClass]=\"className\">\n <button *ngIf=\"showTrigger\" type=\"button\" class=\"inline-flex h-9 appearance-none items-center justify-center rounded-md border border-input bg-background px-3 text-sm font-medium text-foreground shadow-sm\" [attr.aria-expanded]=\"open\" (click)=\"toggle()\">{{ triggerText }}</button>\n <div *ngIf=\"open || !showTrigger\" [ngClass]=\"['absolute left-0 top-full z-30 mt-2 min-w-80 rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md', panelClassName]\">\n <ng-content></ng-content>\n </div>\n</div>\n" }]
3317
- }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { open: [{
3318
- type: Input
3319
- }], triggerText: [{
3470
+ args: [{ selector: 'pdm-popover', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div #anchorEl class=\"relative inline-block\" [ngClass]=\"className\">\n <button #triggerEl *ngIf=\"showTrigger\" type=\"button\" class=\"inline-flex h-9 appearance-none items-center justify-center rounded-md border border-input bg-background px-3 text-sm font-medium text-foreground shadow-sm\" [attr.aria-expanded]=\"open\" (click)=\"toggle()\">{{ triggerText }}</button>\n <div #panelEl *ngIf=\"open || !showTrigger\" [ngClass]=\"panelClasses\">\n <ng-content></ng-content>\n </div>\n</div>\n" }]
3471
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { triggerText: [{
3320
3472
  type: Input
3321
3473
  }], className: [{
3322
3474
  type: Input
@@ -3326,12 +3478,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
3326
3478
  type: Input
3327
3479
  }], openChange: [{
3328
3480
  type: Output
3481
+ }], anchorRef: [{
3482
+ type: ViewChild,
3483
+ args: ['anchorEl']
3484
+ }], triggerRef: [{
3485
+ type: ViewChild,
3486
+ args: ['triggerEl']
3487
+ }], panelRef: [{
3488
+ type: ViewChild,
3489
+ args: ['panelEl']
3490
+ }], open: [{
3491
+ type: Input
3329
3492
  }], onEsc: [{
3330
3493
  type: HostListener,
3331
3494
  args: ['document:keydown.escape']
3332
3495
  }], onDocumentClick: [{
3333
3496
  type: HostListener,
3334
3497
  args: ['document:click', ['$event']]
3498
+ }], onViewportChange: [{
3499
+ type: HostListener,
3500
+ args: ['window:resize']
3501
+ }, {
3502
+ type: HostListener,
3503
+ args: ['window:scroll']
3335
3504
  }] } });
3336
3505
 
3337
3506
  class PdmProgressComponent {