pdm-ui-kit 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +168 -3
  2. package/esm2020/lib/components/button-group/button-group.component.mjs +211 -182
  3. package/esm2020/lib/components/combobox/combobox.component.mjs +136 -14
  4. package/esm2020/lib/components/context-menu/context-menu.component.mjs +121 -42
  5. package/esm2020/lib/components/data-table/data-table.component.mjs +3 -3
  6. package/esm2020/lib/components/date-picker/date-picker.component.mjs +66 -54
  7. package/esm2020/lib/components/dialog/dialog.component.mjs +111 -94
  8. package/esm2020/lib/components/hover-card/hover-card.component.mjs +185 -24
  9. package/esm2020/lib/components/input/input.component.mjs +15 -15
  10. package/esm2020/lib/components/input-group/input-group.component.mjs +14 -14
  11. package/esm2020/lib/components/menubar/menubar.component.mjs +105 -29
  12. package/esm2020/lib/components/popover/popover.component.mjs +107 -75
  13. package/esm2020/lib/components/select/select.component.mjs +23 -22
  14. package/esm2020/lib/components/table/table.component.mjs +77 -68
  15. package/esm2020/lib/components/tabs/tabs.component.mjs +6 -6
  16. package/esm2020/lib/components/toggle-group/toggle-group.component.mjs +6 -6
  17. package/esm2020/lib/components/tooltip/tooltip.component.mjs +162 -19
  18. package/esm2020/lib/overlay/z-index-helper.mjs +69 -0
  19. package/esm2020/lib/utils/z-index.mjs +25 -28
  20. package/esm2020/public-api.mjs +67 -66
  21. package/fesm2015/pdm-ui-kit.mjs +1379 -654
  22. package/fesm2015/pdm-ui-kit.mjs.map +1 -1
  23. package/fesm2020/pdm-ui-kit.mjs +1383 -654
  24. package/fesm2020/pdm-ui-kit.mjs.map +1 -1
  25. package/lib/components/button-group/button-group.component.d.ts +8 -2
  26. package/lib/components/combobox/combobox.component.d.ts +20 -3
  27. package/lib/components/context-menu/context-menu.component.d.ts +17 -8
  28. package/lib/components/date-picker/date-picker.component.d.ts +5 -6
  29. package/lib/components/dialog/dialog.component.d.ts +5 -5
  30. package/lib/components/hover-card/hover-card.component.d.ts +27 -4
  31. package/lib/components/input/input.component.d.ts +3 -3
  32. package/lib/components/input-group/input-group.component.d.ts +1 -1
  33. package/lib/components/menubar/menubar.component.d.ts +16 -8
  34. package/lib/components/popover/popover.component.d.ts +13 -12
  35. package/lib/components/select/select.component.d.ts +4 -5
  36. package/lib/components/table/table.component.d.ts +2 -2
  37. package/lib/components/tabs/tabs.component.d.ts +1 -1
  38. package/lib/components/toggle-group/toggle-group.component.d.ts +1 -1
  39. package/lib/components/tooltip/tooltip.component.d.ts +21 -3
  40. package/lib/overlay/z-index-helper.d.ts +36 -0
  41. package/lib/utils/z-index.d.ts +14 -18
  42. package/package.json +6 -6
  43. package/public-api.d.ts +66 -65
  44. package/src/lib/styles/tokens.css +182 -0
@@ -2,11 +2,11 @@ import * as i1 from '@angular/common';
2
2
  import { isPlatformBrowser, DOCUMENT, CommonModule } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
4
  import { EventEmitter, Component, ChangeDetectionStrategy, Input, Output, HostListener, ViewChild, ViewChildren, ElementRef, PLATFORM_ID, Directive, Inject, ContentChildren, NgModule } from '@angular/core';
5
- import * as i1$2 from '@angular/cdk/overlay';
5
+ import * as i1$1 from '@angular/cdk/overlay';
6
6
  import { OverlayModule } from '@angular/cdk/overlay';
7
- import { icons } from 'lucide';
8
- import * as i1$1 from '@angular/platform-browser';
9
7
  import { TemplatePortal } from '@angular/cdk/portal';
8
+ import { icons } from 'lucide';
9
+ import * as i1$2 from '@angular/platform-browser';
10
10
  import { format } from 'date-fns';
11
11
 
12
12
  class PdmAccordionComponent {
@@ -315,199 +315,228 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
315
315
  type: Input
316
316
  }] } });
317
317
 
318
+ const ROOT_LAYOUT = {
319
+ horizontal: "w-full flex flex-row items-center overflow-x-auto",
320
+ vertical: "flex flex-col items-stretch",
321
+ };
322
+ const ATTACHMENT_EDGE_CLASSES = {
323
+ horizontal: [
324
+ "[&>*]:rounded-none",
325
+ "[&>*:first-child]:rounded-l-md",
326
+ "[&>*:last-child]:rounded-r-md",
327
+ "[&>*:not(:first-child)]:border-l-0",
328
+ "[&>*:not(:first-child)]:-ml-px",
329
+ ],
330
+ vertical: [
331
+ "[&>*]:rounded-none",
332
+ "[&>*:first-child]:rounded-t-md",
333
+ "[&>*:last-child]:rounded-b-md",
334
+ "[&>*:not(:first-child)]:border-t-0",
335
+ "[&>*:not(:first-child)]:-mt-px",
336
+ ],
337
+ };
338
+ const ATTACHMENT_CONTROL_CLASSES = {
339
+ horizontal: [
340
+ "[&>pdm-button]:flex",
341
+ "[&>pdm-button>button]:h-9",
342
+ "[&>pdm-button>button]:!rounded-none",
343
+ "[&>pdm-button>button]:shadow-none",
344
+ "[&>pdm-button:first-child>button]:!rounded-l-md",
345
+ "[&>pdm-button:last-child>button]:!rounded-r-md",
346
+ "[&>pdm-input]:flex-1",
347
+ "[&>pdm-input]:min-w-0",
348
+ "[&>pdm-input>div]:w-full",
349
+ "[&>pdm-input>div]:min-w-0",
350
+ "[&>pdm-input>div]:!rounded-none",
351
+ "[&>pdm-input>div]:shadow-none",
352
+ "[&>pdm-input>div>input]:!rounded-none",
353
+ "[&>pdm-input>div>input]:bg-background",
354
+ "[&>pdm-input>div>input]:shadow-none",
355
+ "[&>pdm-input:first-child>div]:!rounded-l-md",
356
+ "[&>pdm-input:last-child>div]:!rounded-r-md",
357
+ "[&>pdm-input:first-child>div>input]:!rounded-l-md",
358
+ "[&>pdm-input:last-child>div>input]:!rounded-r-md",
359
+ "[&>pdm-input-group]:min-w-0",
360
+ "[&>pdm-input-group>div]:!rounded-none",
361
+ "[&>pdm-input-group>div]:shadow-none",
362
+ "[&>pdm-input-group:first-child>div]:!rounded-l-md",
363
+ "[&>pdm-input-group:last-child>div]:!rounded-r-md",
364
+ "[&>pdm-select>select]:!rounded-none",
365
+ "[&>pdm-select>select]:shadow-none",
366
+ "[&>pdm-select>div>button]:!rounded-none",
367
+ "[&>pdm-select>div>button]:shadow-none",
368
+ "[&>pdm-select:first-child>select]:!rounded-l-md",
369
+ "[&>pdm-select:last-child>select]:!rounded-r-md",
370
+ "[&>pdm-select:first-child>div>button]:!rounded-l-md",
371
+ "[&>pdm-select:last-child>div>button]:!rounded-r-md",
372
+ "[&>pdm-select:not(:first-child)>div>button]:!rounded-l-none",
373
+ "[&>pdm-select:not(:last-child)>div>button]:!rounded-r-none",
374
+ "[&>pdm-tooltip>span>*]:rounded-none",
375
+ "[&>pdm-tooltip>span>*]:shadow-none",
376
+ "[&>pdm-tooltip:not(:first-child)>span>*]:border-l-0",
377
+ "[&>pdm-tooltip>span>button]:!rounded-none",
378
+ "[&>pdm-tooltip>span>button]:shadow-none",
379
+ "[&>pdm-tooltip:first-child>span>button]:!rounded-l-md",
380
+ "[&>pdm-tooltip:last-child>span>button]:!rounded-r-md",
381
+ "[&>pdm-tooltip>span>input]:!rounded-none",
382
+ "[&>pdm-tooltip>span>input]:bg-background",
383
+ "[&>pdm-tooltip>span>input]:shadow-none",
384
+ "[&>pdm-tooltip:first-child>span>input]:!rounded-l-md",
385
+ "[&>pdm-tooltip:last-child>span>input]:!rounded-r-md",
386
+ "[&>pdm-tooltip>span>select]:!rounded-none",
387
+ "[&>pdm-tooltip>span>select]:shadow-none",
388
+ "[&>pdm-tooltip:first-child>span>select]:!rounded-l-md",
389
+ "[&>pdm-tooltip:last-child>span>select]:!rounded-r-md",
390
+ "[&>pdm-tooltip>span>pdm-button>button]:!rounded-none",
391
+ "[&>pdm-tooltip>span>pdm-button>button]:shadow-none",
392
+ "[&>pdm-tooltip:first-child>span>pdm-button>button]:!rounded-l-md",
393
+ "[&>pdm-tooltip:last-child>span>pdm-button>button]:!rounded-r-md",
394
+ "[&>pdm-tooltip>span>pdm-input>div]:!rounded-none",
395
+ "[&>pdm-tooltip>span>pdm-input>div]:shadow-none",
396
+ "[&>pdm-tooltip>span>pdm-input>div>input]:!rounded-none",
397
+ "[&>pdm-tooltip>span>pdm-input>div>input]:bg-background",
398
+ "[&>pdm-tooltip>span>pdm-input>div>input]:shadow-none",
399
+ "[&>pdm-tooltip:first-child>span>pdm-input>div]:!rounded-l-md",
400
+ "[&>pdm-tooltip:last-child>span>pdm-input>div]:!rounded-r-md",
401
+ "[&>pdm-tooltip:first-child>span>pdm-input>div>input]:!rounded-l-md",
402
+ "[&>pdm-tooltip:last-child>span>pdm-input>div>input]:!rounded-r-md",
403
+ "[&>pdm-tooltip>span>pdm-input-group>div]:!rounded-none",
404
+ "[&>pdm-tooltip>span>pdm-input-group>div]:shadow-none",
405
+ "[&>pdm-tooltip:first-child>span>pdm-input-group>div]:!rounded-l-md",
406
+ "[&>pdm-tooltip:last-child>span>pdm-input-group>div]:!rounded-r-md",
407
+ "[&>pdm-tooltip>span>pdm-select>select]:!rounded-none",
408
+ "[&>pdm-tooltip>span>pdm-select>select]:shadow-none",
409
+ "[&>pdm-tooltip>span>pdm-select>div>button]:!rounded-none",
410
+ "[&>pdm-tooltip>span>pdm-select>div>button]:shadow-none",
411
+ "[&>pdm-tooltip:first-child>span>pdm-select>select]:!rounded-l-md",
412
+ "[&>pdm-tooltip:last-child>span>pdm-select>select]:!rounded-r-md",
413
+ "[&>pdm-tooltip:first-child>span>pdm-select>div>button]:!rounded-l-md",
414
+ "[&>pdm-tooltip:last-child>span>pdm-select>div>button]:!rounded-r-md",
415
+ "[&>pdm-tooltip:not(:first-child)>span>pdm-select>div>button]:!rounded-l-none",
416
+ "[&>pdm-tooltip:not(:last-child)>span>pdm-select>div>button]:!rounded-r-none",
417
+ ],
418
+ vertical: [
419
+ "[&>*]:rounded-none",
420
+ "[&>*:first-child]:rounded-t-md",
421
+ "[&>*:last-child]:rounded-b-md",
422
+ "[&>*:not(:first-child)]:border-t-0",
423
+ "[&>*:not(:first-child)]:-mt-px",
424
+ "[&>pdm-button]:flex",
425
+ "[&>pdm-button>button]:h-9",
426
+ "[&>pdm-button>button]:!rounded-none",
427
+ "[&>pdm-button>button]:shadow-none",
428
+ "[&>pdm-button:first-child>button]:!rounded-t-md",
429
+ "[&>pdm-button:last-child>button]:!rounded-b-md",
430
+ "[&>pdm-input>div]:!rounded-none",
431
+ "[&>pdm-input>div]:shadow-none",
432
+ "[&>pdm-input>div>input]:!rounded-none",
433
+ "[&>pdm-input>div>input]:bg-background",
434
+ "[&>pdm-input>div>input]:shadow-none",
435
+ "[&>pdm-input:first-child>div]:!rounded-t-md",
436
+ "[&>pdm-input:last-child>div]:!rounded-b-md",
437
+ "[&>pdm-input:first-child>div>input]:!rounded-t-md",
438
+ "[&>pdm-input:last-child>div>input]:!rounded-b-md",
439
+ "[&>pdm-input-group>div]:!rounded-none",
440
+ "[&>pdm-input-group>div]:shadow-none",
441
+ "[&>pdm-input-group:first-child>div]:!rounded-t-md",
442
+ "[&>pdm-input-group:last-child>div]:!rounded-b-md",
443
+ "[&>pdm-select>select]:!rounded-none",
444
+ "[&>pdm-select>select]:shadow-none",
445
+ "[&>pdm-select>div>button]:!rounded-none",
446
+ "[&>pdm-select>div>button]:shadow-none",
447
+ "[&>pdm-select:first-child>select]:!rounded-t-md",
448
+ "[&>pdm-select:last-child>select]:!rounded-b-md",
449
+ "[&>pdm-select:first-child>div>button]:!rounded-t-md",
450
+ "[&>pdm-select:last-child>div>button]:!rounded-b-md",
451
+ "[&>pdm-select:not(:first-child)>div>button]:!rounded-t-none",
452
+ "[&>pdm-select:not(:last-child)>div>button]:!rounded-b-none",
453
+ "[&>pdm-tooltip>span>*]:rounded-none",
454
+ "[&>pdm-tooltip>span>*]:shadow-none",
455
+ "[&>pdm-tooltip:not(:first-child)>span>*]:border-t-0",
456
+ "[&>pdm-tooltip>span>button]:!rounded-none",
457
+ "[&>pdm-tooltip>span>button]:shadow-none",
458
+ "[&>pdm-tooltip:first-child>span>button]:!rounded-t-md",
459
+ "[&>pdm-tooltip:last-child>span>button]:!rounded-b-md",
460
+ "[&>pdm-tooltip>span>input]:!rounded-none",
461
+ "[&>pdm-tooltip>span>input]:bg-background",
462
+ "[&>pdm-tooltip>span>input]:shadow-none",
463
+ "[&>pdm-tooltip:first-child>span>input]:!rounded-t-md",
464
+ "[&>pdm-tooltip:last-child>span>input]:!rounded-b-md",
465
+ "[&>pdm-tooltip>span>select]:!rounded-none",
466
+ "[&>pdm-tooltip>span>select]:shadow-none",
467
+ "[&>pdm-tooltip:first-child>span>select]:!rounded-t-md",
468
+ "[&>pdm-tooltip:last-child>span>select]:!rounded-b-md",
469
+ "[&>pdm-tooltip>span>pdm-button>button]:!rounded-none",
470
+ "[&>pdm-tooltip>span>pdm-button>button]:shadow-none",
471
+ "[&>pdm-tooltip:first-child>span>pdm-button>button]:!rounded-t-md",
472
+ "[&>pdm-tooltip:last-child>span>pdm-button>button]:!rounded-b-md",
473
+ "[&>pdm-tooltip>span>pdm-input>div]:!rounded-none",
474
+ "[&>pdm-tooltip>span>pdm-input>div]:shadow-none",
475
+ "[&>pdm-tooltip>span>pdm-input>div>input]:!rounded-none",
476
+ "[&>pdm-tooltip>span>pdm-input>div>input]:bg-background",
477
+ "[&>pdm-tooltip>span>pdm-input>div>input]:shadow-none",
478
+ "[&>pdm-tooltip:first-child>span>pdm-input>div]:!rounded-t-md",
479
+ "[&>pdm-tooltip:last-child>span>pdm-input>div]:!rounded-b-md",
480
+ "[&>pdm-tooltip:first-child>span>pdm-input>div>input]:!rounded-t-md",
481
+ "[&>pdm-tooltip:last-child>span>pdm-input>div>input]:!rounded-b-md",
482
+ "[&>pdm-tooltip>span>pdm-input-group>div]:!rounded-none",
483
+ "[&>pdm-tooltip>span>pdm-input-group>div]:shadow-none",
484
+ "[&>pdm-tooltip:first-child>span>pdm-input-group>div]:!rounded-t-md",
485
+ "[&>pdm-tooltip:last-child>span>pdm-input-group>div]:!rounded-b-md",
486
+ "[&>pdm-tooltip>span>pdm-select>select]:!rounded-none",
487
+ "[&>pdm-tooltip>span>pdm-select>select]:shadow-none",
488
+ "[&>pdm-tooltip>span>pdm-select>div>button]:!rounded-none",
489
+ "[&>pdm-tooltip>span>pdm-select>div>button]:shadow-none",
490
+ "[&>pdm-tooltip:first-child>span>pdm-select>select]:!rounded-t-md",
491
+ "[&>pdm-tooltip:last-child>span>pdm-select>select]:!rounded-b-md",
492
+ "[&>pdm-tooltip:first-child>span>pdm-select>div>button]:!rounded-t-md",
493
+ "[&>pdm-tooltip:last-child>span>pdm-select>div>button]:!rounded-b-md",
494
+ "[&>pdm-tooltip:not(:first-child)>span>pdm-select>div>button]:!rounded-t-none",
495
+ "[&>pdm-tooltip:not(:last-child)>span>pdm-select>div>button]:!rounded-b-none",
496
+ ],
497
+ };
498
+ const FOCUS_STACKING_CLASS = "*:focus-visible:relative *:focus-visible:z-10";
499
+ const SEPARATOR_CLASSES = "overflow-hidden rounded-md border border-border bg-secondary shadow-sm";
318
500
  class PdmButtonGroupComponent {
319
501
  constructor() {
320
- this.variant = 'default';
502
+ this.variant = "default";
321
503
  this.separated = true;
322
- this.className = '';
504
+ this.className = "";
323
505
  }
324
- get rootClasses() {
506
+ get axis() {
325
507
  var _a, _b;
326
- const effectiveOrientation = (_b = (_a = this.orientation) !== null && _a !== void 0 ? _a : this.direction) !== null && _b !== void 0 ? _b : 'horizontal';
327
- const isVertical = this.variant === 'orientation' || effectiveOrientation === 'vertical';
328
- const isGroup = this.variant === 'group';
329
- const isAttached = !this.separated && this.variant !== 'default';
330
- const isSeparator = this.variant === 'separator';
331
- const attachedClasses = isAttached && !isGroup
332
- ? isVertical
333
- ? [
334
- '[&>*]:rounded-none',
335
- '[&>*:first-child]:rounded-t-md',
336
- '[&>*:last-child]:rounded-b-md',
337
- '[&>*:not(:first-child)]:border-t-0',
338
- '[&>*:not(:first-child)]:-mt-px'
339
- ].join(' ')
340
- : [
341
- '[&>*]:rounded-none',
342
- '[&>*:first-child]:rounded-l-md',
343
- '[&>*:last-child]:rounded-r-md',
344
- '[&>*:not(:first-child)]:border-l-0',
345
- '[&>*:not(:first-child)]:-ml-px'
346
- ].join(' ')
347
- : '';
348
- const groupHorizontalClasses = isGroup && !isVertical && !this.separated
349
- ? [
350
- '[&>*]:rounded-none',
351
- '[&>*:first-child]:rounded-l-md',
352
- '[&>*:last-child]:rounded-r-md',
353
- '[&>*:not(:first-child)]:-ml-px',
354
- '[&>*:not(:first-child)]:border-l-0',
355
- '[&>pdm-button]:flex',
356
- '[&>pdm-button>button]:h-9',
357
- '[&>pdm-input]:flex-1',
358
- '[&>pdm-input>div]:w-full',
359
- '[&>pdm-select>select]:!rounded-none',
360
- '[&>pdm-select:first-child>select]:!rounded-l-md',
361
- '[&>pdm-select:last-child>select]:!rounded-r-md',
362
- '[&>pdm-select>select]:shadow-none',
363
- '[&>pdm-select>div>button]:!rounded-none',
364
- '[&>pdm-select:first-child>div>button]:!rounded-l-md',
365
- '[&>pdm-select:last-child>div>button]:!rounded-r-md',
366
- '[&>pdm-select:not(:first-child)>div>button]:!rounded-l-none',
367
- '[&>pdm-select:not(:last-child)>div>button]:!rounded-r-none',
368
- '[&>pdm-select>div>button]:shadow-none',
369
- '[&>pdm-button>button]:!rounded-none',
370
- '[&>pdm-button:first-child>button]:!rounded-l-md',
371
- '[&>pdm-button:last-child>button]:!rounded-r-md',
372
- '[&>pdm-input>div>input]:!rounded-none',
373
- '[&>pdm-input:first-child>div>input]:!rounded-l-md',
374
- '[&>pdm-input:last-child>div>input]:!rounded-r-md',
375
- '[&>pdm-input-group>div]:!rounded-none',
376
- '[&>pdm-input-group:first-child>div]:!rounded-l-md',
377
- '[&>pdm-input-group:last-child>div]:!rounded-r-md',
378
- '[&>pdm-input>div>input]:bg-background',
379
- '[&>pdm-input>div>input]:shadow-none',
380
- '[&>pdm-button>button]:rounded-l-none',
381
- '[&>pdm-button>button]:shadow-none',
382
- '[&>pdm-tooltip>span>*]:rounded-none',
383
- '[&>pdm-tooltip:first-child>span>*]:rounded-l-md',
384
- '[&>pdm-tooltip:last-child>span>*]:rounded-r-md',
385
- '[&>pdm-tooltip:not(:first-child)>span>*]:border-l-0',
386
- '[&>pdm-tooltip>span>pdm-button>button]:!rounded-none',
387
- '[&>pdm-tooltip:first-child>span>pdm-button>button]:!rounded-l-md',
388
- '[&>pdm-tooltip:last-child>span>pdm-button>button]:!rounded-r-md',
389
- '[&>pdm-tooltip>span>pdm-button>button]:shadow-none',
390
- '[&>pdm-tooltip>span>button]:!rounded-none',
391
- '[&>pdm-tooltip:first-child>span>button]:!rounded-l-md',
392
- '[&>pdm-tooltip:last-child>span>button]:!rounded-r-md',
393
- '[&>pdm-tooltip>span>button]:shadow-none',
394
- '[&>pdm-tooltip>span>pdm-input>div>input]:!rounded-none',
395
- '[&>pdm-tooltip:first-child>span>pdm-input>div>input]:!rounded-l-md',
396
- '[&>pdm-tooltip:last-child>span>pdm-input>div>input]:!rounded-r-md',
397
- '[&>pdm-tooltip>span>pdm-input>div>input]:shadow-none',
398
- '[&>pdm-tooltip>span>input]:!rounded-none',
399
- '[&>pdm-tooltip:first-child>span>input]:!rounded-l-md',
400
- '[&>pdm-tooltip:last-child>span>input]:!rounded-r-md',
401
- '[&>pdm-tooltip>span>input]:shadow-none',
402
- '[&>pdm-tooltip>span>pdm-input-group>div]:!rounded-none',
403
- '[&>pdm-tooltip:first-child>span>pdm-input-group>div]:!rounded-l-md',
404
- '[&>pdm-tooltip:last-child>span>pdm-input-group>div]:!rounded-r-md',
405
- '[&>pdm-tooltip>span>pdm-select>select]:!rounded-none',
406
- '[&>pdm-tooltip:first-child>span>pdm-select>select]:!rounded-l-md',
407
- '[&>pdm-tooltip:last-child>span>pdm-select>select]:!rounded-r-md',
408
- '[&>pdm-tooltip>span>pdm-select>select]:shadow-none',
409
- '[&>pdm-tooltip>span>pdm-select>div>button]:!rounded-none',
410
- '[&>pdm-tooltip:first-child>span>pdm-select>div>button]:!rounded-l-md',
411
- '[&>pdm-tooltip:last-child>span>pdm-select>div>button]:!rounded-r-md',
412
- '[&>pdm-tooltip:not(:first-child)>span>pdm-select>div>button]:!rounded-l-none',
413
- '[&>pdm-tooltip:not(:last-child)>span>pdm-select>div>button]:!rounded-r-none',
414
- '[&>pdm-tooltip>span>pdm-select>div>button]:shadow-none',
415
- '[&>pdm-tooltip>span>select]:!rounded-none',
416
- '[&>pdm-tooltip:first-child>span>select]:!rounded-l-md',
417
- '[&>pdm-tooltip:last-child>span>select]:!rounded-r-md',
418
- '[&>pdm-tooltip>span>select]:shadow-none'
419
- ].join(' ')
420
- : '';
421
- const groupVerticalClasses = isGroup && isVertical && !this.separated
422
- ? [
423
- '[&>*]:rounded-none',
424
- '[&>*:first-child]:rounded-t-md',
425
- '[&>*:last-child]:rounded-b-md',
426
- '[&>*:not(:first-child)]:-mt-px',
427
- '[&>*:not(:first-child)]:border-t-0',
428
- '[&>pdm-button]:flex',
429
- '[&>pdm-button>button]:h-9',
430
- '[&>pdm-button>button]:!rounded-none',
431
- '[&>pdm-button:first-child>button]:!rounded-t-md',
432
- '[&>pdm-button:last-child>button]:!rounded-b-md',
433
- '[&>pdm-input>div>input]:!rounded-none',
434
- '[&>pdm-input:first-child>div>input]:!rounded-t-md',
435
- '[&>pdm-input:last-child>div>input]:!rounded-b-md',
436
- '[&>pdm-input-group>div]:!rounded-none',
437
- '[&>pdm-input-group:first-child>div]:!rounded-t-md',
438
- '[&>pdm-input-group:last-child>div]:!rounded-b-md',
439
- '[&>pdm-select>select]:!rounded-none',
440
- '[&>pdm-select:first-child>select]:!rounded-t-md',
441
- '[&>pdm-select:last-child>select]:!rounded-b-md',
442
- '[&>pdm-select>select]:shadow-none',
443
- '[&>pdm-select>div>button]:!rounded-none',
444
- '[&>pdm-select:first-child>div>button]:!rounded-t-md',
445
- '[&>pdm-select:last-child>div>button]:!rounded-b-md',
446
- '[&>pdm-select:not(:first-child)>div>button]:!rounded-t-none',
447
- '[&>pdm-select:not(:last-child)>div>button]:!rounded-b-none',
448
- '[&>pdm-select>div>button]:shadow-none',
449
- '[&>pdm-input>div>input]:bg-background',
450
- '[&>pdm-input>div>input]:shadow-none',
451
- '[&>pdm-button>button]:shadow-none',
452
- '[&>pdm-tooltip>span>*]:rounded-none',
453
- '[&>pdm-tooltip:first-child>span>*]:rounded-t-md',
454
- '[&>pdm-tooltip:last-child>span>*]:rounded-b-md',
455
- '[&>pdm-tooltip:not(:first-child)>span>*]:border-t-0',
456
- '[&>pdm-tooltip>span>pdm-button>button]:!rounded-none',
457
- '[&>pdm-tooltip:first-child>span>pdm-button>button]:!rounded-t-md',
458
- '[&>pdm-tooltip:last-child>span>pdm-button>button]:!rounded-b-md',
459
- '[&>pdm-tooltip>span>pdm-button>button]:shadow-none',
460
- '[&>pdm-tooltip>span>button]:!rounded-none',
461
- '[&>pdm-tooltip:first-child>span>button]:!rounded-t-md',
462
- '[&>pdm-tooltip:last-child>span>button]:!rounded-b-md',
463
- '[&>pdm-tooltip>span>button]:shadow-none',
464
- '[&>pdm-tooltip>span>pdm-input>div>input]:!rounded-none',
465
- '[&>pdm-tooltip:first-child>span>pdm-input>div>input]:!rounded-t-md',
466
- '[&>pdm-tooltip:last-child>span>pdm-input>div>input]:!rounded-b-md',
467
- '[&>pdm-tooltip>span>pdm-input>div>input]:shadow-none',
468
- '[&>pdm-tooltip>span>input]:!rounded-none',
469
- '[&>pdm-tooltip:first-child>span>input]:!rounded-t-md',
470
- '[&>pdm-tooltip:last-child>span>input]:!rounded-b-md',
471
- '[&>pdm-tooltip>span>input]:shadow-none',
472
- '[&>pdm-tooltip>span>pdm-input-group>div]:!rounded-none',
473
- '[&>pdm-tooltip:first-child>span>pdm-input-group>div]:!rounded-t-md',
474
- '[&>pdm-tooltip:last-child>span>pdm-input-group>div]:!rounded-b-md',
475
- '[&>pdm-tooltip>span>pdm-select>select]:!rounded-none',
476
- '[&>pdm-tooltip:first-child>span>pdm-select>select]:!rounded-t-md',
477
- '[&>pdm-tooltip:last-child>span>pdm-select>select]:!rounded-b-md',
478
- '[&>pdm-tooltip>span>pdm-select>select]:shadow-none',
479
- '[&>pdm-tooltip>span>pdm-select>div>button]:!rounded-none',
480
- '[&>pdm-tooltip:first-child>span>pdm-select>div>button]:!rounded-t-md',
481
- '[&>pdm-tooltip:last-child>span>pdm-select>div>button]:!rounded-b-md',
482
- '[&>pdm-tooltip:not(:first-child)>span>pdm-select>div>button]:!rounded-t-none',
483
- '[&>pdm-tooltip:not(:last-child)>span>pdm-select>div>button]:!rounded-b-none',
484
- '[&>pdm-tooltip>span>pdm-select>div>button]:shadow-none',
485
- '[&>pdm-tooltip>span>select]:!rounded-none',
486
- '[&>pdm-tooltip:first-child>span>select]:!rounded-t-md',
487
- '[&>pdm-tooltip:last-child>span>select]:!rounded-b-md',
488
- '[&>pdm-tooltip>span>select]:shadow-none'
489
- ].join(' ')
490
- : '';
508
+ return (_b = (_a = this.orientation) !== null && _a !== void 0 ? _a : this.direction) !== null && _b !== void 0 ? _b : "horizontal";
509
+ }
510
+ get isVertical() {
511
+ return this.variant === "orientation" || this.axis === "vertical";
512
+ }
513
+ get shouldAttach() {
514
+ return !this.separated && this.variant !== "default";
515
+ }
516
+ get ariaOrientation() {
517
+ return this.isVertical ? "vertical" : "horizontal";
518
+ }
519
+ get rootClasses() {
491
520
  return [
492
- 'inline-flex w-fit',
493
- isVertical ? 'flex-col items-stretch' : 'items-center',
494
- this.variant === 'default' || this.separated ? 'gap-2' : 'gap-0',
495
- isGroup ? '*:focus-visible:relative *:focus-visible:z-10' : '',
496
- attachedClasses,
497
- groupHorizontalClasses,
498
- groupVerticalClasses,
499
- isSeparator
500
- ? 'overflow-hidden rounded-md border border-border bg-secondary shadow-sm'
501
- : '',
502
- this.className
521
+ ROOT_LAYOUT[this.isVertical ? "vertical" : "horizontal"],
522
+ this.variant === "default" || this.separated ? "gap-2" : "gap-0",
523
+ this.shouldAttach
524
+ ? ATTACHMENT_EDGE_CLASSES[this.isVertical ? "vertical" : "horizontal"].join(" ")
525
+ : "",
526
+ this.shouldAttach
527
+ ? ATTACHMENT_CONTROL_CLASSES[this.isVertical ? "vertical" : "horizontal"].join(" ")
528
+ : "",
529
+ this.shouldAttach ? FOCUS_STACKING_CLASS : "",
530
+ this.variant === "separator" ? SEPARATOR_CLASSES : "",
531
+ this.className,
503
532
  ];
504
533
  }
505
534
  }
506
535
  PdmButtonGroupComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmButtonGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
507
- PdmButtonGroupComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmButtonGroupComponent, selector: "pdm-button-group", inputs: { variant: "variant", orientation: "orientation", direction: "direction", separated: "separated", className: "className" }, ngImport: i0, template: "<div\n role=\"group\"\n [attr.aria-orientation]=\"variant === 'orientation' || orientation === 'vertical' || direction === 'vertical' ? 'vertical' : 'horizontal'\"\n [ngClass]=\"rootClasses\"\n>\n <ng-content></ng-content>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
536
+ PdmButtonGroupComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmButtonGroupComponent, selector: "pdm-button-group", inputs: { variant: "variant", orientation: "orientation", direction: "direction", separated: "separated", className: "className" }, ngImport: i0, template: "<div\n role=\"group\"\n [attr.aria-orientation]=\"ariaOrientation\"\n [ngClass]=\"rootClasses\"\n>\n <ng-content></ng-content>\n</div>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
508
537
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmButtonGroupComponent, decorators: [{
509
538
  type: Component,
510
- args: [{ selector: 'pdm-button-group', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n role=\"group\"\n [attr.aria-orientation]=\"variant === 'orientation' || orientation === 'vertical' || direction === 'vertical' ? 'vertical' : 'horizontal'\"\n [ngClass]=\"rootClasses\"\n>\n <ng-content></ng-content>\n</div>\n" }]
539
+ args: [{ selector: "pdm-button-group", changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n role=\"group\"\n [attr.aria-orientation]=\"ariaOrientation\"\n [ngClass]=\"rootClasses\"\n>\n <ng-content></ng-content>\n</div>\n", styles: [":host{display:block}\n"] }]
511
540
  }], propDecorators: { variant: [{
512
541
  type: Input
513
542
  }], orientation: [{
@@ -1542,35 +1571,207 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
1542
1571
  type: Output
1543
1572
  }] } });
1544
1573
 
1574
+ /**
1575
+ * Z-Index helper for overlay components.
1576
+ *
1577
+ * CRITICAL: Consumer custom panelClass MUST NOT replace the base z-index.
1578
+ * This helper ensures z-index is preserved when merging custom classes.
1579
+ */
1580
+ /**
1581
+ * Base z-index class for overlays - MUST be included in any overlay panel.
1582
+ * This ensures overlays appear above modals (z-50) and drawers (z-40).
1583
+ */
1584
+ const OVERLAY_BASE_Z_INDEX = "z-[70]";
1585
+ /**
1586
+ * Merge consumer's panelClass with our base z-index.
1587
+ * Consumer classes are APPENDED, not replacing our z-index guarantee.
1588
+ *
1589
+ * @param baseZIndex - Base z-index class to enforce (default: OVERLAY_BASE_Z_INDEX)
1590
+ * @param consumerClasses - Optional additional classes from consumer
1591
+ * @returns Array of classes safe for CDK Overlay panelClass
1592
+ */
1593
+ function mergeOverlayPanelClass(baseZIndex = OVERLAY_BASE_Z_INDEX, consumerClasses) {
1594
+ const baseClasses = baseZIndex.split(" ");
1595
+ if (!consumerClasses) {
1596
+ return baseClasses;
1597
+ }
1598
+ const consumerClassArray = Array.isArray(consumerClasses)
1599
+ ? consumerClasses
1600
+ : consumerClasses.split(" ");
1601
+ // Consumer classes are appended AFTER base classes
1602
+ // This ensures z-index from baseClasses is preserved first
1603
+ return [...baseClasses, ...consumerClassArray];
1604
+ }
1605
+ /**
1606
+ * Create OverlayConfig with guaranteed z-index.
1607
+ * Use this instead of direct OverlayConfig to ensure z-index enforcement.
1608
+ *
1609
+ * @param baseConfig - Base overlay configuration
1610
+ * @param consumerPanelClass - Optional consumer panelClass to merge
1611
+ * @returns OverlayConfig with z-index guarantee
1612
+ */
1613
+ function createZIndexEnforcedOverlay(baseConfig, consumerPanelClass) {
1614
+ const mergedClasses = mergeOverlayPanelClass(OVERLAY_BASE_Z_INDEX, consumerPanelClass);
1615
+ const existingPanelClass = baseConfig.panelClass;
1616
+ if (existingPanelClass) {
1617
+ const existingArray = Array.isArray(existingPanelClass)
1618
+ ? existingPanelClass
1619
+ : existingPanelClass.split(" ");
1620
+ return Object.assign(Object.assign({}, baseConfig), { panelClass: [...mergedClasses, ...existingArray] });
1621
+ }
1622
+ return Object.assign(Object.assign({}, baseConfig), { panelClass: mergedClasses });
1623
+ }
1624
+ /**
1625
+ * Helper to extract z-index from a class string for debugging.
1626
+ */
1627
+ function extractZIndex(classes) {
1628
+ const classArray = Array.isArray(classes) ? classes : classes.split(" ");
1629
+ for (const cls of classArray) {
1630
+ if (cls.startsWith("z-") || cls.startsWith("z-[")) {
1631
+ return cls;
1632
+ }
1633
+ }
1634
+ return null;
1635
+ }
1636
+
1545
1637
  class PdmComboboxComponent {
1546
- constructor() {
1638
+ constructor(overlay, viewContainerRef, elementRef, cdr) {
1639
+ this.overlay = overlay;
1640
+ this.viewContainerRef = viewContainerRef;
1641
+ this.elementRef = elementRef;
1642
+ this.cdr = cdr;
1547
1643
  this.open = false;
1548
- this.placeholder = 'Select framework...';
1549
- this.searchPlaceholder = 'Search framework';
1550
- this.className = '';
1551
- this.options = ['Next.js', 'SvelteKit', 'Nuxt.js', 'Remix', 'Astro'];
1552
- this.value = '';
1644
+ this.placeholder = "Select framework...";
1645
+ this.searchPlaceholder = "Search framework";
1646
+ this.className = "";
1647
+ this.options = [
1648
+ "Next.js",
1649
+ "SvelteKit",
1650
+ "Nuxt.js",
1651
+ "Remix",
1652
+ "Astro",
1653
+ ];
1654
+ this.value = "";
1553
1655
  this.width = 200;
1656
+ this.panelClassName = "";
1554
1657
  this.openChange = new EventEmitter();
1555
1658
  this.valueChange = new EventEmitter();
1659
+ this.overlayRef = null;
1660
+ this.outsideClickSub = null;
1661
+ }
1662
+ ngOnDestroy() {
1663
+ this.destroyOverlay();
1556
1664
  }
1557
1665
  get selectedLabel() {
1558
1666
  return this.value || this.placeholder;
1559
1667
  }
1560
1668
  toggle() {
1561
- this.openChange.emit(!this.open);
1669
+ if (this.open) {
1670
+ this.close();
1671
+ }
1672
+ else {
1673
+ this.openPanel();
1674
+ }
1562
1675
  }
1563
1676
  select(option) {
1564
1677
  this.valueChange.emit(option);
1678
+ this.value = option;
1679
+ this.close();
1680
+ }
1681
+ onEscape() {
1682
+ if (this.open) {
1683
+ this.close();
1684
+ }
1685
+ }
1686
+ openPanel() {
1687
+ var _a;
1688
+ if (this.overlayRef)
1689
+ return;
1690
+ const triggerEl = (_a = this.triggerRef) === null || _a === void 0 ? void 0 : _a.nativeElement;
1691
+ if (!triggerEl)
1692
+ return;
1693
+ this.open = true;
1694
+ this.openChange.emit(true);
1695
+ this.cdr.markForCheck();
1696
+ const positionStrategy = this.overlay
1697
+ .position()
1698
+ .flexibleConnectedTo(triggerEl)
1699
+ .withPositions(this.getPositionConfigs())
1700
+ .withFlexibleDimensions(false)
1701
+ .withPush(true);
1702
+ const panelClass = mergeOverlayPanelClass(OVERLAY_BASE_Z_INDEX, this.panelClassName);
1703
+ this.overlayRef = this.overlay.create({
1704
+ positionStrategy,
1705
+ panelClass,
1706
+ });
1707
+ const portal = new TemplatePortal(this.panelTemplateRef, this.viewContainerRef);
1708
+ this.overlayRef.attach(portal);
1709
+ // Close on click outside
1710
+ this.outsideClickSub = this.overlayRef
1711
+ .outsidePointerEvents()
1712
+ .subscribe(() => {
1713
+ this.close();
1714
+ });
1715
+ this.cdr.markForCheck();
1716
+ }
1717
+ close() {
1718
+ if (!this.overlayRef)
1719
+ return;
1720
+ this.open = false;
1565
1721
  this.openChange.emit(false);
1722
+ this.cdr.markForCheck();
1723
+ this.destroyOverlay();
1724
+ }
1725
+ destroyOverlay() {
1726
+ if (this.outsideClickSub) {
1727
+ this.outsideClickSub.unsubscribe();
1728
+ this.outsideClickSub = null;
1729
+ }
1730
+ if (this.overlayRef) {
1731
+ this.overlayRef.detach();
1732
+ this.overlayRef.dispose();
1733
+ this.overlayRef = null;
1734
+ }
1735
+ }
1736
+ getPositionConfigs() {
1737
+ return [
1738
+ {
1739
+ originX: "start",
1740
+ originY: "bottom",
1741
+ overlayX: "start",
1742
+ overlayY: "top",
1743
+ offsetY: 4,
1744
+ },
1745
+ {
1746
+ originX: "start",
1747
+ originY: "top",
1748
+ overlayX: "start",
1749
+ overlayY: "bottom",
1750
+ offsetY: -4,
1751
+ },
1752
+ {
1753
+ originX: "end",
1754
+ originY: "bottom",
1755
+ overlayX: "end",
1756
+ overlayY: "top",
1757
+ offsetY: 4,
1758
+ },
1759
+ {
1760
+ originX: "start",
1761
+ originY: "bottom",
1762
+ overlayX: "end",
1763
+ overlayY: "top",
1764
+ offsetY: 4,
1765
+ },
1766
+ ];
1566
1767
  }
1567
1768
  }
1568
- PdmComboboxComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmComboboxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1569
- PdmComboboxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmComboboxComponent, selector: "pdm-combobox", inputs: { open: "open", placeholder: "placeholder", searchPlaceholder: "searchPlaceholder", className: "className", options: "options", value: "value", width: "width" }, outputs: { openChange: "openChange", valueChange: "valueChange" }, ngImport: i0, template: "<div [ngClass]=\"['flex flex-col gap-1', className]\" [style.width.px]=\"width\">\n <button\n type=\"button\"\n class=\"flex h-9 w-full appearance-none items-center justify-between gap-2 rounded-md border border-input bg-background px-3 py-2 text-sm shadow-sm\"\n [attr.aria-expanded]=\"open\"\n (click)=\"toggle()\"\n >\n <span class=\"min-w-0 flex-1 truncate text-left text-sm font-medium text-foreground\">{{ selectedLabel }}</span>\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4 text-foreground\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M7 15L12 20L17 15\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n <path d=\"M17 9L12 4L7 9\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n\n <div\n *ngIf=\"open\"\n class=\"w-full rounded-md border border-border bg-popover p-0 text-popover-foreground shadow-md\"\n >\n <div class=\"flex items-center gap-2 border-b border-border px-3\">\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4 text-muted-foreground\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"11\" cy=\"11\" r=\"7\" stroke=\"currentColor\" stroke-width=\"1.5\"></circle>\n <path d=\"M20 20L16.6 16.6\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"></path>\n </svg>\n <div class=\"h-9 flex-1 py-2 text-sm text-muted-foreground\">{{ searchPlaceholder }}</div>\n </div>\n\n <div class=\"p-1\">\n <button\n *ngFor=\"let option of options\"\n type=\"button\"\n class=\"flex w-full appearance-none items-center gap-2 rounded-sm border-0 bg-transparent px-2 py-1.5 text-left text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground\"\n [ngClass]=\"option === value ? 'bg-accent text-accent-foreground' : ''\"\n (click)=\"select(option)\"\n >\n <span class=\"min-w-0 flex-1 truncate\">{{ option }}</span>\n <svg *ngIf=\"option === value\" viewBox=\"0 0 24 24\" class=\"h-4 w-4 text-foreground\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M5 12.5L9.2 16.7L19 7\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1769
+ PdmComboboxComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmComboboxComponent, deps: [{ token: i1$1.Overlay }, { token: i0.ViewContainerRef }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1770
+ PdmComboboxComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmComboboxComponent, selector: "pdm-combobox", inputs: { open: "open", placeholder: "placeholder", searchPlaceholder: "searchPlaceholder", className: "className", options: "options", value: "value", width: "width", panelClassName: "panelClassName" }, outputs: { openChange: "openChange", valueChange: "valueChange" }, host: { listeners: { "document:keydown.escape": "onEscape()" } }, viewQueries: [{ propertyName: "triggerRef", first: true, predicate: ["triggerEl"], descendants: true }, { propertyName: "panelTemplateRef", first: true, predicate: ["panelTemplate"], descendants: true }], ngImport: i0, template: "<div [ngClass]=\"['flex flex-col gap-1', className]\" [style.width.px]=\"width\">\n <button\n #triggerEl\n type=\"button\"\n class=\"flex h-9 w-full appearance-none items-center justify-between gap-2 rounded-md border border-input bg-background px-3 py-2 text-sm shadow-sm\"\n [attr.aria-expanded]=\"open\"\n [attr.aria-haspopup]=\"'listbox'\"\n (click)=\"toggle()\"\n >\n <span\n class=\"min-w-0 flex-1 truncate text-left text-sm font-medium text-foreground\"\n >{{ selectedLabel }}</span\n >\n <svg\n viewBox=\"0 0 24 24\"\n class=\"h-4 w-4 text-foreground\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M7 15L12 20L17 15\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n ></path>\n <path\n d=\"M17 9L12 4L7 9\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n ></path>\n </svg>\n </button>\n\n <!-- Template for CDK Overlay -->\n <ng-template #panelTemplate>\n <div\n class=\"w-full rounded-md border border-border bg-popover p-0 text-popover-foreground shadow-md\"\n >\n <div class=\"flex items-center gap-2 border-b border-border px-3 py-2\">\n <svg\n viewBox=\"0 0 24 24\"\n class=\"h-4 w-4 text-muted-foreground\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle\n cx=\"11\"\n cy=\"11\"\n r=\"7\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n ></circle>\n <path\n d=\"M20 20L16.6 16.6\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n ></path>\n </svg>\n <div class=\"flex-1 py-2 text-sm text-muted-foreground\">\n {{ searchPlaceholder }}\n </div>\n </div>\n\n <div class=\"p-1\">\n <button\n *ngFor=\"let option of options\"\n type=\"button\"\n class=\"flex w-full appearance-none items-center gap-2 rounded-sm border-0 bg-transparent px-2 py-1.5 text-left text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground\"\n [ngClass]=\"option === value ? 'bg-accent text-accent-foreground' : ''\"\n role=\"option\"\n [attr.aria-selected]=\"option === value\"\n (click)=\"select(option)\"\n >\n <span class=\"min-w-0 flex-1 truncate\">{{ option }}</span>\n <svg\n *ngIf=\"option === value\"\n viewBox=\"0 0 24 24\"\n class=\"h-4 w-4 text-foreground\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M5 12.5L9.2 16.7L19 7\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n ></path>\n </svg>\n </button>\n </div>\n </div>\n </ng-template>\n</div>\n", styles: [":host{display:block}\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 });
1570
1771
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmComboboxComponent, decorators: [{
1571
1772
  type: Component,
1572
- args: [{ selector: 'pdm-combobox', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"['flex flex-col gap-1', className]\" [style.width.px]=\"width\">\n <button\n type=\"button\"\n class=\"flex h-9 w-full appearance-none items-center justify-between gap-2 rounded-md border border-input bg-background px-3 py-2 text-sm shadow-sm\"\n [attr.aria-expanded]=\"open\"\n (click)=\"toggle()\"\n >\n <span class=\"min-w-0 flex-1 truncate text-left text-sm font-medium text-foreground\">{{ selectedLabel }}</span>\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4 text-foreground\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M7 15L12 20L17 15\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n <path d=\"M17 9L12 4L7 9\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n\n <div\n *ngIf=\"open\"\n class=\"w-full rounded-md border border-border bg-popover p-0 text-popover-foreground shadow-md\"\n >\n <div class=\"flex items-center gap-2 border-b border-border px-3\">\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4 text-muted-foreground\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"11\" cy=\"11\" r=\"7\" stroke=\"currentColor\" stroke-width=\"1.5\"></circle>\n <path d=\"M20 20L16.6 16.6\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"></path>\n </svg>\n <div class=\"h-9 flex-1 py-2 text-sm text-muted-foreground\">{{ searchPlaceholder }}</div>\n </div>\n\n <div class=\"p-1\">\n <button\n *ngFor=\"let option of options\"\n type=\"button\"\n class=\"flex w-full appearance-none items-center gap-2 rounded-sm border-0 bg-transparent px-2 py-1.5 text-left text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground\"\n [ngClass]=\"option === value ? 'bg-accent text-accent-foreground' : ''\"\n (click)=\"select(option)\"\n >\n <span class=\"min-w-0 flex-1 truncate\">{{ option }}</span>\n <svg *ngIf=\"option === value\" viewBox=\"0 0 24 24\" class=\"h-4 w-4 text-foreground\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M5 12.5L9.2 16.7L19 7\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n </div>\n </div>\n</div>\n" }]
1573
- }], propDecorators: { open: [{
1773
+ args: [{ selector: "pdm-combobox", changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"['flex flex-col gap-1', className]\" [style.width.px]=\"width\">\n <button\n #triggerEl\n type=\"button\"\n class=\"flex h-9 w-full appearance-none items-center justify-between gap-2 rounded-md border border-input bg-background px-3 py-2 text-sm shadow-sm\"\n [attr.aria-expanded]=\"open\"\n [attr.aria-haspopup]=\"'listbox'\"\n (click)=\"toggle()\"\n >\n <span\n class=\"min-w-0 flex-1 truncate text-left text-sm font-medium text-foreground\"\n >{{ selectedLabel }}</span\n >\n <svg\n viewBox=\"0 0 24 24\"\n class=\"h-4 w-4 text-foreground\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M7 15L12 20L17 15\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n ></path>\n <path\n d=\"M17 9L12 4L7 9\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n ></path>\n </svg>\n </button>\n\n <!-- Template for CDK Overlay -->\n <ng-template #panelTemplate>\n <div\n class=\"w-full rounded-md border border-border bg-popover p-0 text-popover-foreground shadow-md\"\n >\n <div class=\"flex items-center gap-2 border-b border-border px-3 py-2\">\n <svg\n viewBox=\"0 0 24 24\"\n class=\"h-4 w-4 text-muted-foreground\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle\n cx=\"11\"\n cy=\"11\"\n r=\"7\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n ></circle>\n <path\n d=\"M20 20L16.6 16.6\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n ></path>\n </svg>\n <div class=\"flex-1 py-2 text-sm text-muted-foreground\">\n {{ searchPlaceholder }}\n </div>\n </div>\n\n <div class=\"p-1\">\n <button\n *ngFor=\"let option of options\"\n type=\"button\"\n class=\"flex w-full appearance-none items-center gap-2 rounded-sm border-0 bg-transparent px-2 py-1.5 text-left text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground\"\n [ngClass]=\"option === value ? 'bg-accent text-accent-foreground' : ''\"\n role=\"option\"\n [attr.aria-selected]=\"option === value\"\n (click)=\"select(option)\"\n >\n <span class=\"min-w-0 flex-1 truncate\">{{ option }}</span>\n <svg\n *ngIf=\"option === value\"\n viewBox=\"0 0 24 24\"\n class=\"h-4 w-4 text-foreground\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M5 12.5L9.2 16.7L19 7\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n ></path>\n </svg>\n </button>\n </div>\n </div>\n </ng-template>\n</div>\n", styles: [":host{display:block}\n"] }]
1774
+ }], ctorParameters: function () { return [{ type: i1$1.Overlay }, { type: i0.ViewContainerRef }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { open: [{
1574
1775
  type: Input
1575
1776
  }], placeholder: [{
1576
1777
  type: Input
@@ -1584,10 +1785,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
1584
1785
  type: Input
1585
1786
  }], width: [{
1586
1787
  type: Input
1788
+ }], panelClassName: [{
1789
+ type: Input
1587
1790
  }], openChange: [{
1588
1791
  type: Output
1589
1792
  }], valueChange: [{
1590
1793
  type: Output
1794
+ }], triggerRef: [{
1795
+ type: ViewChild,
1796
+ args: ["triggerEl"]
1797
+ }], panelTemplateRef: [{
1798
+ type: ViewChild,
1799
+ args: ["panelTemplate"]
1800
+ }], onEscape: [{
1801
+ type: HostListener,
1802
+ args: ["document:keydown.escape"]
1591
1803
  }] } });
1592
1804
 
1593
1805
  const FALLBACK_NODE = [['circle', { cx: '12', cy: '12', r: '9' }]];
@@ -1709,12 +1921,12 @@ class PdmIconComponent {
1709
1921
  .replace(/>/g, '&gt;');
1710
1922
  }
1711
1923
  }
1712
- 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 });
1924
+ PdmIconComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmIconComponent, deps: [{ token: i1$2.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component });
1713
1925
  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 });
1714
1926
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmIconComponent, decorators: [{
1715
1927
  type: Component,
1716
1928
  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"] }]
1717
- }], ctorParameters: function () { return [{ type: i1$1.DomSanitizer }]; }, propDecorators: { name: [{
1929
+ }], ctorParameters: function () { return [{ type: i1$2.DomSanitizer }]; }, propDecorators: { name: [{
1718
1930
  type: Input
1719
1931
  }], library: [{
1720
1932
  type: Input
@@ -1805,72 +2017,140 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
1805
2017
  }] } });
1806
2018
 
1807
2019
  class PdmContextMenuComponent {
1808
- constructor(elementRef) {
1809
- this.elementRef = elementRef;
2020
+ constructor(overlay, viewContainerRef, _elementRef, cdr) {
2021
+ this.overlay = overlay;
2022
+ this.viewContainerRef = viewContainerRef;
2023
+ this._elementRef = _elementRef;
2024
+ this.cdr = cdr;
1810
2025
  this.items = [
1811
- { type: 'item', label: 'Back', value: 'back', inset: true, shortcut: '⌘[' },
1812
- { type: 'item', label: 'Forward', value: 'forward', inset: true, shortcut: '⌘]', disabled: true },
1813
- { type: 'item', label: 'Reload', value: 'reload', inset: true, shortcut: '⌘R' },
1814
- { type: 'item', label: 'More Tools', value: 'more-tools', inset: true, showChevron: true },
1815
- { type: 'separator' },
1816
- { type: 'item', label: 'Show Bookmarks Bar', value: 'show-bookmarks', checked: true },
1817
- { type: 'item', label: 'Show Full URLs', value: 'show-urls', inset: true },
1818
- { type: 'separator' },
1819
- { type: 'label', label: 'People' },
1820
- { type: 'separator' },
1821
- { type: 'item', label: 'Pedro Duarte', value: 'pedro', selectedDot: true },
1822
- { type: 'item', label: 'Colm Tuite', value: 'colm', inset: true }
2026
+ { type: "item", label: "Back", value: "back", inset: true, shortcut: "⌘[" },
2027
+ {
2028
+ type: "item",
2029
+ label: "Forward",
2030
+ value: "forward",
2031
+ inset: true,
2032
+ shortcut: "⌘]",
2033
+ disabled: true,
2034
+ },
2035
+ {
2036
+ type: "item",
2037
+ label: "Reload",
2038
+ value: "reload",
2039
+ inset: true,
2040
+ shortcut: "⌘R",
2041
+ },
2042
+ {
2043
+ type: "item",
2044
+ label: "More Tools",
2045
+ value: "more-tools",
2046
+ inset: true,
2047
+ showChevron: true,
2048
+ },
2049
+ { type: "separator" },
2050
+ {
2051
+ type: "item",
2052
+ label: "Show Bookmarks Bar",
2053
+ value: "show-bookmarks",
2054
+ checked: true,
2055
+ },
2056
+ { type: "item", label: "Show Full URLs", value: "show-urls", inset: true },
2057
+ { type: "separator" },
2058
+ { type: "label", label: "People" },
2059
+ { type: "separator" },
2060
+ { type: "item", label: "Pedro Duarte", value: "pedro", selectedDot: true },
2061
+ { type: "item", label: "Colm Tuite", value: "colm", inset: true },
1823
2062
  ];
1824
- this.className = '';
1825
- this.triggerLabel = 'Right click here';
2063
+ this.className = "";
2064
+ this.triggerLabel = "Right click here";
1826
2065
  this.width = 300;
1827
2066
  this.height = 150;
2067
+ this.panelClassName = "";
1828
2068
  this.itemSelect = new EventEmitter();
1829
2069
  this.open = false;
1830
2070
  this.x = 0;
1831
2071
  this.y = 0;
2072
+ this.overlayRef = null;
2073
+ this.outsideClickSub = null;
1832
2074
  }
1833
- ngOnInit() {
1834
- this.boundPointerDown = (event) => this.onDocumentPointerDown(event);
1835
- document.addEventListener('pointerdown', this.boundPointerDown, { capture: true });
1836
- }
2075
+ ngOnInit() { }
1837
2076
  ngOnDestroy() {
1838
- if (this.boundPointerDown) {
1839
- document.removeEventListener('pointerdown', this.boundPointerDown, { capture: true });
1840
- }
2077
+ this.destroyOverlay();
1841
2078
  }
1842
2079
  onContextMenu(event) {
1843
2080
  event.preventDefault();
2081
+ event.stopPropagation();
1844
2082
  this.x = event.clientX;
1845
2083
  this.y = event.clientY;
1846
2084
  this.open = true;
2085
+ this.cdr.markForCheck();
2086
+ this.createOverlay();
1847
2087
  }
1848
2088
  select(item) {
1849
- if (item.disabled || item.type === 'separator' || item.type === 'label' || !item.value)
2089
+ if (item.disabled ||
2090
+ item.type === "separator" ||
2091
+ item.type === "label" ||
2092
+ !item.value)
1850
2093
  return;
1851
2094
  this.itemSelect.emit(item.value);
1852
2095
  this.open = false;
2096
+ this.cdr.markForCheck();
2097
+ this.destroyOverlay();
1853
2098
  }
1854
- onEsc() {
1855
- if (this.open) {
1856
- this.open = false;
2099
+ onDocumentClick(event) {
2100
+ if (this.open && event.type === "click") {
2101
+ // Don't close on click inside the menu
2102
+ if (this.overlayRef &&
2103
+ this.overlayRef.overlayElement.contains(event.target)) {
2104
+ return;
2105
+ }
2106
+ this.close();
1857
2107
  }
1858
2108
  }
1859
- onDocumentPointerDown(event) {
1860
- if (!this.open)
1861
- return;
1862
- const target = event.target;
1863
- if (target && !this.elementRef.nativeElement.contains(target)) {
1864
- this.open = false;
2109
+ createOverlay() {
2110
+ this.destroyOverlay();
2111
+ // Create global position strategy at cursor position
2112
+ const positionStrategy = this.overlay
2113
+ .position()
2114
+ .global()
2115
+ .left(`${this.x}px`)
2116
+ .top(`${this.y}px`);
2117
+ const panelClass = mergeOverlayPanelClass(OVERLAY_BASE_Z_INDEX, this.panelClassName);
2118
+ this.overlayRef = this.overlay.create({
2119
+ positionStrategy,
2120
+ panelClass,
2121
+ });
2122
+ const portal = new TemplatePortal(this.menuTemplateRef, this.viewContainerRef);
2123
+ this.overlayRef.attach(portal);
2124
+ // Close on click outside
2125
+ this.outsideClickSub = this.overlayRef
2126
+ .outsidePointerEvents()
2127
+ .subscribe(() => {
2128
+ this.close();
2129
+ });
2130
+ }
2131
+ close() {
2132
+ this.open = false;
2133
+ this.cdr.markForCheck();
2134
+ this.destroyOverlay();
2135
+ }
2136
+ destroyOverlay() {
2137
+ if (this.outsideClickSub) {
2138
+ this.outsideClickSub.unsubscribe();
2139
+ this.outsideClickSub = null;
2140
+ }
2141
+ if (this.overlayRef) {
2142
+ this.overlayRef.detach();
2143
+ this.overlayRef.dispose();
2144
+ this.overlayRef = null;
1865
2145
  }
1866
2146
  }
1867
2147
  }
1868
- PdmContextMenuComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmContextMenuComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
1869
- PdmContextMenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmContextMenuComponent, selector: "pdm-context-menu", inputs: { items: "items", className: "className", triggerLabel: "triggerLabel", width: "width", height: "height" }, outputs: { itemSelect: "itemSelect" }, host: { listeners: { "document:keydown.escape": "onEsc()" } }, ngImport: i0, template: "<div class=\"relative\" [ngClass]=\"className\" (contextmenu)=\"onContextMenu($event)\">\n <div\n class=\"flex items-center justify-center rounded-md border border-dashed border-border\"\n [style.width.px]=\"width\"\n [style.height.px]=\"height\"\n >\n <span class=\"text-sm font-medium text-foreground\">{{ triggerLabel }}</span>\n </div>\n\n <div\n *ngIf=\"open\"\n class=\"fixed z-[70] min-w-48 max-w-xs rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md sm:min-w-52\"\n [style.left.px]=\"x + 4\"\n [style.top.px]=\"y + 2\"\n >\n <div>\n <ng-container *ngFor=\"let item of items\">\n <div *ngIf=\"item.type === 'separator'\" class=\"-mx-1 my-1 h-px bg-muted\"></div>\n\n <div *ngIf=\"item.type === 'label'\" class=\"px-2 py-1.5 text-sm font-semibold text-foreground\">\n {{ item.label }}\n </div>\n\n <button\n *ngIf=\"!item.type || item.type === 'item'\"\n type=\"button\"\n [disabled]=\"item.disabled\"\n class=\"relative flex w-full appearance-none cursor-default select-none items-center rounded-sm border-0 bg-transparent py-1.5 pr-2 text-left text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground disabled:pointer-events-none disabled:opacity-50\"\n [ngClass]=\"item.inset ? 'pl-8' : 'px-2'\"\n (click)=\"select(item)\"\n >\n <span class=\"mr-2 inline-flex w-4 shrink-0 items-center justify-center text-foreground\">\n <svg *ngIf=\"item.checked\" viewBox=\"0 0 24 24\" class=\"h-3.5 w-3.5\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M5 12.5L9.2 16.7L19 7\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n <span *ngIf=\"item.selectedDot\" class=\"h-2 w-2 rounded-full bg-foreground\"></span>\n </span>\n <span class=\"min-w-0 flex-1 truncate text-foreground\">{{ item.label }}</span>\n <span *ngIf=\"item.shortcut\" class=\"text-xs text-muted-foreground\">{{ item.shortcut }}</span>\n <svg *ngIf=\"item.showChevron\" viewBox=\"0 0 24 24\" class=\"h-3.5 w-3.5 text-muted-foreground\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M9 6L15 12L9 18\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n </ng-container>\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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2148
+ PdmContextMenuComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmContextMenuComponent, deps: [{ token: i1$1.Overlay }, { token: i0.ViewContainerRef }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
2149
+ PdmContextMenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmContextMenuComponent, selector: "pdm-context-menu", inputs: { items: "items", className: "className", triggerLabel: "triggerLabel", width: "width", height: "height", panelClassName: "panelClassName" }, outputs: { itemSelect: "itemSelect" }, host: { listeners: { "document:keydown.escape": "onDocumentClick()", "document:click": "onDocumentClick()" } }, viewQueries: [{ propertyName: "menuTemplateRef", first: true, predicate: ["menuTemplate"], descendants: true }], ngImport: i0, template: "<div\n class=\"relative\"\n [ngClass]=\"className\"\n (contextmenu)=\"onContextMenu($event)\"\n>\n <div\n class=\"flex items-center justify-center rounded-md border border-dashed border-border\"\n [style.width.px]=\"width\"\n [style.height.px]=\"height\"\n >\n <span class=\"text-sm font-medium text-foreground\">{{ triggerLabel }}</span>\n </div>\n\n <!-- Template for CDK Overlay -->\n <ng-template #menuTemplate>\n <div\n class=\"min-w-48 max-w-xs rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md sm:min-w-52\"\n >\n <div>\n <ng-container *ngFor=\"let item of items\">\n <div\n *ngIf=\"item.type === 'separator'\"\n class=\"-mx-1 my-1 h-px bg-muted\"\n ></div>\n\n <div\n *ngIf=\"item.type === 'label'\"\n class=\"px-2 py-1.5 text-sm font-semibold text-foreground\"\n >\n {{ item.label }}\n </div>\n\n <button\n *ngIf=\"!item.type || item.type === 'item'\"\n type=\"button\"\n [disabled]=\"item.disabled\"\n class=\"relative flex w-full appearance-none cursor-default select-none items-center rounded-sm border-0 bg-transparent py-1.5 pr-2 text-left text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground disabled:pointer-events-none disabled:opacity-50\"\n [ngClass]=\"item.inset ? 'pl-8' : 'px-2'\"\n (click)=\"select(item)\"\n >\n <span\n class=\"mr-2 inline-flex w-4 shrink-0 items-center justify-center text-foreground\"\n >\n <svg\n *ngIf=\"item.checked\"\n viewBox=\"0 0 24 24\"\n class=\"h-3.5 w-3.5\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M5 12.5L9.2 16.7L19 7\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n ></path>\n </svg>\n <span\n *ngIf=\"item.selectedDot\"\n class=\"h-2 w-2 rounded-full bg-foreground\"\n ></span>\n </span>\n <span class=\"min-w-0 flex-1 truncate text-foreground\">{{\n item.label\n }}</span>\n <span *ngIf=\"item.shortcut\" class=\"text-xs text-muted-foreground\">{{\n item.shortcut\n }}</span>\n <svg\n *ngIf=\"item.showChevron\"\n viewBox=\"0 0 24 24\"\n class=\"h-3.5 w-3.5 text-muted-foreground\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M9 6L15 12L9 18\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n ></path>\n </svg>\n </button>\n </ng-container>\n </div>\n </div>\n </ng-template>\n</div>\n", styles: [":host{display:block}\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 });
1870
2150
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmContextMenuComponent, decorators: [{
1871
2151
  type: Component,
1872
- args: [{ selector: 'pdm-context-menu', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"relative\" [ngClass]=\"className\" (contextmenu)=\"onContextMenu($event)\">\n <div\n class=\"flex items-center justify-center rounded-md border border-dashed border-border\"\n [style.width.px]=\"width\"\n [style.height.px]=\"height\"\n >\n <span class=\"text-sm font-medium text-foreground\">{{ triggerLabel }}</span>\n </div>\n\n <div\n *ngIf=\"open\"\n class=\"fixed z-[70] min-w-48 max-w-xs rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md sm:min-w-52\"\n [style.left.px]=\"x + 4\"\n [style.top.px]=\"y + 2\"\n >\n <div>\n <ng-container *ngFor=\"let item of items\">\n <div *ngIf=\"item.type === 'separator'\" class=\"-mx-1 my-1 h-px bg-muted\"></div>\n\n <div *ngIf=\"item.type === 'label'\" class=\"px-2 py-1.5 text-sm font-semibold text-foreground\">\n {{ item.label }}\n </div>\n\n <button\n *ngIf=\"!item.type || item.type === 'item'\"\n type=\"button\"\n [disabled]=\"item.disabled\"\n class=\"relative flex w-full appearance-none cursor-default select-none items-center rounded-sm border-0 bg-transparent py-1.5 pr-2 text-left text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground disabled:pointer-events-none disabled:opacity-50\"\n [ngClass]=\"item.inset ? 'pl-8' : 'px-2'\"\n (click)=\"select(item)\"\n >\n <span class=\"mr-2 inline-flex w-4 shrink-0 items-center justify-center text-foreground\">\n <svg *ngIf=\"item.checked\" viewBox=\"0 0 24 24\" class=\"h-3.5 w-3.5\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M5 12.5L9.2 16.7L19 7\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n <span *ngIf=\"item.selectedDot\" class=\"h-2 w-2 rounded-full bg-foreground\"></span>\n </span>\n <span class=\"min-w-0 flex-1 truncate text-foreground\">{{ item.label }}</span>\n <span *ngIf=\"item.shortcut\" class=\"text-xs text-muted-foreground\">{{ item.shortcut }}</span>\n <svg *ngIf=\"item.showChevron\" viewBox=\"0 0 24 24\" class=\"h-3.5 w-3.5 text-muted-foreground\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M9 6L15 12L9 18\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n </ng-container>\n </div>\n </div>\n</div>\n" }]
1873
- }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { items: [{
2152
+ args: [{ selector: "pdm-context-menu", changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"relative\"\n [ngClass]=\"className\"\n (contextmenu)=\"onContextMenu($event)\"\n>\n <div\n class=\"flex items-center justify-center rounded-md border border-dashed border-border\"\n [style.width.px]=\"width\"\n [style.height.px]=\"height\"\n >\n <span class=\"text-sm font-medium text-foreground\">{{ triggerLabel }}</span>\n </div>\n\n <!-- Template for CDK Overlay -->\n <ng-template #menuTemplate>\n <div\n class=\"min-w-48 max-w-xs rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md sm:min-w-52\"\n >\n <div>\n <ng-container *ngFor=\"let item of items\">\n <div\n *ngIf=\"item.type === 'separator'\"\n class=\"-mx-1 my-1 h-px bg-muted\"\n ></div>\n\n <div\n *ngIf=\"item.type === 'label'\"\n class=\"px-2 py-1.5 text-sm font-semibold text-foreground\"\n >\n {{ item.label }}\n </div>\n\n <button\n *ngIf=\"!item.type || item.type === 'item'\"\n type=\"button\"\n [disabled]=\"item.disabled\"\n class=\"relative flex w-full appearance-none cursor-default select-none items-center rounded-sm border-0 bg-transparent py-1.5 pr-2 text-left text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground disabled:pointer-events-none disabled:opacity-50\"\n [ngClass]=\"item.inset ? 'pl-8' : 'px-2'\"\n (click)=\"select(item)\"\n >\n <span\n class=\"mr-2 inline-flex w-4 shrink-0 items-center justify-center text-foreground\"\n >\n <svg\n *ngIf=\"item.checked\"\n viewBox=\"0 0 24 24\"\n class=\"h-3.5 w-3.5\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M5 12.5L9.2 16.7L19 7\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n ></path>\n </svg>\n <span\n *ngIf=\"item.selectedDot\"\n class=\"h-2 w-2 rounded-full bg-foreground\"\n ></span>\n </span>\n <span class=\"min-w-0 flex-1 truncate text-foreground\">{{\n item.label\n }}</span>\n <span *ngIf=\"item.shortcut\" class=\"text-xs text-muted-foreground\">{{\n item.shortcut\n }}</span>\n <svg\n *ngIf=\"item.showChevron\"\n viewBox=\"0 0 24 24\"\n class=\"h-3.5 w-3.5 text-muted-foreground\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M9 6L15 12L9 18\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n ></path>\n </svg>\n </button>\n </ng-container>\n </div>\n </div>\n </ng-template>\n</div>\n", styles: [":host{display:block}\n"] }]
2153
+ }], ctorParameters: function () { return [{ type: i1$1.Overlay }, { type: i0.ViewContainerRef }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { items: [{
1874
2154
  type: Input
1875
2155
  }], className: [{
1876
2156
  type: Input
@@ -1880,11 +2160,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
1880
2160
  type: Input
1881
2161
  }], height: [{
1882
2162
  type: Input
2163
+ }], panelClassName: [{
2164
+ type: Input
1883
2165
  }], itemSelect: [{
1884
2166
  type: Output
1885
- }], onEsc: [{
2167
+ }], menuTemplateRef: [{
2168
+ type: ViewChild,
2169
+ args: ["menuTemplate"]
2170
+ }], onDocumentClick: [{
1886
2171
  type: HostListener,
1887
- args: ['document:keydown.escape']
2172
+ args: ["document:keydown.escape"]
2173
+ }, {
2174
+ type: HostListener,
2175
+ args: ["document:click"]
1888
2176
  }] } });
1889
2177
 
1890
2178
  /**
@@ -2056,7 +2344,7 @@ class PdmTableComponent {
2056
2344
  * - data: tabla con bordes y espaciado para data
2057
2345
  * - interactive: tabla con hover, sticky header y estilos interactivos
2058
2346
  */
2059
- this.variant = 'default';
2347
+ this.variant = "default";
2060
2348
  /**
2061
2349
  * Estrategia responsive para la tabla
2062
2350
  * - scroll: scroll horizontal en mobile (default, más simple)
@@ -2064,11 +2352,11 @@ class PdmTableComponent {
2064
2352
  * - stack: convierte filas en cards en mobile (requiere data-label en celdas)
2065
2353
  * - collapse: oculta columnas menos importantes en mobile
2066
2354
  */
2067
- this.responsiveStrategy = 'scroll';
2355
+ this.responsiveStrategy = "scroll";
2068
2356
  /**
2069
2357
  * Clases CSS adicionales para el wrapper
2070
2358
  */
2071
- this.className = '';
2359
+ this.className = "";
2072
2360
  /**
2073
2361
  * Si es true, aplica padding negativo en mobile para scroll edge-to-edge
2074
2362
  * Útil cuando la tabla está dentro de un container con padding
@@ -2076,119 +2364,128 @@ class PdmTableComponent {
2076
2364
  this.fullBleed = false;
2077
2365
  }
2078
2366
  get wrapperClasses() {
2079
- const baseClasses = ['relative', 'w-full'];
2367
+ const baseClasses = ["relative", "w-full"];
2080
2368
  const strategyClasses = this.getResponsiveStrategyClasses();
2081
2369
  const variantClasses = this.getVariantWrapperClasses();
2082
2370
  // Full bleed: scroll edge-to-edge en mobile
2083
- if (this.fullBleed && this.responsiveStrategy === 'scroll') {
2084
- baseClasses.push('-mx-4', 'px-4', 'sm:mx-0', 'sm:px-0');
2371
+ if (this.fullBleed && this.responsiveStrategy === "scroll") {
2372
+ baseClasses.push("-mx-4", "px-4", "sm:mx-0", "sm:px-0");
2085
2373
  }
2086
2374
  return [
2087
2375
  ...baseClasses,
2088
2376
  ...strategyClasses,
2089
2377
  ...variantClasses,
2090
- this.className
2378
+ this.className,
2091
2379
  ].filter(Boolean);
2092
2380
  }
2093
2381
  get tableClasses() {
2094
- const baseClasses = ['w-full', 'caption-bottom', 'text-sm'];
2382
+ const baseClasses = ["w-full", "caption-bottom", "text-sm"];
2095
2383
  const variantClasses = this.getVariantTableClasses();
2096
2384
  const cellClasses = this.getCellClasses();
2097
2385
  return [...baseClasses, ...variantClasses, ...cellClasses].filter(Boolean);
2098
2386
  }
2099
2387
  getResponsiveStrategyClasses() {
2100
2388
  const strategy = TABLE_RESPONSIVE[this.responsiveStrategy];
2101
- if (this.responsiveStrategy === 'scroll') {
2102
- return ['overflow-x-auto'];
2389
+ if (this.responsiveStrategy === "scroll") {
2390
+ return ["overflow-x-auto"];
2103
2391
  }
2104
- if (this.responsiveStrategy === 'wrap') {
2105
- return ['overflow-x-auto'];
2392
+ if (this.responsiveStrategy === "wrap") {
2393
+ return ["overflow-x-auto"];
2106
2394
  }
2107
- if (this.responsiveStrategy === 'stack') {
2395
+ if (this.responsiveStrategy === "stack") {
2108
2396
  // Stack requiere lógica en el template, aquí solo el wrapper
2109
2397
  return [];
2110
2398
  }
2111
- if (this.responsiveStrategy === 'collapse') {
2112
- return ['overflow-x-auto'];
2399
+ if (this.responsiveStrategy === "collapse") {
2400
+ return ["overflow-x-auto"];
2113
2401
  }
2114
- return ['overflow-auto'];
2402
+ return ["overflow-auto"];
2115
2403
  }
2116
2404
  getVariantWrapperClasses() {
2117
- if (this.variant === 'interactive') {
2118
- return ['rounded-xl', 'border', 'border-border', 'bg-background'];
2405
+ if (this.variant === "interactive") {
2406
+ return ["rounded-xl", "border", "border-border", "bg-background"];
2119
2407
  }
2120
- if (this.variant === 'data') {
2121
- return ['rounded-md', 'border', 'border-border', 'bg-background'];
2408
+ if (this.variant === "data") {
2409
+ return ["rounded-md", "border", "border-border", "bg-background"];
2122
2410
  }
2123
2411
  return [];
2124
2412
  }
2125
2413
  getVariantTableClasses() {
2126
- if (this.variant === 'data') {
2414
+ if (this.variant === "data") {
2127
2415
  return [
2128
- 'border-collapse',
2129
- 'text-foreground',
2130
- '[&_thead_tr]:border-b',
2131
- '[&_thead_tr]:border-border',
2132
- '[&_tbody_tr]:border-b',
2133
- '[&_tbody_tr]:border-border',
2134
- '[&_tbody_tr:last-child]:border-b-0',
2135
- '[&_th]:h-10',
2136
- '[&_th]:px-2',
2137
- '[&_th]:text-left',
2138
- '[&_th]:align-middle',
2139
- '[&_th]:font-medium',
2140
- '[&_td]:p-2',
2141
- '[&_td]:align-middle'
2416
+ "border-collapse",
2417
+ "text-foreground",
2418
+ "[&_thead_tr]:border-b",
2419
+ "[&_thead_tr]:border-border",
2420
+ "[&_tbody_tr]:border-b",
2421
+ "[&_tbody_tr]:border-border",
2422
+ "[&_tbody_tr:last-child]:border-b-0",
2423
+ "[&_th]:h-10",
2424
+ "[&_th]:px-2",
2425
+ "[&_th]:text-left",
2426
+ "[&_th]:align-middle",
2427
+ "[&_th]:font-medium",
2428
+ "[&_td]:p-2",
2429
+ "[&_td]:align-middle",
2142
2430
  ];
2143
2431
  }
2144
- if (this.variant === 'interactive') {
2432
+ if (this.variant === "interactive") {
2145
2433
  return [
2146
- 'text-foreground',
2147
- '[&_thead]:sticky',
2148
- '[&_thead]:top-0',
2149
- '[&_thead]:z-10',
2150
- '[&_thead]:bg-muted/70',
2151
- '[&_thead_tr]:border-b',
2152
- '[&_thead_tr]:border-border',
2153
- '[&_th]:h-12',
2154
- '[&_th]:px-4',
2155
- '[&_th]:text-left',
2156
- '[&_th]:align-middle',
2157
- '[&_th]:text-sm',
2158
- '[&_th]:font-medium',
2159
- '[&_tbody_tr]:border-b',
2160
- '[&_tbody_tr]:border-border',
2161
- '[&_tbody_tr]:transition-colors',
2162
- '[&_tbody_tr:hover]:bg-muted/50',
2163
- '[&_tbody_tr:last-child]:border-b-0',
2164
- '[&_td]:h-14',
2165
- '[&_td]:px-4',
2166
- '[&_td]:align-middle',
2167
- '[&_td]:text-sm',
2168
- '[&_svg]:text-muted-foreground'
2434
+ "text-foreground",
2435
+ "[&_thead]:sticky",
2436
+ "[&_thead]:top-0",
2437
+ "[&_thead]:z-10",
2438
+ "[&_thead]:bg-muted/70",
2439
+ "[&_thead_tr]:border-b",
2440
+ "[&_thead_tr]:border-border",
2441
+ "[&_th]:h-12",
2442
+ "[&_th]:px-4",
2443
+ "[&_th]:text-left",
2444
+ "[&_th]:align-middle",
2445
+ "[&_th]:text-sm",
2446
+ "[&_th]:font-medium",
2447
+ "[&_tbody_tr]:border-b",
2448
+ "[&_tbody_tr]:border-border",
2449
+ "[&_tbody_tr]:transition-colors",
2450
+ "[&_tbody_tr:hover]:bg-muted/50",
2451
+ "[&_tbody_tr:last-child]:border-b-0",
2452
+ "[&_td]:h-14",
2453
+ "[&_td]:px-4",
2454
+ "[&_td]:align-middle",
2455
+ "[&_td]:text-sm",
2456
+ "[&_svg]:text-muted-foreground",
2169
2457
  ];
2170
2458
  }
2171
2459
  return [];
2172
2460
  }
2173
2461
  getCellClasses() {
2174
2462
  // Manejo responsive de whitespace
2175
- if (this.responsiveStrategy === 'scroll') {
2463
+ if (this.responsiveStrategy === "scroll") {
2176
2464
  // En scroll, permitir wrap en mobile, nowrap en desktop
2177
- return ['[&_td]:whitespace-normal', '[&_th]:whitespace-normal', 'sm:[&_td]:whitespace-nowrap', 'sm:[&_th]:whitespace-nowrap'];
2465
+ return [
2466
+ "[&_td]:whitespace-normal",
2467
+ "[&_th]:whitespace-normal",
2468
+ "sm:[&_td]:whitespace-nowrap",
2469
+ "sm:[&_th]:whitespace-nowrap",
2470
+ ];
2178
2471
  }
2179
- if (this.responsiveStrategy === 'wrap') {
2472
+ if (this.responsiveStrategy === "wrap") {
2180
2473
  // En wrap, siempre permitir wrap
2181
- return ['[&_td]:whitespace-normal', '[&_td]:break-words', '[&_th]:whitespace-normal'];
2474
+ return [
2475
+ "[&_td]:whitespace-normal",
2476
+ "[&_td]:break-words",
2477
+ "[&_th]:whitespace-normal",
2478
+ ];
2182
2479
  }
2183
2480
  // Default: nowrap (comportamiento anterior para backward compatibility)
2184
2481
  return [];
2185
2482
  }
2186
2483
  }
2187
2484
  PdmTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2188
- PdmTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmTableComponent, selector: "pdm-table", inputs: { variant: "variant", responsiveStrategy: "responsiveStrategy", className: "className", fullBleed: "fullBleed" }, ngImport: i0, template: "<div [ngClass]=\"wrapperClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table-container' : null\">\n <table #tableElement [ngClass]=\"tableClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table' : null\">\n <ng-content></ng-content>\n </table>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2485
+ PdmTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmTableComponent, selector: "pdm-table", inputs: { variant: "variant", responsiveStrategy: "responsiveStrategy", className: "className", fullBleed: "fullBleed" }, ngImport: i0, template: "<div [ngClass]=\"wrapperClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table-container' : null\">\n <table #tableElement [ngClass]=\"tableClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table' : null\">\n <ng-content></ng-content>\n </table>\n</div>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2189
2486
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTableComponent, decorators: [{
2190
2487
  type: Component,
2191
- args: [{ selector: 'pdm-table', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"wrapperClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table-container' : null\">\n <table #tableElement [ngClass]=\"tableClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table' : null\">\n <ng-content></ng-content>\n </table>\n</div>\n" }]
2488
+ args: [{ selector: "pdm-table", changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"wrapperClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table-container' : null\">\n <table #tableElement [ngClass]=\"tableClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table' : null\">\n <ng-content></ng-content>\n </table>\n</div>\n", styles: [":host{display:block}\n"] }]
2192
2489
  }], propDecorators: { variant: [{
2193
2490
  type: Input
2194
2491
  }], responsiveStrategy: [{
@@ -2434,10 +2731,10 @@ class PdmDataTableComponent {
2434
2731
  }
2435
2732
  }
2436
2733
  PdmDataTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDataTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2437
- PdmDataTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmDataTableComponent, selector: "pdm-data-table", inputs: { className: "className", columns: "columns", responsiveStrategy: "responsiveStrategy", selectable: "selectable", showActions: "showActions", showFilter: "showFilter", showPagination: "showPagination", showColumnSelector: "showColumnSelector", filterPlaceholder: "filterPlaceholder", columnsLabel: "columnsLabel", previousLabel: "previousLabel", nextLabel: "nextLabel", emptyLabel: "emptyLabel", rowsSelectedLabel: "rowsSelectedLabel", statusLabel: "statusLabel", emailLabel: "emailLabel", amountLabel: "amountLabel", rows: "rows", page: "page", pageSize: "pageSize", query: "query", filterFn: "filterFn" }, outputs: { queryChange: "queryChange", rowAction: "rowAction", pageChange: "pageChange", selectionChange: "selectionChange", columnSort: "columnSort" }, ngImport: i0, template: "<section [ngClass]=\"['flex w-full flex-col', className]\">\n <!-- Toolbar: Filtro + Selector de columnas -->\n <div *ngIf=\"showFilter || showColumnSelector\" class=\"flex w-full items-center justify-between gap-2 py-4\">\n <input\n *ngIf=\"showFilter\"\n type=\"text\"\n [placeholder]=\"filterPlaceholder\"\n [value]=\"query\"\n (input)=\"onQueryInput($event)\"\n class=\"h-9 flex-1 rounded-md border border-input bg-transparent px-3 py-1 text-sm text-foreground shadow-sm placeholder:text-muted-foreground outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\"\n />\n\n <button \n *ngIf=\"showColumnSelector\"\n type=\"button\" \n class=\"inline-flex h-9 appearance-none items-center gap-2 rounded-md border border-input bg-background px-3 py-2 text-sm font-medium text-foreground shadow-sm whitespace-nowrap\">\n <span>{{ columnsLabel }}</span>\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4 text-foreground\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M7 10L12 15L17 10\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n </div>\n\n <!-- Tabla con responsive -->\n <pdm-table \n variant=\"data\"\n [responsiveStrategy]=\"responsiveStrategy\"\n [fullBleed]=\"false\">\n <thead>\n <tr>\n <!-- Columna de selecci\u00F3n -->\n <th *ngIf=\"selectable\" class=\"w-10 px-2 py-2 text-left font-medium\">\n <input \n type=\"checkbox\" \n (change)=\"onToggleAll($event)\"\n class=\"h-4 w-4 rounded-sm border border-input\" \n />\n </th>\n\n <!-- Columnas din\u00E1micas -->\n <th \n *ngFor=\"let column of effectiveColumns\"\n [ngClass]=\"getHeaderClass(column)\"\n [ngStyle]=\"getColumnStyle(column)\">\n \n <!-- Header sortable -->\n <button \n *ngIf=\"column.sortable\"\n type=\"button\" \n (click)=\"onSort(column)\"\n class=\"inline-flex appearance-none items-center gap-1 rounded-sm border-0 bg-transparent px-3 py-2 text-sm hover:underline\">\n <span>{{ column.label }}</span>\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M8 6L4 10L8 14M16 18L20 14L16 10\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n\n <!-- Header no sortable -->\n <span *ngIf=\"!column.sortable\">{{ column.label }}</span>\n </th>\n\n <!-- Columna de acciones -->\n <th *ngIf=\"showActions\" class=\"w-10 px-2 py-2\"></th>\n </tr>\n </thead>\n\n <tbody>\n <!-- Filas con datos -->\n <tr *ngFor=\"let row of pagedRows\">\n <!-- Celda de selecci\u00F3n -->\n <td *ngIf=\"selectable\" class=\"px-2 py-2\">\n <input \n type=\"checkbox\" \n [checked]=\"isSelected(row)\" \n (change)=\"onToggleRow(row, $event)\" \n class=\"h-4 w-4 rounded-sm border border-input\" \n />\n </td>\n\n <!-- Celdas din\u00E1micas -->\n <td \n *ngFor=\"let column of effectiveColumns\"\n [ngClass]=\"getCellClass(column)\">\n \n <!-- Template personalizado si existe -->\n <ng-container *ngIf=\"column.cellTemplate; else defaultCell\">\n <ng-container \n *ngTemplateOutlet=\"column.cellTemplate; context: { $implicit: row, value: row[column.key] }\">\n </ng-container>\n </ng-container>\n\n <!-- Renderizado default -->\n <ng-template #defaultCell>\n {{ getCellValue(row, column) }}\n </ng-template>\n </td>\n\n <!-- Celda de acciones -->\n <td *ngIf=\"showActions\" class=\"px-2 py-2\">\n <button \n type=\"button\" \n class=\"inline-flex h-8 w-8 appearance-none items-center justify-center border-0 bg-transparent p-0 hover:text-foreground\" \n (click)=\"onAction(row)\">\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"12\" r=\"1.5\" fill=\"currentColor\"></circle>\n <circle cx=\"12\" cy=\"12\" r=\"1.5\" fill=\"currentColor\"></circle>\n <circle cx=\"18\" cy=\"12\" r=\"1.5\" fill=\"currentColor\"></circle>\n </svg>\n </button>\n </td>\n </tr>\n\n <!-- Fila vac\u00EDa -->\n <tr *ngIf=\"pagedRows.length === 0\">\n <td \n [attr.colspan]=\"effectiveColumns.length + (selectable ? 1 : 0) + (showActions ? 1 : 0)\" \n class=\"px-3 py-6 text-center text-sm text-muted-foreground\">\n {{ emptyLabel }}\n </td>\n </tr>\n </tbody>\n </pdm-table>\n\n <!-- Footer: Info + Paginaci\u00F3n -->\n <div *ngIf=\"showPagination || selectable\" class=\"flex w-full items-center gap-2 py-4 flex-wrap sm:flex-nowrap\">\n <p *ngIf=\"selectable\" class=\"m-0 flex-1 pr-2 text-sm text-muted-foreground whitespace-nowrap\">\n {{ selectedCount }} of {{ rows.length }} {{ rowsSelectedLabel }}\n </p>\n\n <div *ngIf=\"showPagination\" class=\"flex items-center gap-2 ml-auto\">\n <span class=\"text-sm text-muted-foreground whitespace-nowrap\">\n Page {{ page }} of {{ totalPages }}\n </span>\n <button \n type=\"button\" \n class=\"h-9 appearance-none rounded-md border border-input bg-background px-4 text-sm font-medium text-foreground shadow-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed\" \n [disabled]=\"page <= 1\" \n (click)=\"previous()\">\n {{ previousLabel }}\n </button>\n <button \n type=\"button\" \n class=\"h-9 appearance-none rounded-md border border-input bg-background px-4 text-sm font-medium text-foreground shadow-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed\" \n [disabled]=\"page >= totalPages\" \n (click)=\"next()\">\n {{ nextLabel }}\n </button>\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"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: PdmTableComponent, selector: "pdm-table", inputs: ["variant", "responsiveStrategy", "className", "fullBleed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2734
+ PdmDataTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmDataTableComponent, selector: "pdm-data-table", inputs: { className: "className", columns: "columns", responsiveStrategy: "responsiveStrategy", selectable: "selectable", showActions: "showActions", showFilter: "showFilter", showPagination: "showPagination", showColumnSelector: "showColumnSelector", filterPlaceholder: "filterPlaceholder", columnsLabel: "columnsLabel", previousLabel: "previousLabel", nextLabel: "nextLabel", emptyLabel: "emptyLabel", rowsSelectedLabel: "rowsSelectedLabel", statusLabel: "statusLabel", emailLabel: "emailLabel", amountLabel: "amountLabel", rows: "rows", page: "page", pageSize: "pageSize", query: "query", filterFn: "filterFn" }, outputs: { queryChange: "queryChange", rowAction: "rowAction", pageChange: "pageChange", selectionChange: "selectionChange", columnSort: "columnSort" }, ngImport: i0, template: "<section [ngClass]=\"['flex w-full flex-col', className]\">\n <!-- Toolbar: Filtro + Selector de columnas -->\n <div\n *ngIf=\"showFilter || showColumnSelector\"\n class=\"flex w-full flex-col gap-2 py-4 sm:flex-row sm:items-center\"\n >\n <input\n *ngIf=\"showFilter\"\n type=\"text\"\n [placeholder]=\"filterPlaceholder\"\n [value]=\"query\"\n (input)=\"onQueryInput($event)\"\n class=\"h-9 flex-1 rounded-md border border-input bg-transparent px-3 py-1 text-sm text-foreground shadow-sm placeholder:text-muted-foreground outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\"\n />\n\n <button\n *ngIf=\"showColumnSelector\"\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center gap-2 rounded-md border border-input bg-background px-3 py-2 text-sm font-medium text-foreground shadow-sm whitespace-nowrap\"\n >\n <span>{{ columnsLabel }}</span>\n <svg\n viewBox=\"0 0 24 24\"\n class=\"h-4 w-4 text-foreground\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M7 10L12 15L17 10\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n ></path>\n </svg>\n </button>\n </div>\n\n <!-- Tabla con responsive -->\n <pdm-table\n variant=\"data\"\n [responsiveStrategy]=\"responsiveStrategy\"\n [fullBleed]=\"false\"\n >\n <thead>\n <tr>\n <!-- Columna de selecci\u00F3n -->\n <th *ngIf=\"selectable\" class=\"w-10 px-2 py-2 text-left font-medium\">\n <input\n type=\"checkbox\"\n (change)=\"onToggleAll($event)\"\n class=\"h-4 w-4 rounded-sm border border-input\"\n />\n </th>\n\n <!-- Columnas din\u00E1micas -->\n <th\n *ngFor=\"let column of effectiveColumns\"\n [ngClass]=\"getHeaderClass(column)\"\n [ngStyle]=\"getColumnStyle(column)\"\n >\n <!-- Header sortable -->\n <button\n *ngIf=\"column.sortable\"\n type=\"button\"\n (click)=\"onSort(column)\"\n class=\"inline-flex appearance-none items-center gap-1 rounded-sm border-0 bg-transparent px-3 py-2 text-sm hover:underline\"\n >\n <span>{{ column.label }}</span>\n <svg\n viewBox=\"0 0 24 24\"\n class=\"h-4 w-4\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M8 6L4 10L8 14M16 18L20 14L16 10\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n ></path>\n </svg>\n </button>\n\n <!-- Header no sortable -->\n <span *ngIf=\"!column.sortable\">{{ column.label }}</span>\n </th>\n\n <!-- Columna de acciones -->\n <th *ngIf=\"showActions\" class=\"w-10 px-2 py-2\"></th>\n </tr>\n </thead>\n\n <tbody>\n <!-- Filas con datos -->\n <tr *ngFor=\"let row of pagedRows\">\n <!-- Celda de selecci\u00F3n -->\n <td *ngIf=\"selectable\" class=\"px-2 py-2\">\n <input\n type=\"checkbox\"\n [checked]=\"isSelected(row)\"\n (change)=\"onToggleRow(row, $event)\"\n class=\"h-4 w-4 rounded-sm border border-input\"\n />\n </td>\n\n <!-- Celdas din\u00E1micas -->\n <td\n *ngFor=\"let column of effectiveColumns\"\n [ngClass]=\"getCellClass(column)\"\n >\n <!-- Template personalizado si existe -->\n <ng-container *ngIf=\"column.cellTemplate; else defaultCell\">\n <ng-container\n *ngTemplateOutlet=\"\n column.cellTemplate;\n context: { $implicit: row, value: row[column.key] }\n \"\n >\n </ng-container>\n </ng-container>\n\n <!-- Renderizado default -->\n <ng-template #defaultCell>\n {{ getCellValue(row, column) }}\n </ng-template>\n </td>\n\n <!-- Celda de acciones -->\n <td *ngIf=\"showActions\" class=\"px-2 py-2\">\n <button\n type=\"button\"\n class=\"inline-flex h-8 w-8 appearance-none items-center justify-center border-0 bg-transparent p-0 hover:text-foreground\"\n (click)=\"onAction(row)\"\n >\n <svg\n viewBox=\"0 0 24 24\"\n class=\"h-4 w-4\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle cx=\"6\" cy=\"12\" r=\"1.5\" fill=\"currentColor\"></circle>\n <circle cx=\"12\" cy=\"12\" r=\"1.5\" fill=\"currentColor\"></circle>\n <circle cx=\"18\" cy=\"12\" r=\"1.5\" fill=\"currentColor\"></circle>\n </svg>\n </button>\n </td>\n </tr>\n\n <!-- Fila vac\u00EDa -->\n <tr *ngIf=\"pagedRows.length === 0\">\n <td\n [attr.colspan]=\"\n effectiveColumns.length +\n (selectable ? 1 : 0) +\n (showActions ? 1 : 0)\n \"\n class=\"px-3 py-6 text-center text-sm text-muted-foreground\"\n >\n {{ emptyLabel }}\n </td>\n </tr>\n </tbody>\n </pdm-table>\n\n <!-- Footer: Info + Paginaci\u00F3n -->\n <div\n *ngIf=\"showPagination || selectable\"\n class=\"flex w-full flex-wrap items-center gap-2 py-4 sm:flex-nowrap\"\n >\n <p\n *ngIf=\"selectable\"\n class=\"m-0 flex-1 pr-2 text-sm text-muted-foreground whitespace-nowrap\"\n >\n {{ selectedCount }} of {{ rows.length }} {{ rowsSelectedLabel }}\n </p>\n\n <div *ngIf=\"showPagination\" class=\"flex items-center gap-2 ml-auto\">\n <span class=\"text-sm text-muted-foreground whitespace-nowrap\">\n Page {{ page }} of {{ totalPages }}\n </span>\n <button\n type=\"button\"\n class=\"h-9 appearance-none rounded-md border border-input bg-background px-4 text-sm font-medium text-foreground shadow-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed\"\n [disabled]=\"page <= 1\"\n (click)=\"previous()\"\n >\n {{ previousLabel }}\n </button>\n <button\n type=\"button\"\n class=\"h-9 appearance-none rounded-md border border-input bg-background px-4 text-sm font-medium text-foreground shadow-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed\"\n [disabled]=\"page >= totalPages\"\n (click)=\"next()\"\n >\n {{ nextLabel }}\n </button>\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"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: PdmTableComponent, selector: "pdm-table", inputs: ["variant", "responsiveStrategy", "className", "fullBleed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2438
2735
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDataTableComponent, decorators: [{
2439
2736
  type: Component,
2440
- args: [{ selector: 'pdm-data-table', changeDetection: ChangeDetectionStrategy.OnPush, template: "<section [ngClass]=\"['flex w-full flex-col', className]\">\n <!-- Toolbar: Filtro + Selector de columnas -->\n <div *ngIf=\"showFilter || showColumnSelector\" class=\"flex w-full items-center justify-between gap-2 py-4\">\n <input\n *ngIf=\"showFilter\"\n type=\"text\"\n [placeholder]=\"filterPlaceholder\"\n [value]=\"query\"\n (input)=\"onQueryInput($event)\"\n class=\"h-9 flex-1 rounded-md border border-input bg-transparent px-3 py-1 text-sm text-foreground shadow-sm placeholder:text-muted-foreground outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\"\n />\n\n <button \n *ngIf=\"showColumnSelector\"\n type=\"button\" \n class=\"inline-flex h-9 appearance-none items-center gap-2 rounded-md border border-input bg-background px-3 py-2 text-sm font-medium text-foreground shadow-sm whitespace-nowrap\">\n <span>{{ columnsLabel }}</span>\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4 text-foreground\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M7 10L12 15L17 10\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n </div>\n\n <!-- Tabla con responsive -->\n <pdm-table \n variant=\"data\"\n [responsiveStrategy]=\"responsiveStrategy\"\n [fullBleed]=\"false\">\n <thead>\n <tr>\n <!-- Columna de selecci\u00F3n -->\n <th *ngIf=\"selectable\" class=\"w-10 px-2 py-2 text-left font-medium\">\n <input \n type=\"checkbox\" \n (change)=\"onToggleAll($event)\"\n class=\"h-4 w-4 rounded-sm border border-input\" \n />\n </th>\n\n <!-- Columnas din\u00E1micas -->\n <th \n *ngFor=\"let column of effectiveColumns\"\n [ngClass]=\"getHeaderClass(column)\"\n [ngStyle]=\"getColumnStyle(column)\">\n \n <!-- Header sortable -->\n <button \n *ngIf=\"column.sortable\"\n type=\"button\" \n (click)=\"onSort(column)\"\n class=\"inline-flex appearance-none items-center gap-1 rounded-sm border-0 bg-transparent px-3 py-2 text-sm hover:underline\">\n <span>{{ column.label }}</span>\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M8 6L4 10L8 14M16 18L20 14L16 10\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n\n <!-- Header no sortable -->\n <span *ngIf=\"!column.sortable\">{{ column.label }}</span>\n </th>\n\n <!-- Columna de acciones -->\n <th *ngIf=\"showActions\" class=\"w-10 px-2 py-2\"></th>\n </tr>\n </thead>\n\n <tbody>\n <!-- Filas con datos -->\n <tr *ngFor=\"let row of pagedRows\">\n <!-- Celda de selecci\u00F3n -->\n <td *ngIf=\"selectable\" class=\"px-2 py-2\">\n <input \n type=\"checkbox\" \n [checked]=\"isSelected(row)\" \n (change)=\"onToggleRow(row, $event)\" \n class=\"h-4 w-4 rounded-sm border border-input\" \n />\n </td>\n\n <!-- Celdas din\u00E1micas -->\n <td \n *ngFor=\"let column of effectiveColumns\"\n [ngClass]=\"getCellClass(column)\">\n \n <!-- Template personalizado si existe -->\n <ng-container *ngIf=\"column.cellTemplate; else defaultCell\">\n <ng-container \n *ngTemplateOutlet=\"column.cellTemplate; context: { $implicit: row, value: row[column.key] }\">\n </ng-container>\n </ng-container>\n\n <!-- Renderizado default -->\n <ng-template #defaultCell>\n {{ getCellValue(row, column) }}\n </ng-template>\n </td>\n\n <!-- Celda de acciones -->\n <td *ngIf=\"showActions\" class=\"px-2 py-2\">\n <button \n type=\"button\" \n class=\"inline-flex h-8 w-8 appearance-none items-center justify-center border-0 bg-transparent p-0 hover:text-foreground\" \n (click)=\"onAction(row)\">\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"12\" r=\"1.5\" fill=\"currentColor\"></circle>\n <circle cx=\"12\" cy=\"12\" r=\"1.5\" fill=\"currentColor\"></circle>\n <circle cx=\"18\" cy=\"12\" r=\"1.5\" fill=\"currentColor\"></circle>\n </svg>\n </button>\n </td>\n </tr>\n\n <!-- Fila vac\u00EDa -->\n <tr *ngIf=\"pagedRows.length === 0\">\n <td \n [attr.colspan]=\"effectiveColumns.length + (selectable ? 1 : 0) + (showActions ? 1 : 0)\" \n class=\"px-3 py-6 text-center text-sm text-muted-foreground\">\n {{ emptyLabel }}\n </td>\n </tr>\n </tbody>\n </pdm-table>\n\n <!-- Footer: Info + Paginaci\u00F3n -->\n <div *ngIf=\"showPagination || selectable\" class=\"flex w-full items-center gap-2 py-4 flex-wrap sm:flex-nowrap\">\n <p *ngIf=\"selectable\" class=\"m-0 flex-1 pr-2 text-sm text-muted-foreground whitespace-nowrap\">\n {{ selectedCount }} of {{ rows.length }} {{ rowsSelectedLabel }}\n </p>\n\n <div *ngIf=\"showPagination\" class=\"flex items-center gap-2 ml-auto\">\n <span class=\"text-sm text-muted-foreground whitespace-nowrap\">\n Page {{ page }} of {{ totalPages }}\n </span>\n <button \n type=\"button\" \n class=\"h-9 appearance-none rounded-md border border-input bg-background px-4 text-sm font-medium text-foreground shadow-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed\" \n [disabled]=\"page <= 1\" \n (click)=\"previous()\">\n {{ previousLabel }}\n </button>\n <button \n type=\"button\" \n class=\"h-9 appearance-none rounded-md border border-input bg-background px-4 text-sm font-medium text-foreground shadow-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed\" \n [disabled]=\"page >= totalPages\" \n (click)=\"next()\">\n {{ nextLabel }}\n </button>\n </div>\n </div>\n</section>\n" }]
2737
+ args: [{ selector: 'pdm-data-table', changeDetection: ChangeDetectionStrategy.OnPush, template: "<section [ngClass]=\"['flex w-full flex-col', className]\">\n <!-- Toolbar: Filtro + Selector de columnas -->\n <div\n *ngIf=\"showFilter || showColumnSelector\"\n class=\"flex w-full flex-col gap-2 py-4 sm:flex-row sm:items-center\"\n >\n <input\n *ngIf=\"showFilter\"\n type=\"text\"\n [placeholder]=\"filterPlaceholder\"\n [value]=\"query\"\n (input)=\"onQueryInput($event)\"\n class=\"h-9 flex-1 rounded-md border border-input bg-transparent px-3 py-1 text-sm text-foreground shadow-sm placeholder:text-muted-foreground outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\"\n />\n\n <button\n *ngIf=\"showColumnSelector\"\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center gap-2 rounded-md border border-input bg-background px-3 py-2 text-sm font-medium text-foreground shadow-sm whitespace-nowrap\"\n >\n <span>{{ columnsLabel }}</span>\n <svg\n viewBox=\"0 0 24 24\"\n class=\"h-4 w-4 text-foreground\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M7 10L12 15L17 10\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n ></path>\n </svg>\n </button>\n </div>\n\n <!-- Tabla con responsive -->\n <pdm-table\n variant=\"data\"\n [responsiveStrategy]=\"responsiveStrategy\"\n [fullBleed]=\"false\"\n >\n <thead>\n <tr>\n <!-- Columna de selecci\u00F3n -->\n <th *ngIf=\"selectable\" class=\"w-10 px-2 py-2 text-left font-medium\">\n <input\n type=\"checkbox\"\n (change)=\"onToggleAll($event)\"\n class=\"h-4 w-4 rounded-sm border border-input\"\n />\n </th>\n\n <!-- Columnas din\u00E1micas -->\n <th\n *ngFor=\"let column of effectiveColumns\"\n [ngClass]=\"getHeaderClass(column)\"\n [ngStyle]=\"getColumnStyle(column)\"\n >\n <!-- Header sortable -->\n <button\n *ngIf=\"column.sortable\"\n type=\"button\"\n (click)=\"onSort(column)\"\n class=\"inline-flex appearance-none items-center gap-1 rounded-sm border-0 bg-transparent px-3 py-2 text-sm hover:underline\"\n >\n <span>{{ column.label }}</span>\n <svg\n viewBox=\"0 0 24 24\"\n class=\"h-4 w-4\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M8 6L4 10L8 14M16 18L20 14L16 10\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n ></path>\n </svg>\n </button>\n\n <!-- Header no sortable -->\n <span *ngIf=\"!column.sortable\">{{ column.label }}</span>\n </th>\n\n <!-- Columna de acciones -->\n <th *ngIf=\"showActions\" class=\"w-10 px-2 py-2\"></th>\n </tr>\n </thead>\n\n <tbody>\n <!-- Filas con datos -->\n <tr *ngFor=\"let row of pagedRows\">\n <!-- Celda de selecci\u00F3n -->\n <td *ngIf=\"selectable\" class=\"px-2 py-2\">\n <input\n type=\"checkbox\"\n [checked]=\"isSelected(row)\"\n (change)=\"onToggleRow(row, $event)\"\n class=\"h-4 w-4 rounded-sm border border-input\"\n />\n </td>\n\n <!-- Celdas din\u00E1micas -->\n <td\n *ngFor=\"let column of effectiveColumns\"\n [ngClass]=\"getCellClass(column)\"\n >\n <!-- Template personalizado si existe -->\n <ng-container *ngIf=\"column.cellTemplate; else defaultCell\">\n <ng-container\n *ngTemplateOutlet=\"\n column.cellTemplate;\n context: { $implicit: row, value: row[column.key] }\n \"\n >\n </ng-container>\n </ng-container>\n\n <!-- Renderizado default -->\n <ng-template #defaultCell>\n {{ getCellValue(row, column) }}\n </ng-template>\n </td>\n\n <!-- Celda de acciones -->\n <td *ngIf=\"showActions\" class=\"px-2 py-2\">\n <button\n type=\"button\"\n class=\"inline-flex h-8 w-8 appearance-none items-center justify-center border-0 bg-transparent p-0 hover:text-foreground\"\n (click)=\"onAction(row)\"\n >\n <svg\n viewBox=\"0 0 24 24\"\n class=\"h-4 w-4\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle cx=\"6\" cy=\"12\" r=\"1.5\" fill=\"currentColor\"></circle>\n <circle cx=\"12\" cy=\"12\" r=\"1.5\" fill=\"currentColor\"></circle>\n <circle cx=\"18\" cy=\"12\" r=\"1.5\" fill=\"currentColor\"></circle>\n </svg>\n </button>\n </td>\n </tr>\n\n <!-- Fila vac\u00EDa -->\n <tr *ngIf=\"pagedRows.length === 0\">\n <td\n [attr.colspan]=\"\n effectiveColumns.length +\n (selectable ? 1 : 0) +\n (showActions ? 1 : 0)\n \"\n class=\"px-3 py-6 text-center text-sm text-muted-foreground\"\n >\n {{ emptyLabel }}\n </td>\n </tr>\n </tbody>\n </pdm-table>\n\n <!-- Footer: Info + Paginaci\u00F3n -->\n <div\n *ngIf=\"showPagination || selectable\"\n class=\"flex w-full flex-wrap items-center gap-2 py-4 sm:flex-nowrap\"\n >\n <p\n *ngIf=\"selectable\"\n class=\"m-0 flex-1 pr-2 text-sm text-muted-foreground whitespace-nowrap\"\n >\n {{ selectedCount }} of {{ rows.length }} {{ rowsSelectedLabel }}\n </p>\n\n <div *ngIf=\"showPagination\" class=\"flex items-center gap-2 ml-auto\">\n <span class=\"text-sm text-muted-foreground whitespace-nowrap\">\n Page {{ page }} of {{ totalPages }}\n </span>\n <button\n type=\"button\"\n class=\"h-9 appearance-none rounded-md border border-input bg-background px-4 text-sm font-medium text-foreground shadow-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed\"\n [disabled]=\"page <= 1\"\n (click)=\"previous()\"\n >\n {{ previousLabel }}\n </button>\n <button\n type=\"button\"\n class=\"h-9 appearance-none rounded-md border border-input bg-background px-4 text-sm font-medium text-foreground shadow-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed\"\n [disabled]=\"page >= totalPages\"\n (click)=\"next()\"\n >\n {{ nextLabel }}\n </button>\n </div>\n </div>\n</section>\n" }]
2441
2738
  }], propDecorators: { className: [{
2442
2739
  type: Input
2443
2740
  }], columns: [{
@@ -2570,8 +2867,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
2570
2867
 
2571
2868
  let nextDatePickerId = 0;
2572
2869
  class PdmDatePickerComponent {
2573
- constructor(elementRef, cdr, overlay, viewContainerRef) {
2574
- this.elementRef = elementRef;
2870
+ constructor(cdr, overlay, viewContainerRef) {
2575
2871
  this.cdr = cdr;
2576
2872
  this.overlay = overlay;
2577
2873
  this.viewContainerRef = viewContainerRef;
@@ -2582,21 +2878,21 @@ class PdmDatePickerComponent {
2582
2878
  this.triggerFocused = false;
2583
2879
  this.overlayRef = null;
2584
2880
  this.backdropSub = null;
2585
- this.id = '';
2586
- this.variant = 'single';
2587
- this.label = '';
2588
- this.labelClassName = '';
2589
- this.className = '';
2590
- this.triggerClassName = '';
2881
+ this.id = "";
2882
+ this.variant = "single";
2883
+ this.label = "";
2884
+ this.labelClassName = "";
2885
+ this.className = "";
2886
+ this.triggerClassName = "";
2591
2887
  /**
2592
2888
  * Additional CSS classes applied to the overlay panel.
2593
2889
  * Backward-compatible: mapped to `overlayOptions.panelClass` when `overlayOptions` is not set.
2594
2890
  * When both are supplied, `overlayOptions.panelClass` takes precedence.
2595
2891
  */
2596
- this.panelClassName = '';
2597
- this.placeholder = 'Pick a date';
2598
- this.rangePlaceholder = 'Pick a date range';
2599
- this.format = 'MMM d, yyyy';
2892
+ this.panelClassName = "";
2893
+ this.placeholder = "Pick a date";
2894
+ this.rangePlaceholder = "Pick a date range";
2895
+ this.format = "MMM d, yyyy";
2600
2896
  this.disabled = false;
2601
2897
  this.readonly = false;
2602
2898
  this.required = false;
@@ -2617,7 +2913,7 @@ class PdmDatePickerComponent {
2617
2913
  set open(value) {
2618
2914
  if (this._open === !!value)
2619
2915
  return;
2620
- if (!!value) {
2916
+ if (value) {
2621
2917
  this.openPanel();
2622
2918
  }
2623
2919
  else {
@@ -2638,7 +2934,7 @@ class PdmDatePickerComponent {
2638
2934
  this._rangeValue = value
2639
2935
  ? {
2640
2936
  start: this.normalizeDate(value.start),
2641
- end: this.normalizeDate(value.end)
2937
+ end: this.normalizeDate(value.end),
2642
2938
  }
2643
2939
  : null;
2644
2940
  this.cdr.markForCheck();
@@ -2650,7 +2946,7 @@ class PdmDatePickerComponent {
2650
2946
  this.destroyOverlay();
2651
2947
  }
2652
2948
  get resolvedVariant() {
2653
- return this.variant === 'range' ? 'range' : 'single';
2949
+ return this.variant === "range" ? "range" : "single";
2654
2950
  }
2655
2951
  get triggerId() {
2656
2952
  return this.id || `${this.instanceId}-trigger`;
@@ -2659,15 +2955,15 @@ class PdmDatePickerComponent {
2659
2955
  return `${this.id || this.instanceId}-panel`;
2660
2956
  }
2661
2957
  get hasSingleValue() {
2662
- return this.resolvedVariant === 'single' && !!this._value;
2958
+ return this.resolvedVariant === "single" && !!this._value;
2663
2959
  }
2664
2960
  get hasRangeValue() {
2665
2961
  var _a;
2666
- return this.resolvedVariant === 'range' && !!((_a = this._rangeValue) === null || _a === void 0 ? void 0 : _a.start);
2962
+ return this.resolvedVariant === "range" && !!((_a = this._rangeValue) === null || _a === void 0 ? void 0 : _a.start);
2667
2963
  }
2668
2964
  get displayText() {
2669
2965
  var _a, _b, _c, _d;
2670
- if (this.resolvedVariant === 'single') {
2966
+ if (this.resolvedVariant === "single") {
2671
2967
  return this._value ? this.formatDate(this._value) : this.placeholder;
2672
2968
  }
2673
2969
  const start = (_b = (_a = this._rangeValue) === null || _a === void 0 ? void 0 : _a.start) !== null && _b !== void 0 ? _b : null;
@@ -2681,29 +2977,29 @@ class PdmDatePickerComponent {
2681
2977
  return `${this.formatDate(start)} - ${this.formatDate(end)}`;
2682
2978
  }
2683
2979
  get textClasses() {
2684
- const hasValue = this.resolvedVariant === 'single' ? this.hasSingleValue : this.hasRangeValue;
2980
+ const hasValue = this.resolvedVariant === "single"
2981
+ ? this.hasSingleValue
2982
+ : this.hasRangeValue;
2685
2983
  return [
2686
- 'min-w-0 flex-1 truncate text-left text-sm leading-5',
2687
- hasValue ? 'text-foreground' : 'text-muted-foreground'
2984
+ "min-w-0 flex-1 truncate text-left text-sm leading-5",
2985
+ hasValue ? "text-foreground" : "text-muted-foreground",
2688
2986
  ];
2689
2987
  }
2690
2988
  get rootClasses() {
2691
2989
  return [
2692
- 'grid gap-2',
2693
- this.resolvedVariant === 'range' ? 'w-[280px]' : 'w-[197px]',
2694
- this.className
2990
+ "grid gap-2",
2991
+ this.resolvedVariant === "range" ? "w-[280px]" : "w-[197px]",
2992
+ this.className,
2695
2993
  ];
2696
2994
  }
2697
2995
  get triggerClasses() {
2698
2996
  const focusStyle = this._open || this.triggerFocused;
2699
2997
  return [
2700
- '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 relative flex w-full appearance-none items-center gap-2 overflow-hidden rounded-lg border bg-background px-3 py-[7.5px] text-left text-sm shadow-sm outline-none transition-colors',
2701
- 'min-h-[36px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50',
2702
- focusStyle
2703
- ? 'border-ring ring-2 ring-ring/50'
2704
- : '',
2705
- this.invalid ? 'border-destructive ring-destructive/20' : '',
2706
- this.triggerClassName
2998
+ "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 relative flex w-full appearance-none items-center gap-2 overflow-hidden rounded-lg border bg-background px-3 py-[7.5px] text-left text-sm shadow-sm outline-none transition-colors",
2999
+ "min-h-[36px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
3000
+ focusStyle ? "border-ring ring-2 ring-ring/50" : "",
3001
+ this.invalid ? "border-destructive ring-destructive/20" : "",
3002
+ this.triggerClassName,
2707
3003
  ];
2708
3004
  }
2709
3005
  toggleOpen() {
@@ -2735,16 +3031,22 @@ class PdmDatePickerComponent {
2735
3031
  this._rangeValue = value
2736
3032
  ? {
2737
3033
  start: this.normalizeDate(value.start),
2738
- end: this.normalizeDate(value.end)
3034
+ end: this.normalizeDate(value.end),
2739
3035
  }
2740
3036
  : null;
2741
3037
  this.rangeValueChange.emit(this._rangeValue
2742
3038
  ? {
2743
- start: this._rangeValue.start ? this.cloneDate(this._rangeValue.start) : null,
2744
- end: this._rangeValue.end ? this.cloneDate(this._rangeValue.end) : null
3039
+ start: this._rangeValue.start
3040
+ ? this.cloneDate(this._rangeValue.start)
3041
+ : null,
3042
+ end: this._rangeValue.end
3043
+ ? this.cloneDate(this._rangeValue.end)
3044
+ : null,
2745
3045
  }
2746
3046
  : null);
2747
- 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)) {
3047
+ if (this.closeOnSelect &&
3048
+ ((_a = this._rangeValue) === null || _a === void 0 ? void 0 : _a.start) &&
3049
+ ((_b = this._rangeValue) === null || _b === void 0 ? void 0 : _b.end)) {
2748
3050
  this.setOpen(false);
2749
3051
  return;
2750
3052
  }
@@ -2770,7 +3072,7 @@ class PdmDatePickerComponent {
2770
3072
  }
2771
3073
  }
2772
3074
  openPanel() {
2773
- var _a, _b, _c;
3075
+ var _a, _b;
2774
3076
  if (this.overlayRef)
2775
3077
  return;
2776
3078
  const triggerEl = (_a = this.triggerRef) === null || _a === void 0 ? void 0 : _a.nativeElement;
@@ -2780,14 +3082,21 @@ class PdmDatePickerComponent {
2780
3082
  this.openChange.emit(true);
2781
3083
  this.cdr.markForCheck();
2782
3084
  const positionStrategy = createFlexiblePositionStrategy(this.overlay, triggerEl, 8);
2783
- // Resolve panelClass: overlayOptions.panelClass wins; otherwise map panelClassName.
2784
- const resolvedPanelClass = (_c = (_b = this.overlayOptions) === null || _b === void 0 ? void 0 : _b.panelClass) !== null && _c !== void 0 ? _c : (this.panelClassName ? ['block', this.panelClassName] : ['block']);
3085
+ // CRITICAL: Use mergeOverlayPanelClass to ensure z-index is never lost.
3086
+ // Consumer classes are appended AFTER base z-index.
3087
+ const zIndexEnforced = mergeOverlayPanelClass(OVERLAY_BASE_Z_INDEX, this.panelClassName);
3088
+ // Resolve panelClass: overlayOptions.panelClass wins; otherwise use z-index enforced.
3089
+ const resolvedPanelClass = ((_b = this.overlayOptions) === null || _b === void 0 ? void 0 : _b.panelClass)
3090
+ ? mergeOverlayPanelClass(OVERLAY_BASE_Z_INDEX, this.overlayOptions.panelClass)
3091
+ : zIndexEnforced;
2785
3092
  this.overlayRef = this.overlay.create(Object.assign(Object.assign({ positionStrategy, scrollStrategy: this.overlay.scrollStrategies.reposition() }, this.overlayOptions), {
2786
- // panelClass always overrides last: it already merges panelClassName + overlayOptions.
3093
+ // panelClass always enforced last to preserve z-index.
2787
3094
  panelClass: resolvedPanelClass }));
2788
3095
  const portal = new TemplatePortal(this.panelTemplateRef, this.viewContainerRef);
2789
3096
  this.overlayRef.attach(portal);
2790
- this.backdropSub = this.overlayRef.outsidePointerEvents().subscribe((event) => {
3097
+ this.backdropSub = this.overlayRef
3098
+ .outsidePointerEvents()
3099
+ .subscribe((event) => {
2791
3100
  const target = event.target;
2792
3101
  if (!triggerEl.contains(target)) {
2793
3102
  this.closePanel();
@@ -2815,10 +3124,10 @@ class PdmDatePickerComponent {
2815
3124
  }
2816
3125
  formatDate(date) {
2817
3126
  try {
2818
- return format(date, this.format || 'MMM d, yyyy');
3127
+ return format(date, this.format || "MMM d, yyyy");
2819
3128
  }
2820
3129
  catch (_a) {
2821
- return format(date, 'MMM d, yyyy');
3130
+ return format(date, "MMM d, yyyy");
2822
3131
  }
2823
3132
  }
2824
3133
  normalizeDate(value) {
@@ -2831,17 +3140,17 @@ class PdmDatePickerComponent {
2831
3140
  return new Date(date.getFullYear(), date.getMonth(), date.getDate());
2832
3141
  }
2833
3142
  }
2834
- PdmDatePickerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDatePickerComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i1$2.Overlay }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component });
3143
+ PdmDatePickerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDatePickerComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.Overlay }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component });
2835
3144
  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", overlayOptions: "overlayOptions", 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()" } }, viewQueries: [{ propertyName: "triggerRef", first: true, predicate: ["triggerEl"], descendants: true }, { propertyName: "panelTemplateRef", first: true, predicate: ["panelTemplate"], 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 <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</div>\n\n<ng-template #panelTemplate>\n <div [id]=\"panelId\" 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</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"] }, { 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 });
2836
3145
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDatePickerComponent, decorators: [{
2837
3146
  type: Component,
2838
- 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 <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</div>\n\n<ng-template #panelTemplate>\n <div [id]=\"panelId\" 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</ng-template>\n" }]
2839
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i1$2.Overlay }, { type: i0.ViewContainerRef }]; }, propDecorators: { triggerRef: [{
3147
+ 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 <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</div>\n\n<ng-template #panelTemplate>\n <div [id]=\"panelId\" 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</ng-template>\n" }]
3148
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i1$1.Overlay }, { type: i0.ViewContainerRef }]; }, propDecorators: { triggerRef: [{
2840
3149
  type: ViewChild,
2841
- args: ['triggerEl']
3150
+ args: ["triggerEl"]
2842
3151
  }], panelTemplateRef: [{
2843
3152
  type: ViewChild,
2844
- args: ['panelTemplate']
3153
+ args: ["panelTemplate"]
2845
3154
  }], id: [{
2846
3155
  type: Input
2847
3156
  }], variant: [{
@@ -2904,7 +3213,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
2904
3213
  type: Input
2905
3214
  }], onEscape: [{
2906
3215
  type: HostListener,
2907
- args: ['document:keydown.escape']
3216
+ args: ["document:keydown.escape"]
2908
3217
  }] } });
2909
3218
 
2910
3219
  /**
@@ -2914,15 +3223,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
2914
3223
  * 1. base (z-0) - Elementos normales del DOM
2915
3224
  * 2. dropdown (z-10) - Selects, combobox, date-pickers
2916
3225
  * 3. sticky (z-20) - Headers, navigation bars
2917
- * 4. overlay (z-30) - Popovers, hover cards, context menus
3226
+ * 4. drawerBackdrop (z-30) - Backdrop de drawers
2918
3227
  * 5. drawer (z-40) - Sidebar drawer, sheets laterales
2919
- * 6. modal (z-50) - Dialogs, alert-dialogs
2920
- * 7. modal-backdrop (z-40) - Backdrop de modals
2921
- * 8. popover (z-60) - Tooltips, dropdowns DENTRO de modals
3228
+ * 6. modalBackdrop (z-40) - Backdrop de modals ( mismo nivel que drawer)
3229
+ * 7. modal (z-50) - Dialogs, alert-dialogs
3230
+ * 8. popover (z-[70]) - Tooltips, dropdowns DENTRO de modals
2922
3231
  * 9. toast (z-[100]) - Notificaciones que deben estar sobre TODO
2923
3232
  *
2924
3233
  * REGLA CRÍTICA:
2925
- * - Componentes overlay (select options, dropdown menu, tooltip) SIEMPRE z-60 o mayor
3234
+ * - Componentes overlay (select options, dropdown menu, tooltip) SIEMPRE z-[70] o mayor
2926
3235
  * - Esto permite que funcionen DENTRO de modals (z-50)
2927
3236
  * - Backdrop de modal debe ser z-40 para estar DEBAJO del contenido del modal (z-50)
2928
3237
  */
@@ -2930,57 +3239,53 @@ const Z_INDEX = {
2930
3239
  /**
2931
3240
  * Base - contenido normal del DOM
2932
3241
  */
2933
- base: 'z-0',
3242
+ base: "z-0",
2934
3243
  /**
2935
3244
  * Dropdown - Selects, combobox, date-pickers
2936
- * Debe estar SOBRE contenido normal pero BAJO modals
3245
+ * Debe estar SOBRE contenido normal pero BAJO overlays
2937
3246
  */
2938
- dropdown: 'z-10',
3247
+ dropdown: "z-10",
2939
3248
  /**
2940
3249
  * Sticky - Headers, navigation fija
2941
3250
  */
2942
- sticky: 'z-20',
2943
- /**
2944
- * Overlay - Popovers, hover cards, context menus
2945
- * Debe estar SOBRE sticky pero BAJO modals
2946
- */
2947
- overlay: 'z-30',
3251
+ sticky: "z-20",
2948
3252
  /**
2949
3253
  * Drawer backdrop - Backdrop de sidebar drawer
2950
- * Debe estar DEBAJO del drawer panel
3254
+ * Debe estar DEBAJO del drawer panel y DEBAJO de modals
2951
3255
  */
2952
- drawerBackdrop: 'z-40',
3256
+ drawerBackdrop: "z-30",
2953
3257
  /**
2954
3258
  * Drawer - Sidebar drawer, sheets laterales
2955
3259
  * Debe estar SOBRE su backdrop pero BAJO modals
2956
3260
  */
2957
- drawer: 'z-50',
3261
+ drawer: "z-40",
2958
3262
  /**
2959
3263
  * Modal backdrop - Backdrop de dialogs
2960
- * Debe estar SOBRE drawers pero DEBAJO del contenido del modal
3264
+ * Mismo nivel que drawer backdrop (z-40)
2961
3265
  */
2962
- modalBackdrop: 'z-50',
3266
+ modalBackdrop: "z-40",
2963
3267
  /**
2964
- * Modal - Dialogs, alert-dialogs, sheets
3268
+ * Modal - Dialogs, alert-dialogs
2965
3269
  * Debe estar SOBRE su backdrop
2966
3270
  */
2967
- modal: 'z-[60]',
3271
+ modal: "z-50",
2968
3272
  /**
2969
3273
  * Popover - Tooltips, dropdowns, selects options DENTRO de modals
2970
3274
  * CRÍTICO: Debe ser MAYOR que modal (z-50) para aparecer sobre modals
3275
+ * USAR SIEMPRE mergeOverlayPanelClass() para asegurar este valor
2971
3276
  */
2972
- popover: 'z-[70]',
3277
+ popover: "z-[70]",
2973
3278
  /**
2974
3279
  * Toast - Notificaciones globales
2975
3280
  * Debe estar sobre TODO
2976
3281
  */
2977
- toast: 'z-[100]'
3282
+ toast: "z-[100]",
2978
3283
  };
2979
3284
  /**
2980
3285
  * Helper para debugging z-index issues
2981
3286
  */
2982
3287
  function logZIndexStack(element) {
2983
- if (typeof window === 'undefined')
3288
+ if (typeof window === "undefined")
2984
3289
  return;
2985
3290
  let current = element;
2986
3291
  const stack = [];
@@ -2988,11 +3293,12 @@ function logZIndexStack(element) {
2988
3293
  const computed = window.getComputedStyle(current);
2989
3294
  const zIndex = computed.zIndex;
2990
3295
  const position = computed.position;
2991
- if (zIndex !== 'auto') {
3296
+ if (zIndex !== "auto") {
2992
3297
  stack.push({
2993
- element: current.tagName + (current.className ? `.${current.className.split(' ')[0]}` : ''),
3298
+ element: current.tagName +
3299
+ (current.className ? `.${current.className.split(" ")[0]}` : ""),
2994
3300
  zIndex,
2995
- position
3301
+ position,
2996
3302
  });
2997
3303
  }
2998
3304
  current = current.parentElement;
@@ -3023,7 +3329,7 @@ function logZIndexStack(element) {
3023
3329
  class PdmDialogComponent {
3024
3330
  constructor() {
3025
3331
  this.open = false;
3026
- this.variant = 'default';
3332
+ this.variant = "default";
3027
3333
  /**
3028
3334
  * Tamaño del dialog
3029
3335
  * - responsive: fullscreen mobile, modal desktop (recomendado)
@@ -3033,21 +3339,21 @@ class PdmDialogComponent {
3033
3339
  * - xl: 800px max
3034
3340
  * - desktop/mobile/mobile-fullscreen: legacy, deprecado
3035
3341
  */
3036
- this.size = 'responsive';
3037
- this.title = 'Edit profile';
3038
- this.description = '';
3342
+ this.size = "responsive";
3343
+ this.title = "Edit profile";
3344
+ this.description = "";
3039
3345
  this.closeOnBackdrop = true;
3040
3346
  this.closeOnEsc = true;
3041
3347
  this.showCloseButton = true;
3042
3348
  this.showHeader = true;
3043
3349
  this.showFooter = true;
3044
- this.primaryActionText = 'Save changes';
3045
- this.secondaryActionText = 'Cancel';
3046
- this.alignFooter = 'right';
3047
- this.headerClassName = '';
3048
- this.bodyClassName = '';
3049
- this.footerClassName = '';
3050
- this.className = '';
3350
+ this.primaryActionText = "Save changes";
3351
+ this.secondaryActionText = "Cancel";
3352
+ this.alignFooter = "right";
3353
+ this.headerClassName = "";
3354
+ this.bodyClassName = "";
3355
+ this.footerClassName = "";
3356
+ this.className = "";
3051
3357
  this.openChange = new EventEmitter();
3052
3358
  this.primaryAction = new EventEmitter();
3053
3359
  this.secondaryAction = new EventEmitter();
@@ -3073,131 +3379,148 @@ class PdmDialogComponent {
3073
3379
  }
3074
3380
  get panelClassName() {
3075
3381
  // Legacy sizes (backward compatibility)
3076
- if (this.size === 'desktop') {
3077
- return this.buildClasses(['max-w-[640px]', 'max-h-[calc(100vh-2rem)]', 'rounded-[10px]']);
3382
+ if (this.size === "desktop") {
3383
+ return this.buildPanelClasses([
3384
+ "max-w-[640px]",
3385
+ "max-h-[calc(100vh-2rem)]",
3386
+ "rounded-[10px]",
3387
+ ]);
3078
3388
  }
3079
- if (this.size === 'mobile') {
3080
- return this.buildClasses(['max-w-[320px]', 'min-h-[240px]', 'rounded-[10px]']);
3389
+ if (this.size === "mobile") {
3390
+ return this.buildPanelClasses([
3391
+ "max-w-[320px]",
3392
+ "min-h-[240px]",
3393
+ "rounded-[10px]",
3394
+ ]);
3081
3395
  }
3082
- if (this.size === 'mobile-fullscreen') {
3083
- return this.buildClasses(['max-w-[320px]', 'h-[min(100dvh,640px)]', 'rounded-none', 'sm:rounded-[10px]']);
3396
+ if (this.size === "mobile-fullscreen") {
3397
+ return this.buildPanelClasses([
3398
+ "max-w-[320px]",
3399
+ "h-[min(100dvh,640px)]",
3400
+ "rounded-none",
3401
+ "sm:rounded-[10px]",
3402
+ ]);
3084
3403
  }
3085
3404
  // New responsive mode (recomendado)
3086
- if (this.size === 'responsive') {
3087
- return this.buildClasses([
3405
+ if (this.size === "responsive") {
3406
+ return this.buildPanelClasses([
3088
3407
  // Mobile: fullscreen con bordes redondeados solo arriba
3089
- 'w-full',
3090
- 'h-full',
3091
- 'max-h-[100dvh]',
3092
- 'rounded-t-[10px]',
3093
- 'sm:rounded-[10px]',
3408
+ "w-full",
3409
+ "h-full",
3410
+ "max-h-[100dvh]",
3411
+ "rounded-t-[10px]",
3412
+ "sm:rounded-[10px]",
3094
3413
  // Desktop: modal centrado
3095
- 'sm:w-auto',
3096
- 'sm:h-auto',
3097
- 'sm:max-w-[640px]',
3098
- 'sm:max-h-[calc(100vh-4rem)]'
3414
+ "sm:w-auto",
3415
+ "sm:h-auto",
3416
+ "sm:max-w-[640px]",
3417
+ "sm:max-h-[calc(100vh-4rem)]",
3099
3418
  ]);
3100
3419
  }
3101
3420
  // New size options
3102
3421
  const sizeMap = {
3103
- sm: 'sm:max-w-[400px]',
3104
- md: 'sm:max-w-[500px]',
3105
- lg: 'sm:max-w-[640px]',
3106
- xl: 'sm:max-w-[800px]'
3422
+ sm: "sm:max-w-[400px]",
3423
+ md: "sm:max-w-[500px]",
3424
+ lg: "sm:max-w-[640px]",
3425
+ xl: "sm:max-w-[800px]",
3107
3426
  };
3108
3427
  const maxWidth = sizeMap[this.size] || sizeMap.lg;
3109
- return this.buildClasses([
3428
+ return this.buildPanelClasses([
3110
3429
  // Mobile: fullscreen
3111
- 'w-full',
3112
- 'h-full',
3113
- 'max-h-[100dvh]',
3114
- 'rounded-t-[10px]',
3430
+ "w-full",
3431
+ "h-full",
3432
+ "max-h-[100dvh]",
3433
+ "rounded-t-[10px]",
3115
3434
  // Desktop: modal
3116
- 'sm:rounded-[10px]',
3117
- 'sm:w-auto',
3118
- 'sm:h-auto',
3435
+ "sm:rounded-[10px]",
3436
+ "sm:w-auto",
3437
+ "sm:h-auto",
3119
3438
  maxWidth,
3120
- 'sm:max-h-[calc(100vh-4rem)]'
3439
+ "sm:max-h-[calc(100vh-4rem)]",
3121
3440
  ]);
3122
3441
  }
3123
- buildClasses(sizeClasses) {
3442
+ buildPanelClasses(sizeClasses) {
3124
3443
  const base = [
3125
- 'relative',
3444
+ "relative",
3126
3445
  Z_INDEX.modal,
3127
- 'flex',
3128
- 'flex-col',
3129
- 'border',
3130
- 'border-border',
3131
- 'bg-background',
3132
- 'text-foreground',
3133
- 'shadow-lg',
3134
- 'overflow-hidden',
3446
+ "flex",
3447
+ "flex-col",
3448
+ "border",
3449
+ "border-border",
3450
+ "bg-background",
3451
+ "text-foreground",
3452
+ "shadow-lg",
3453
+ "overflow-hidden",
3135
3454
  ...sizeClasses,
3136
- this.className
3455
+ this.className,
3137
3456
  ];
3138
- return base.filter(Boolean).join(' ');
3457
+ return base.filter(Boolean).join(" ");
3139
3458
  }
3140
3459
  get bodyWrapperClassName() {
3460
+ // min-h-0 is CRITICAL for flex child to shrink and allow internal scroll
3141
3461
  const base = [
3142
- 'flex-1',
3143
- 'overflow-y-auto',
3144
- 'px-4',
3145
- 'py-6',
3146
- 'sm:px-6',
3147
- this.bodyClassName
3462
+ "flex-1",
3463
+ "min-h-0",
3464
+ "overflow-y-auto",
3465
+ "px-4",
3466
+ "py-6",
3467
+ "sm:px-6",
3468
+ this.bodyClassName,
3148
3469
  ];
3149
- return base.filter(Boolean).join(' ');
3470
+ return base.filter(Boolean).join(" ");
3150
3471
  }
3151
3472
  get headerWrapperClassName() {
3152
3473
  const base = [
3153
- 'flex',
3154
- 'items-start',
3155
- 'justify-between',
3156
- 'gap-3',
3157
- 'p-4',
3158
- 'sm:p-6',
3159
- 'border-b',
3160
- 'border-border',
3161
- this.headerClassName
3474
+ "flex",
3475
+ "items-start",
3476
+ "justify-between",
3477
+ "gap-3",
3478
+ "p-4",
3479
+ "sm:p-6",
3480
+ "border-b",
3481
+ "border-border",
3482
+ this.headerClassName,
3162
3483
  ];
3163
- return base.filter(Boolean).join(' ');
3484
+ return base.filter(Boolean).join(" ");
3164
3485
  }
3165
3486
  get footerWrapperClassName() {
3166
- const effectiveAlign = this.alignFooter === 'right' && this.variant === 'custom-close' ? 'left' : this.alignFooter;
3487
+ const effectiveAlign = this.alignFooter === "right" && this.variant === "custom-close"
3488
+ ? "left"
3489
+ : this.alignFooter;
3167
3490
  const base = [
3168
- 'p-4',
3169
- 'sm:p-6',
3170
- 'border-t',
3171
- 'border-border',
3491
+ "p-4",
3492
+ "sm:p-6",
3493
+ "border-t",
3494
+ "border-border",
3172
3495
  // Mobile: siempre full-width
3173
- 'flex',
3174
- 'flex-col',
3175
- 'gap-2',
3496
+ "flex",
3497
+ "flex-col",
3498
+ "gap-2",
3176
3499
  // Desktop: según alignFooter
3177
- effectiveAlign === 'full-width'
3178
- ? 'sm:flex-col'
3179
- : 'sm:flex-row sm:items-center',
3180
- effectiveAlign === 'left' ? 'sm:justify-start' : '',
3181
- effectiveAlign === 'right' ? 'sm:justify-end' : '',
3182
- this.footerClassName
3500
+ effectiveAlign === "full-width"
3501
+ ? "sm:flex-col"
3502
+ : "sm:flex-row sm:items-center",
3503
+ effectiveAlign === "left" ? "sm:justify-start" : "",
3504
+ effectiveAlign === "right" ? "sm:justify-end" : "",
3505
+ this.footerClassName,
3183
3506
  ];
3184
- return base.filter(Boolean).join(' ');
3507
+ return base.filter(Boolean).join(" ");
3185
3508
  }
3186
3509
  get containerClassName() {
3187
- // Container con backdrop z-50
3510
+ // Container con backdrop z-40
3188
3511
  // Mobile: fullscreen desde el bottom
3189
3512
  // Desktop: centrado
3190
3513
  return responsive({
3191
3514
  default: `fixed inset-x-0 bottom-0 ${Z_INDEX.modalBackdrop} flex items-end justify-center`,
3192
- sm: `fixed inset-0 ${Z_INDEX.modalBackdrop} flex items-center justify-center p-4`
3515
+ sm: `fixed inset-0 ${Z_INDEX.modalBackdrop} flex items-center justify-center p-4`,
3193
3516
  });
3194
3517
  }
3195
3518
  }
3196
3519
  PdmDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3197
- PdmDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmDialogComponent, selector: "pdm-dialog", inputs: { open: "open", variant: "variant", size: "size", title: "title", description: "description", closeOnBackdrop: "closeOnBackdrop", closeOnEsc: "closeOnEsc", showCloseButton: "showCloseButton", showHeader: "showHeader", showFooter: "showFooter", primaryActionText: "primaryActionText", secondaryActionText: "secondaryActionText", alignFooter: "alignFooter", headerClassName: "headerClassName", bodyClassName: "bodyClassName", footerClassName: "footerClassName", className: "className" }, outputs: { openChange: "openChange", primaryAction: "primaryAction", secondaryAction: "secondaryAction" }, host: { listeners: { "document:keydown.escape": "onEsc()" } }, ngImport: i0, template: "<div *ngIf=\"open\" [ngClass]=\"containerClassName\">\n <!-- Backdrop -->\n <div class=\"absolute inset-0 bg-foreground/30 backdrop-blur-sm\" (click)=\"onBackdropClick()\"></div>\n \n <!-- Dialog Panel -->\n <section role=\"dialog\" aria-modal=\"true\" [ngClass]=\"panelClassName\">\n <!-- Header -->\n <div *ngIf=\"showHeader\" [ngClass]=\"headerWrapperClassName\">\n <div class=\"min-w-0 flex-1\">\n <h2 class=\"m-0 text-lg font-semibold leading-none tracking-tight text-foreground\">{{ title }}</h2>\n <p *ngIf=\"description\" class=\"m-0 mt-2 text-sm text-muted-foreground\">{{ description }}</p>\n </div>\n <button\n *ngIf=\"showCloseButton\"\n type=\"button\"\n class=\"inline-flex h-6 w-6 flex-shrink-0 appearance-none items-center justify-center rounded-sm border-0 bg-transparent p-0 text-foreground opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none\"\n (click)=\"close()\"\n aria-label=\"Close dialog\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 6L18 18M18 6L6 18\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"></path>\n </svg>\n </button>\n </div>\n\n <!-- Body -->\n <div [ngClass]=\"bodyWrapperClassName\">\n <ng-content></ng-content>\n </div>\n\n <!-- Footer -->\n <div *ngIf=\"showFooter\" [ngClass]=\"footerWrapperClassName\">\n <ng-container *ngIf=\"variant === 'custom-close'; else defaultActions\">\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-full appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm sm:w-auto\"\n (click)=\"onSecondaryAction()\"\n >\n {{ secondaryActionText }}\n </button>\n </ng-container>\n\n <ng-template #defaultActions>\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-full appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm sm:w-auto\"\n (click)=\"onSecondaryAction()\"\n >\n {{ secondaryActionText }}\n </button>\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-full appearance-none items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground shadow-sm sm:w-auto\"\n (click)=\"onPrimaryAction()\"\n >\n {{ primaryActionText }}\n </button>\n </ng-template>\n </div>\n </section>\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 });
3520
+ PdmDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmDialogComponent, selector: "pdm-dialog", inputs: { open: "open", variant: "variant", size: "size", title: "title", description: "description", closeOnBackdrop: "closeOnBackdrop", closeOnEsc: "closeOnEsc", showCloseButton: "showCloseButton", showHeader: "showHeader", showFooter: "showFooter", primaryActionText: "primaryActionText", secondaryActionText: "secondaryActionText", alignFooter: "alignFooter", headerClassName: "headerClassName", bodyClassName: "bodyClassName", footerClassName: "footerClassName", className: "className" }, outputs: { openChange: "openChange", primaryAction: "primaryAction", secondaryAction: "secondaryAction" }, host: { listeners: { "document:keydown.escape": "onEsc()" } }, ngImport: i0, template: "<div *ngIf=\"open\" [ngClass]=\"containerClassName\">\n <!-- Backdrop -->\n <div class=\"absolute inset-0 bg-foreground/30 backdrop-blur-sm\" (click)=\"onBackdropClick()\"></div>\n \n <!-- Dialog Panel -->\n <section role=\"dialog\" aria-modal=\"true\" [ngClass]=\"panelClassName\">\n <!-- Header -->\n <div *ngIf=\"showHeader\" [ngClass]=\"headerWrapperClassName\">\n <div class=\"min-w-0 flex-1\">\n <h2 class=\"m-0 text-lg font-semibold leading-none tracking-tight text-foreground\">{{ title }}</h2>\n <p *ngIf=\"description\" class=\"m-0 mt-2 text-sm text-muted-foreground\">{{ description }}</p>\n </div>\n <button\n *ngIf=\"showCloseButton\"\n type=\"button\"\n class=\"inline-flex h-6 w-6 flex-shrink-0 appearance-none items-center justify-center rounded-sm border-0 bg-transparent p-0 text-foreground opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none\"\n (click)=\"close()\"\n aria-label=\"Close dialog\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 6L18 18M18 6L6 18\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"></path>\n </svg>\n </button>\n </div>\n\n <!-- Body -->\n <div [ngClass]=\"bodyWrapperClassName\">\n <ng-content></ng-content>\n </div>\n\n <!-- Footer -->\n <div *ngIf=\"showFooter\" [ngClass]=\"footerWrapperClassName\">\n <ng-container *ngIf=\"variant === 'custom-close'; else defaultActions\">\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-full appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm sm:w-auto\"\n (click)=\"onSecondaryAction()\"\n >\n {{ secondaryActionText }}\n </button>\n </ng-container>\n\n <ng-template #defaultActions>\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-full appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm sm:w-auto\"\n (click)=\"onSecondaryAction()\"\n >\n {{ secondaryActionText }}\n </button>\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-full appearance-none items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground shadow-sm sm:w-auto\"\n (click)=\"onPrimaryAction()\"\n >\n {{ primaryActionText }}\n </button>\n </ng-template>\n </div>\n </section>\n</div>\n", styles: [":host{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 });
3198
3521
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDialogComponent, decorators: [{
3199
3522
  type: Component,
3200
- args: [{ selector: 'pdm-dialog', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div *ngIf=\"open\" [ngClass]=\"containerClassName\">\n <!-- Backdrop -->\n <div class=\"absolute inset-0 bg-foreground/30 backdrop-blur-sm\" (click)=\"onBackdropClick()\"></div>\n \n <!-- Dialog Panel -->\n <section role=\"dialog\" aria-modal=\"true\" [ngClass]=\"panelClassName\">\n <!-- Header -->\n <div *ngIf=\"showHeader\" [ngClass]=\"headerWrapperClassName\">\n <div class=\"min-w-0 flex-1\">\n <h2 class=\"m-0 text-lg font-semibold leading-none tracking-tight text-foreground\">{{ title }}</h2>\n <p *ngIf=\"description\" class=\"m-0 mt-2 text-sm text-muted-foreground\">{{ description }}</p>\n </div>\n <button\n *ngIf=\"showCloseButton\"\n type=\"button\"\n class=\"inline-flex h-6 w-6 flex-shrink-0 appearance-none items-center justify-center rounded-sm border-0 bg-transparent p-0 text-foreground opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none\"\n (click)=\"close()\"\n aria-label=\"Close dialog\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 6L18 18M18 6L6 18\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"></path>\n </svg>\n </button>\n </div>\n\n <!-- Body -->\n <div [ngClass]=\"bodyWrapperClassName\">\n <ng-content></ng-content>\n </div>\n\n <!-- Footer -->\n <div *ngIf=\"showFooter\" [ngClass]=\"footerWrapperClassName\">\n <ng-container *ngIf=\"variant === 'custom-close'; else defaultActions\">\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-full appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm sm:w-auto\"\n (click)=\"onSecondaryAction()\"\n >\n {{ secondaryActionText }}\n </button>\n </ng-container>\n\n <ng-template #defaultActions>\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-full appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm sm:w-auto\"\n (click)=\"onSecondaryAction()\"\n >\n {{ secondaryActionText }}\n </button>\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-full appearance-none items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground shadow-sm sm:w-auto\"\n (click)=\"onPrimaryAction()\"\n >\n {{ primaryActionText }}\n </button>\n </ng-template>\n </div>\n </section>\n</div>\n" }]
3523
+ args: [{ selector: "pdm-dialog", changeDetection: ChangeDetectionStrategy.OnPush, template: "<div *ngIf=\"open\" [ngClass]=\"containerClassName\">\n <!-- Backdrop -->\n <div class=\"absolute inset-0 bg-foreground/30 backdrop-blur-sm\" (click)=\"onBackdropClick()\"></div>\n \n <!-- Dialog Panel -->\n <section role=\"dialog\" aria-modal=\"true\" [ngClass]=\"panelClassName\">\n <!-- Header -->\n <div *ngIf=\"showHeader\" [ngClass]=\"headerWrapperClassName\">\n <div class=\"min-w-0 flex-1\">\n <h2 class=\"m-0 text-lg font-semibold leading-none tracking-tight text-foreground\">{{ title }}</h2>\n <p *ngIf=\"description\" class=\"m-0 mt-2 text-sm text-muted-foreground\">{{ description }}</p>\n </div>\n <button\n *ngIf=\"showCloseButton\"\n type=\"button\"\n class=\"inline-flex h-6 w-6 flex-shrink-0 appearance-none items-center justify-center rounded-sm border-0 bg-transparent p-0 text-foreground opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none\"\n (click)=\"close()\"\n aria-label=\"Close dialog\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 6L18 18M18 6L6 18\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"></path>\n </svg>\n </button>\n </div>\n\n <!-- Body -->\n <div [ngClass]=\"bodyWrapperClassName\">\n <ng-content></ng-content>\n </div>\n\n <!-- Footer -->\n <div *ngIf=\"showFooter\" [ngClass]=\"footerWrapperClassName\">\n <ng-container *ngIf=\"variant === 'custom-close'; else defaultActions\">\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-full appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm sm:w-auto\"\n (click)=\"onSecondaryAction()\"\n >\n {{ secondaryActionText }}\n </button>\n </ng-container>\n\n <ng-template #defaultActions>\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-full appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm sm:w-auto\"\n (click)=\"onSecondaryAction()\"\n >\n {{ secondaryActionText }}\n </button>\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-full appearance-none items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground shadow-sm sm:w-auto\"\n (click)=\"onPrimaryAction()\"\n >\n {{ primaryActionText }}\n </button>\n </ng-template>\n </div>\n </section>\n</div>\n", styles: [":host{display:block}\n"] }]
3201
3524
  }], propDecorators: { open: [{
3202
3525
  type: Input
3203
3526
  }], variant: [{
@@ -3240,7 +3563,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
3240
3563
  type: Output
3241
3564
  }], onEsc: [{
3242
3565
  type: HostListener,
3243
- args: ['document:keydown.escape']
3566
+ args: ["document:keydown.escape"]
3244
3567
  }] } });
3245
3568
 
3246
3569
  /**
@@ -3686,12 +4009,12 @@ class PdmDropdownMenuComponent {
3686
4009
  }
3687
4010
  }
3688
4011
  }
3689
- PdmDropdownMenuComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDropdownMenuComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i1$2.Overlay }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component });
4012
+ PdmDropdownMenuComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDropdownMenuComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i1$1.Overlay }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component });
3690
4013
  PdmDropdownMenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmDropdownMenuComponent, selector: "pdm-dropdown-menu", inputs: { triggerText: "triggerText", variant: "variant", items: "items", closeOnSelect: "closeOnSelect", className: "className", panelClassName: "panelClassName", overlayOptions: "overlayOptions" }, outputs: { itemSelect: "itemSelect", itemsChange: "itemsChange" }, host: { listeners: { "document:keydown.escape": "onEsc()" } }, viewQueries: [{ propertyName: "triggerRef", first: true, predicate: ["triggerEl"], descendants: true }, { propertyName: "panelTemplateRef", first: true, predicate: ["panelTemplate"], descendants: true }], ngImport: i0, template: "<button\n #triggerEl\n type=\"button\"\n [ngClass]=\"[\n 'inline-flex h-9 appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n className\n ]\"\n [attr.aria-expanded]=\"open\"\n (click)=\"toggle()\"\n>\n {{ triggerText }}\n</button>\n\n<ng-template #panelTemplate>\n <div\n class=\"min-w-32 overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md\"\n >\n <ng-container *ngFor=\"let item of resolvedItems\">\n <div *ngIf=\"item.type === 'separator'\" class=\"-mx-1 my-1 h-px bg-muted\"></div>\n\n <div\n *ngIf=\"item.type === 'label'\"\n [ngClass]=\"['px-2 py-1.5 text-sm font-semibold text-foreground', item.inset ? 'pl-8' : '']\"\n >\n {{ item.label }}\n </div>\n\n <button\n *ngIf=\"!item.type || item.type === 'item'\"\n type=\"button\"\n [disabled]=\"item.disabled\"\n [ngClass]=\"[\n 'relative flex w-full appearance-none cursor-default select-none items-center gap-2 rounded-sm border-0 bg-transparent px-2 py-1.5 text-left text-sm text-foreground outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground disabled:pointer-events-none disabled:opacity-50',\n item.inset ? 'pl-8' : ''\n ]\"\n (click)=\"select(item)\"\n >\n <span class=\"inline-flex h-4 w-4 shrink-0 items-center justify-center\">\n <svg\n *ngIf=\"item.checked\"\n viewBox=\"0 0 24 24\"\n class=\"h-3.5 w-3.5 text-foreground\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M5 12.5L9.2 16.7L19 7\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n <span *ngIf=\"item.radioSelected\" class=\"h-2 w-2 rounded-full bg-foreground\"></span>\n </span>\n <span class=\"min-w-0 flex-1 truncate\">{{ item.label }}</span>\n <span *ngIf=\"item.shortcut\" class=\"text-xs text-muted-foreground\">{{ item.shortcut }}</span>\n <span *ngIf=\"item.showChevron\" class=\"text-sm text-muted-foreground\">\u203A</span>\n </button>\n </ng-container>\n </div>\n</ng-template>\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 });
3691
4014
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDropdownMenuComponent, decorators: [{
3692
4015
  type: Component,
3693
4016
  args: [{ selector: 'pdm-dropdown-menu', changeDetection: ChangeDetectionStrategy.OnPush, template: "<button\n #triggerEl\n type=\"button\"\n [ngClass]=\"[\n 'inline-flex h-9 appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n className\n ]\"\n [attr.aria-expanded]=\"open\"\n (click)=\"toggle()\"\n>\n {{ triggerText }}\n</button>\n\n<ng-template #panelTemplate>\n <div\n class=\"min-w-32 overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md\"\n >\n <ng-container *ngFor=\"let item of resolvedItems\">\n <div *ngIf=\"item.type === 'separator'\" class=\"-mx-1 my-1 h-px bg-muted\"></div>\n\n <div\n *ngIf=\"item.type === 'label'\"\n [ngClass]=\"['px-2 py-1.5 text-sm font-semibold text-foreground', item.inset ? 'pl-8' : '']\"\n >\n {{ item.label }}\n </div>\n\n <button\n *ngIf=\"!item.type || item.type === 'item'\"\n type=\"button\"\n [disabled]=\"item.disabled\"\n [ngClass]=\"[\n 'relative flex w-full appearance-none cursor-default select-none items-center gap-2 rounded-sm border-0 bg-transparent px-2 py-1.5 text-left text-sm text-foreground outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground disabled:pointer-events-none disabled:opacity-50',\n item.inset ? 'pl-8' : ''\n ]\"\n (click)=\"select(item)\"\n >\n <span class=\"inline-flex h-4 w-4 shrink-0 items-center justify-center\">\n <svg\n *ngIf=\"item.checked\"\n viewBox=\"0 0 24 24\"\n class=\"h-3.5 w-3.5 text-foreground\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M5 12.5L9.2 16.7L19 7\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n <span *ngIf=\"item.radioSelected\" class=\"h-2 w-2 rounded-full bg-foreground\"></span>\n </span>\n <span class=\"min-w-0 flex-1 truncate\">{{ item.label }}</span>\n <span *ngIf=\"item.shortcut\" class=\"text-xs text-muted-foreground\">{{ item.shortcut }}</span>\n <span *ngIf=\"item.showChevron\" class=\"text-sm text-muted-foreground\">\u203A</span>\n </button>\n </ng-container>\n </div>\n</ng-template>\n" }]
3694
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i1$2.Overlay }, { type: i0.ViewContainerRef }]; }, propDecorators: { triggerText: [{
4017
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i1$1.Overlay }, { type: i0.ViewContainerRef }]; }, propDecorators: { triggerText: [{
3695
4018
  type: Input
3696
4019
  }], variant: [{
3697
4020
  type: Input
@@ -4048,35 +4371,178 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
4048
4371
  }] } });
4049
4372
 
4050
4373
  class PdmHoverCardComponent {
4051
- constructor() {
4052
- this.className = '';
4053
- this.panelClassName = '';
4054
- this.side = 'bottom';
4055
- this.align = 'start';
4374
+ constructor(overlay, viewContainerRef, elementRef, cdr) {
4375
+ this.overlay = overlay;
4376
+ this.viewContainerRef = viewContainerRef;
4377
+ this.elementRef = elementRef;
4378
+ this.cdr = cdr;
4379
+ this.className = "";
4380
+ this.panelClassName = "";
4381
+ this.side = "bottom";
4382
+ this.align = "start";
4056
4383
  this.panelWidth = 304;
4057
4384
  this.open = false;
4385
+ this.overlayRef = null;
4386
+ this.showTimeout = null;
4387
+ this.hideTimeout = null;
4058
4388
  }
4059
- get positionClass() {
4060
- const sideClassMap = {
4061
- top: 'bottom-full mb-2',
4062
- right: 'left-full ml-2',
4063
- bottom: 'top-full mt-2',
4064
- left: 'right-full mr-2'
4065
- };
4066
- const alignClassMap = {
4067
- start: this.side === 'top' || this.side === 'bottom' ? 'left-0' : 'top-0',
4068
- center: this.side === 'top' || this.side === 'bottom' ? 'left-1/2 -translate-x-1/2' : 'top-1/2 -translate-y-1/2',
4069
- end: this.side === 'top' || this.side === 'bottom' ? 'right-0' : 'bottom-0'
4389
+ ngOnDestroy() {
4390
+ this.clearTimeouts();
4391
+ this.destroyOverlay();
4392
+ }
4393
+ onMouseEnter() {
4394
+ this.clearTimeouts();
4395
+ this.showTimeout = setTimeout(() => this.show(), 150);
4396
+ }
4397
+ onMouseLeave() {
4398
+ this.clearTimeouts();
4399
+ this.hideTimeout = setTimeout(() => this.hide(), 150);
4400
+ }
4401
+ onFocusIn() {
4402
+ this.clearTimeouts();
4403
+ this.show();
4404
+ }
4405
+ onFocusOut() {
4406
+ this.clearTimeouts();
4407
+ this.hide();
4408
+ }
4409
+ clearTimeouts() {
4410
+ if (this.showTimeout) {
4411
+ clearTimeout(this.showTimeout);
4412
+ this.showTimeout = null;
4413
+ }
4414
+ if (this.hideTimeout) {
4415
+ clearTimeout(this.hideTimeout);
4416
+ this.hideTimeout = null;
4417
+ }
4418
+ }
4419
+ show() {
4420
+ if (this.open)
4421
+ return;
4422
+ this.open = true;
4423
+ this.cdr.markForCheck();
4424
+ this.createOverlay();
4425
+ }
4426
+ hide() {
4427
+ if (!this.open)
4428
+ return;
4429
+ this.open = false;
4430
+ this.cdr.markForCheck();
4431
+ this.destroyOverlay();
4432
+ }
4433
+ createOverlay() {
4434
+ if (this.overlayRef)
4435
+ return;
4436
+ const triggerEl = this.elementRef.nativeElement.querySelector("[pdmHoverTrigger]") ||
4437
+ this.elementRef.nativeElement;
4438
+ const positionStrategy = this.overlay
4439
+ .position()
4440
+ .flexibleConnectedTo(triggerEl)
4441
+ .withPositions(this.getPositionConfigs())
4442
+ .withFlexibleDimensions(false)
4443
+ .withPush(true);
4444
+ const panelClass = mergeOverlayPanelClass(OVERLAY_BASE_Z_INDEX, this.panelClassName);
4445
+ this.overlayRef = this.overlay.create({
4446
+ positionStrategy,
4447
+ panelClass,
4448
+ });
4449
+ const portal = new TemplatePortal(this.panelTemplateRef, this.viewContainerRef);
4450
+ this.overlayRef.attach(portal);
4451
+ }
4452
+ destroyOverlay() {
4453
+ if (this.overlayRef) {
4454
+ this.overlayRef.detach();
4455
+ this.overlayRef.dispose();
4456
+ this.overlayRef = null;
4457
+ }
4458
+ }
4459
+ getPositionConfigs() {
4460
+ // Map our side/align to CDK positions
4461
+ const configs = [];
4462
+ // Primary position based on side
4463
+ switch (this.side) {
4464
+ case "top":
4465
+ configs.push({
4466
+ originX: this.getAlignX(),
4467
+ originY: "top",
4468
+ overlayX: this.getAlignX(),
4469
+ overlayY: "bottom",
4470
+ offsetY: -8,
4471
+ });
4472
+ break;
4473
+ case "right":
4474
+ configs.push({
4475
+ originX: "end",
4476
+ originY: this.getAlignY(),
4477
+ overlayX: "start",
4478
+ overlayY: this.getAlignY(),
4479
+ offsetX: 8,
4480
+ });
4481
+ break;
4482
+ case "bottom":
4483
+ default:
4484
+ configs.push({
4485
+ originX: this.getAlignX(),
4486
+ originY: "bottom",
4487
+ overlayX: this.getAlignX(),
4488
+ overlayY: "top",
4489
+ offsetY: 8,
4490
+ });
4491
+ break;
4492
+ case "left":
4493
+ configs.push({
4494
+ originX: "start",
4495
+ originY: this.getAlignY(),
4496
+ overlayX: "end",
4497
+ overlayY: this.getAlignY(),
4498
+ offsetX: -8,
4499
+ });
4500
+ break;
4501
+ }
4502
+ // Add fallback positions
4503
+ switch (this.side) {
4504
+ case "top":
4505
+ case "bottom":
4506
+ configs.push({
4507
+ originX: "center",
4508
+ originY: this.side === "top" ? "top" : "bottom",
4509
+ overlayX: "center",
4510
+ overlayY: this.side === "top" ? "bottom" : "top",
4511
+ offsetY: this.side === "top" ? -8 : 8,
4512
+ });
4513
+ break;
4514
+ case "left":
4515
+ case "right":
4516
+ configs.push({
4517
+ originX: this.side === "left" ? "start" : "end",
4518
+ originY: "center",
4519
+ overlayX: this.side === "left" ? "end" : "start",
4520
+ overlayY: "center",
4521
+ offsetX: this.side === "left" ? -8 : 8,
4522
+ });
4523
+ break;
4524
+ }
4525
+ return configs;
4526
+ }
4527
+ getAlignX() {
4528
+ return this.align;
4529
+ }
4530
+ getAlignY() {
4531
+ // Map 'start'/'end' to 'top'/'bottom' for Y axis
4532
+ const alignMap = {
4533
+ start: "top",
4534
+ center: "center",
4535
+ end: "bottom",
4070
4536
  };
4071
- return `${sideClassMap[this.side]} ${alignClassMap[this.align]}`;
4537
+ return alignMap[this.align];
4072
4538
  }
4073
4539
  }
4074
- PdmHoverCardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmHoverCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4075
- PdmHoverCardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmHoverCardComponent, selector: "pdm-hover-card", inputs: { className: "className", panelClassName: "panelClassName", side: "side", align: "align", panelWidth: "panelWidth" }, ngImport: i0, template: "<div\n class=\"relative inline-flex\"\n [ngClass]=\"className\"\n (mouseenter)=\"open = true\"\n (mouseleave)=\"open = false\"\n (focusin)=\"open = true\"\n (focusout)=\"open = false\"\n>\n <div>\n <ng-content select=\"[pdmHoverTrigger]\"></ng-content>\n </div>\n\n <section\n *ngIf=\"open\"\n [style.width.px]=\"panelWidth\"\n [ngClass]=\"[\n 'absolute z-[70] rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md',\n positionClass,\n panelClassName\n ]\"\n >\n <ng-content select=\"[pdmHoverContent]\"></ng-content>\n </section>\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 });
4540
+ PdmHoverCardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmHoverCardComponent, deps: [{ token: i1$1.Overlay }, { token: i0.ViewContainerRef }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4541
+ PdmHoverCardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmHoverCardComponent, selector: "pdm-hover-card", inputs: { className: "className", panelClassName: "panelClassName", side: "side", align: "align", panelWidth: "panelWidth" }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()", "focusin": "onFocusIn()", "focusout": "onFocusOut()" } }, viewQueries: [{ propertyName: "panelTemplateRef", first: true, predicate: ["panelTemplate"], descendants: true }], ngImport: i0, template: "<div\n class=\"relative inline-flex\"\n [ngClass]=\"className\"\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n (focusin)=\"onFocusIn()\"\n (focusout)=\"onFocusOut()\"\n>\n <div>\n <ng-content select=\"[pdmHoverTrigger]\"></ng-content>\n </div>\n\n <!-- Template for CDK Overlay -->\n <ng-template #panelTemplate>\n <section\n [style.width.px]=\"panelWidth\"\n class=\"rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md\"\n >\n <ng-content select=\"[pdmHoverContent]\"></ng-content>\n </section>\n </ng-template>\n</div>\n", styles: [":host{display:inline-flex}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4076
4542
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmHoverCardComponent, decorators: [{
4077
4543
  type: Component,
4078
- args: [{ selector: 'pdm-hover-card', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"relative inline-flex\"\n [ngClass]=\"className\"\n (mouseenter)=\"open = true\"\n (mouseleave)=\"open = false\"\n (focusin)=\"open = true\"\n (focusout)=\"open = false\"\n>\n <div>\n <ng-content select=\"[pdmHoverTrigger]\"></ng-content>\n </div>\n\n <section\n *ngIf=\"open\"\n [style.width.px]=\"panelWidth\"\n [ngClass]=\"[\n 'absolute z-[70] rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md',\n positionClass,\n panelClassName\n ]\"\n >\n <ng-content select=\"[pdmHoverContent]\"></ng-content>\n </section>\n</div>\n" }]
4079
- }], propDecorators: { className: [{
4544
+ args: [{ selector: "pdm-hover-card", changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"relative inline-flex\"\n [ngClass]=\"className\"\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n (focusin)=\"onFocusIn()\"\n (focusout)=\"onFocusOut()\"\n>\n <div>\n <ng-content select=\"[pdmHoverTrigger]\"></ng-content>\n </div>\n\n <!-- Template for CDK Overlay -->\n <ng-template #panelTemplate>\n <section\n [style.width.px]=\"panelWidth\"\n class=\"rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md\"\n >\n <ng-content select=\"[pdmHoverContent]\"></ng-content>\n </section>\n </ng-template>\n</div>\n", styles: [":host{display:inline-flex}\n"] }]
4545
+ }], ctorParameters: function () { return [{ type: i1$1.Overlay }, { type: i0.ViewContainerRef }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { className: [{
4080
4546
  type: Input
4081
4547
  }], panelClassName: [{
4082
4548
  type: Input
@@ -4086,6 +4552,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
4086
4552
  type: Input
4087
4553
  }], panelWidth: [{
4088
4554
  type: Input
4555
+ }], panelTemplateRef: [{
4556
+ type: ViewChild,
4557
+ args: ["panelTemplate"]
4558
+ }], onMouseEnter: [{
4559
+ type: HostListener,
4560
+ args: ["mouseenter"]
4561
+ }], onMouseLeave: [{
4562
+ type: HostListener,
4563
+ args: ["mouseleave"]
4564
+ }], onFocusIn: [{
4565
+ type: HostListener,
4566
+ args: ["focusin"]
4567
+ }], onFocusOut: [{
4568
+ type: HostListener,
4569
+ args: ["focusout"]
4089
4570
  }] } });
4090
4571
 
4091
4572
  class PdmItemComponent {
@@ -4110,21 +4591,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
4110
4591
 
4111
4592
  class PdmInputComponent {
4112
4593
  constructor() {
4113
- this.id = '';
4114
- this.type = 'text';
4115
- this.value = '';
4116
- this.placeholder = '';
4594
+ this.id = "";
4595
+ this.type = "text";
4596
+ this.value = "";
4597
+ this.placeholder = "";
4117
4598
  this.disabled = false;
4118
4599
  this.readonly = false;
4119
4600
  this.required = false;
4120
4601
  this.invalid = false;
4121
- this.size = 'regular';
4122
- this.roundness = 'default';
4123
- this.className = '';
4124
- this.inputClassName = '';
4125
- this.label = '';
4126
- this.helperText = '';
4127
- this.errorText = '';
4602
+ this.size = "regular";
4603
+ this.roundness = "default";
4604
+ this.className = "";
4605
+ this.inputClassName = "";
4606
+ this.label = "";
4607
+ this.helperText = "";
4608
+ this.errorText = "";
4128
4609
  this.valueChange = new EventEmitter();
4129
4610
  this.blurred = new EventEmitter();
4130
4611
  }
@@ -4136,10 +4617,10 @@ class PdmInputComponent {
4136
4617
  }
4137
4618
  }
4138
4619
  PdmInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4139
- PdmInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmInputComponent, selector: "pdm-input", inputs: { id: "id", type: "type", value: "value", placeholder: "placeholder", disabled: "disabled", readonly: "readonly", required: "required", invalid: "invalid", size: "size", roundness: "roundness", className: "className", inputClassName: "inputClassName", label: "label", helperText: "helperText", errorText: "errorText" }, outputs: { valueChange: "valueChange", blurred: "blurred" }, ngImport: i0, template: "<div [ngClass]=\"['grid w-full gap-3', className]\">\n <label\n *ngIf=\"label\"\n [attr.for]=\"id\"\n [ngClass]=\"[\n 'text-sm font-medium leading-none',\n invalid ? 'text-destructive' : 'text-foreground'\n ]\"\n >{{ label }}</label\n >\n <input\n [id]=\"id\"\n [type]=\"type\"\n [value]=\"value\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [readonly]=\"readonly\"\n [required]=\"required\"\n [attr.aria-invalid]=\"invalid\"\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 aria-invalid:placeholder:text-destructive/70 placeholder:text-muted-foreground w-full min-w-0 rounded-lg border bg-transparent px-3 py-1 text-sm shadow-sm transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50',\n size === 'large' ? 'h-10 px-4 text-sm' : '',\n size === 'regular' ? 'h-9 px-3 text-sm' : '',\n size === 'small' ? 'h-8 px-2 text-sm' : '',\n size === 'mini' ? 'h-6 px-1.5 text-xs' : '',\n roundness === 'round' ? 'rounded-full' : 'rounded-lg',\n type === 'file' ? 'text-sm' : 'text-foreground',\n inputClassName,\n ]\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur($event)\"\n />\n <p *ngIf=\"!invalid && helperText\" class=\"m-0 text-sm text-muted-foreground\">\n {{ helperText }}\n </p>\n <p *ngIf=\"invalid && errorText\" class=\"m-0 text-sm text-destructive\">\n {{ errorText }}\n </p>\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 });
4620
+ PdmInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmInputComponent, selector: "pdm-input", inputs: { id: "id", type: "type", value: "value", placeholder: "placeholder", disabled: "disabled", readonly: "readonly", required: "required", invalid: "invalid", size: "size", roundness: "roundness", className: "className", inputClassName: "inputClassName", label: "label", helperText: "helperText", errorText: "errorText" }, outputs: { valueChange: "valueChange", blurred: "blurred" }, ngImport: i0, template: "<div [ngClass]=\"['grid w-full gap-3', className]\">\n <label\n *ngIf=\"label\"\n [attr.for]=\"id\"\n [ngClass]=\"[\n 'text-sm font-medium leading-none',\n invalid ? 'text-destructive' : 'text-foreground'\n ]\"\n >{{ label }}</label\n >\n <input\n [id]=\"id\"\n [type]=\"type\"\n [value]=\"value\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [readonly]=\"readonly\"\n [required]=\"required\"\n [attr.aria-invalid]=\"invalid\"\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 aria-invalid:placeholder:text-destructive/70 placeholder:text-muted-foreground w-full min-w-0 rounded-lg border bg-transparent px-3 py-1 text-sm shadow-sm transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50',\n size === 'large' ? 'h-10 px-4 text-sm' : '',\n size === 'regular' ? 'h-9 px-3 text-sm' : '',\n size === 'small' ? 'h-8 px-2 text-sm' : '',\n size === 'mini' ? 'h-6 px-1.5 text-xs' : '',\n roundness === 'round' ? 'rounded-full' : 'rounded-lg',\n type === 'file' ? 'text-sm' : 'text-foreground',\n inputClassName,\n ]\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur($event)\"\n />\n <p *ngIf=\"!invalid && helperText\" class=\"m-0 text-sm text-muted-foreground\">\n {{ helperText }}\n </p>\n <p *ngIf=\"invalid && errorText\" class=\"m-0 text-sm text-destructive\">\n {{ errorText }}\n </p>\n</div>\n", styles: [":host{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 });
4140
4621
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmInputComponent, decorators: [{
4141
4622
  type: Component,
4142
- args: [{ selector: 'pdm-input', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"['grid w-full gap-3', className]\">\n <label\n *ngIf=\"label\"\n [attr.for]=\"id\"\n [ngClass]=\"[\n 'text-sm font-medium leading-none',\n invalid ? 'text-destructive' : 'text-foreground'\n ]\"\n >{{ label }}</label\n >\n <input\n [id]=\"id\"\n [type]=\"type\"\n [value]=\"value\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [readonly]=\"readonly\"\n [required]=\"required\"\n [attr.aria-invalid]=\"invalid\"\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 aria-invalid:placeholder:text-destructive/70 placeholder:text-muted-foreground w-full min-w-0 rounded-lg border bg-transparent px-3 py-1 text-sm shadow-sm transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50',\n size === 'large' ? 'h-10 px-4 text-sm' : '',\n size === 'regular' ? 'h-9 px-3 text-sm' : '',\n size === 'small' ? 'h-8 px-2 text-sm' : '',\n size === 'mini' ? 'h-6 px-1.5 text-xs' : '',\n roundness === 'round' ? 'rounded-full' : 'rounded-lg',\n type === 'file' ? 'text-sm' : 'text-foreground',\n inputClassName,\n ]\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur($event)\"\n />\n <p *ngIf=\"!invalid && helperText\" class=\"m-0 text-sm text-muted-foreground\">\n {{ helperText }}\n </p>\n <p *ngIf=\"invalid && errorText\" class=\"m-0 text-sm text-destructive\">\n {{ errorText }}\n </p>\n</div>\n" }]
4623
+ args: [{ selector: "pdm-input", changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"['grid w-full gap-3', className]\">\n <label\n *ngIf=\"label\"\n [attr.for]=\"id\"\n [ngClass]=\"[\n 'text-sm font-medium leading-none',\n invalid ? 'text-destructive' : 'text-foreground'\n ]\"\n >{{ label }}</label\n >\n <input\n [id]=\"id\"\n [type]=\"type\"\n [value]=\"value\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [readonly]=\"readonly\"\n [required]=\"required\"\n [attr.aria-invalid]=\"invalid\"\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 aria-invalid:placeholder:text-destructive/70 placeholder:text-muted-foreground w-full min-w-0 rounded-lg border bg-transparent px-3 py-1 text-sm shadow-sm transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50',\n size === 'large' ? 'h-10 px-4 text-sm' : '',\n size === 'regular' ? 'h-9 px-3 text-sm' : '',\n size === 'small' ? 'h-8 px-2 text-sm' : '',\n size === 'mini' ? 'h-6 px-1.5 text-xs' : '',\n roundness === 'round' ? 'rounded-full' : 'rounded-lg',\n type === 'file' ? 'text-sm' : 'text-foreground',\n inputClassName,\n ]\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur($event)\"\n />\n <p *ngIf=\"!invalid && helperText\" class=\"m-0 text-sm text-muted-foreground\">\n {{ helperText }}\n </p>\n <p *ngIf=\"invalid && errorText\" class=\"m-0 text-sm text-destructive\">\n {{ errorText }}\n </p>\n</div>\n", styles: [":host{display:block}\n"] }]
4143
4624
  }], propDecorators: { id: [{
4144
4625
  type: Input
4145
4626
  }], type: [{
@@ -4253,18 +4734,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
4253
4734
 
4254
4735
  class PdmInputGroupComponent {
4255
4736
  constructor() {
4256
- this.id = '';
4257
- this.type = 'text';
4258
- this.value = '';
4259
- this.placeholder = '';
4737
+ this.id = "";
4738
+ this.type = "text";
4739
+ this.value = "";
4740
+ this.placeholder = "";
4260
4741
  this.disabled = false;
4261
4742
  this.invalid = false;
4262
- this.prefixText = '';
4263
- this.suffixText = '';
4264
- this.prefixIcon = '';
4265
- this.suffixIcon = '';
4266
- this.buttonText = '';
4267
- this.className = '';
4743
+ this.prefixText = "";
4744
+ this.suffixText = "";
4745
+ this.prefixIcon = "";
4746
+ this.suffixIcon = "";
4747
+ this.buttonText = "";
4748
+ this.className = "";
4268
4749
  this.valueChange = new EventEmitter();
4269
4750
  this.buttonClick = new EventEmitter();
4270
4751
  }
@@ -4276,10 +4757,10 @@ class PdmInputGroupComponent {
4276
4757
  }
4277
4758
  }
4278
4759
  PdmInputGroupComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmInputGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4279
- PdmInputGroupComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmInputGroupComponent, selector: "pdm-input-group", inputs: { id: "id", type: "type", value: "value", placeholder: "placeholder", disabled: "disabled", invalid: "invalid", prefixText: "prefixText", suffixText: "suffixText", prefixIcon: "prefixIcon", suffixIcon: "suffixIcon", buttonText: "buttonText", className: "className" }, outputs: { valueChange: "valueChange", buttonClick: "buttonClick" }, ngImport: i0, template: "<div\n [ngClass]=\"[\n 'flex w-full items-center gap-2',\n disabled ? 'opacity-50' : '',\n className\n ]\"\n>\n <div\n [ngClass]=\"[\n 'flex h-9 min-w-0 flex-1 items-center overflow-hidden rounded-md border border-input bg-transparent px-3 py-1 text-sm text-foreground shadow-sm transition-colors focus-within:border-ring focus-within:ring-2 focus-within:ring-ring/50',\n invalid ? 'border-destructive focus-within:ring-destructive' : '',\n disabled ? 'cursor-not-allowed' : ''\n ]\"\n >\n <div\n *ngIf=\"prefixText || prefixIcon\"\n class=\"inline-flex h-full shrink-0 items-center gap-2 pr-2 text-sm text-muted-foreground\"\n >\n <pdm-icon *ngIf=\"prefixIcon\" [name]=\"prefixIcon\" [size]=\"16\"></pdm-icon>\n <span *ngIf=\"prefixText\">{{ prefixText }}</span>\n <ng-content select=\"[pdmInputGroupPrefix]\"></ng-content>\n </div>\n\n <input\n [id]=\"id\"\n [type]=\"type\"\n [value]=\"value\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [attr.aria-invalid]=\"invalid\"\n [ngClass]=\"[\n 'h-full min-w-0 flex-1 border-0 bg-transparent p-0 text-sm text-foreground outline-none placeholder:text-muted-foreground aria-invalid:placeholder:text-destructive/70',\n type === 'file' ? 'text-sm file:mr-2 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground' : ''\n ]\"\n (input)=\"onInput($event)\"\n />\n\n <div\n *ngIf=\"!buttonText && (suffixText || suffixIcon)\"\n class=\"inline-flex h-full shrink-0 items-center gap-2 pl-2 text-sm text-muted-foreground\"\n >\n <pdm-icon *ngIf=\"suffixIcon\" [name]=\"suffixIcon\" [size]=\"16\"></pdm-icon>\n <span *ngIf=\"suffixText\" class=\"font-medium\">{{ suffixText }}</span>\n <ng-content select=\"[pdmInputGroupSuffix]\"></ng-content>\n </div>\n </div>\n\n <button\n *ngIf=\"buttonText\"\n type=\"button\"\n [disabled]=\"disabled\"\n class=\"inline-flex h-9 shrink-0 appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm outline-none transition-colors focus-visible:ring-2 focus-visible:ring-ring/50 disabled:cursor-not-allowed\"\n (click)=\"onButtonClick($event)\"\n >\n {{ buttonText }}\n </button>\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: PdmIconComponent, selector: "pdm-icon", inputs: ["name", "library", "assetUrl", "size", "strokeWidth", "className", "ariaLabel", "decorative"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4760
+ PdmInputGroupComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmInputGroupComponent, selector: "pdm-input-group", inputs: { id: "id", type: "type", value: "value", placeholder: "placeholder", disabled: "disabled", invalid: "invalid", prefixText: "prefixText", suffixText: "suffixText", prefixIcon: "prefixIcon", suffixIcon: "suffixIcon", buttonText: "buttonText", className: "className" }, outputs: { valueChange: "valueChange", buttonClick: "buttonClick" }, ngImport: i0, template: "<div\n [ngClass]=\"[\n 'flex w-full flex-col items-stretch gap-2 sm:flex-row sm:items-center',\n disabled ? 'opacity-50' : '',\n className,\n ]\"\n>\n <div\n [ngClass]=\"[\n 'flex h-9 min-w-0 flex-1 items-center overflow-hidden rounded-md border border-input bg-transparent px-3 py-1 text-sm text-foreground shadow-sm transition-colors focus-within:border-ring focus-within:ring-2 focus-within:ring-ring/50',\n invalid ? 'border-destructive focus-within:ring-destructive' : '',\n disabled ? 'cursor-not-allowed' : '',\n ]\"\n >\n <div\n *ngIf=\"prefixText || prefixIcon\"\n class=\"inline-flex h-full shrink-0 items-center gap-2 pr-2 text-sm text-muted-foreground\"\n >\n <pdm-icon *ngIf=\"prefixIcon\" [name]=\"prefixIcon\" [size]=\"16\"></pdm-icon>\n <span *ngIf=\"prefixText\">{{ prefixText }}</span>\n <ng-content select=\"[pdmInputGroupPrefix]\"></ng-content>\n </div>\n\n <input\n [id]=\"id\"\n [type]=\"type\"\n [value]=\"value\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [attr.aria-invalid]=\"invalid\"\n [ngClass]=\"[\n 'h-full min-w-0 flex-1 border-0 bg-transparent p-0 text-sm text-foreground outline-none placeholder:text-muted-foreground aria-invalid:placeholder:text-destructive/70',\n type === 'file'\n ? 'text-sm file:mr-2 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground'\n : '',\n ]\"\n (input)=\"onInput($event)\"\n />\n\n <div\n *ngIf=\"!buttonText && (suffixText || suffixIcon)\"\n class=\"inline-flex h-full shrink-0 items-center gap-2 pl-2 text-sm text-muted-foreground\"\n >\n <pdm-icon *ngIf=\"suffixIcon\" [name]=\"suffixIcon\" [size]=\"16\"></pdm-icon>\n <span *ngIf=\"suffixText\" class=\"font-medium\">{{ suffixText }}</span>\n <ng-content select=\"[pdmInputGroupSuffix]\"></ng-content>\n </div>\n </div>\n\n <button\n *ngIf=\"buttonText\"\n type=\"button\"\n [disabled]=\"disabled\"\n class=\"inline-flex h-9 w-full shrink-0 appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm outline-none transition-colors focus-visible:ring-2 focus-visible:ring-ring/50 disabled:cursor-not-allowed sm:w-auto\"\n (click)=\"onButtonClick($event)\"\n >\n {{ buttonText }}\n </button>\n</div>\n", styles: [":host{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"] }, { kind: "component", type: PdmIconComponent, selector: "pdm-icon", inputs: ["name", "library", "assetUrl", "size", "strokeWidth", "className", "ariaLabel", "decorative"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4280
4761
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmInputGroupComponent, decorators: [{
4281
4762
  type: Component,
4282
- args: [{ selector: 'pdm-input-group', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n [ngClass]=\"[\n 'flex w-full items-center gap-2',\n disabled ? 'opacity-50' : '',\n className\n ]\"\n>\n <div\n [ngClass]=\"[\n 'flex h-9 min-w-0 flex-1 items-center overflow-hidden rounded-md border border-input bg-transparent px-3 py-1 text-sm text-foreground shadow-sm transition-colors focus-within:border-ring focus-within:ring-2 focus-within:ring-ring/50',\n invalid ? 'border-destructive focus-within:ring-destructive' : '',\n disabled ? 'cursor-not-allowed' : ''\n ]\"\n >\n <div\n *ngIf=\"prefixText || prefixIcon\"\n class=\"inline-flex h-full shrink-0 items-center gap-2 pr-2 text-sm text-muted-foreground\"\n >\n <pdm-icon *ngIf=\"prefixIcon\" [name]=\"prefixIcon\" [size]=\"16\"></pdm-icon>\n <span *ngIf=\"prefixText\">{{ prefixText }}</span>\n <ng-content select=\"[pdmInputGroupPrefix]\"></ng-content>\n </div>\n\n <input\n [id]=\"id\"\n [type]=\"type\"\n [value]=\"value\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [attr.aria-invalid]=\"invalid\"\n [ngClass]=\"[\n 'h-full min-w-0 flex-1 border-0 bg-transparent p-0 text-sm text-foreground outline-none placeholder:text-muted-foreground aria-invalid:placeholder:text-destructive/70',\n type === 'file' ? 'text-sm file:mr-2 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground' : ''\n ]\"\n (input)=\"onInput($event)\"\n />\n\n <div\n *ngIf=\"!buttonText && (suffixText || suffixIcon)\"\n class=\"inline-flex h-full shrink-0 items-center gap-2 pl-2 text-sm text-muted-foreground\"\n >\n <pdm-icon *ngIf=\"suffixIcon\" [name]=\"suffixIcon\" [size]=\"16\"></pdm-icon>\n <span *ngIf=\"suffixText\" class=\"font-medium\">{{ suffixText }}</span>\n <ng-content select=\"[pdmInputGroupSuffix]\"></ng-content>\n </div>\n </div>\n\n <button\n *ngIf=\"buttonText\"\n type=\"button\"\n [disabled]=\"disabled\"\n class=\"inline-flex h-9 shrink-0 appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm outline-none transition-colors focus-visible:ring-2 focus-visible:ring-ring/50 disabled:cursor-not-allowed\"\n (click)=\"onButtonClick($event)\"\n >\n {{ buttonText }}\n </button>\n</div>\n" }]
4763
+ args: [{ selector: "pdm-input-group", changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n [ngClass]=\"[\n 'flex w-full flex-col items-stretch gap-2 sm:flex-row sm:items-center',\n disabled ? 'opacity-50' : '',\n className,\n ]\"\n>\n <div\n [ngClass]=\"[\n 'flex h-9 min-w-0 flex-1 items-center overflow-hidden rounded-md border border-input bg-transparent px-3 py-1 text-sm text-foreground shadow-sm transition-colors focus-within:border-ring focus-within:ring-2 focus-within:ring-ring/50',\n invalid ? 'border-destructive focus-within:ring-destructive' : '',\n disabled ? 'cursor-not-allowed' : '',\n ]\"\n >\n <div\n *ngIf=\"prefixText || prefixIcon\"\n class=\"inline-flex h-full shrink-0 items-center gap-2 pr-2 text-sm text-muted-foreground\"\n >\n <pdm-icon *ngIf=\"prefixIcon\" [name]=\"prefixIcon\" [size]=\"16\"></pdm-icon>\n <span *ngIf=\"prefixText\">{{ prefixText }}</span>\n <ng-content select=\"[pdmInputGroupPrefix]\"></ng-content>\n </div>\n\n <input\n [id]=\"id\"\n [type]=\"type\"\n [value]=\"value\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [attr.aria-invalid]=\"invalid\"\n [ngClass]=\"[\n 'h-full min-w-0 flex-1 border-0 bg-transparent p-0 text-sm text-foreground outline-none placeholder:text-muted-foreground aria-invalid:placeholder:text-destructive/70',\n type === 'file'\n ? 'text-sm file:mr-2 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground'\n : '',\n ]\"\n (input)=\"onInput($event)\"\n />\n\n <div\n *ngIf=\"!buttonText && (suffixText || suffixIcon)\"\n class=\"inline-flex h-full shrink-0 items-center gap-2 pl-2 text-sm text-muted-foreground\"\n >\n <pdm-icon *ngIf=\"suffixIcon\" [name]=\"suffixIcon\" [size]=\"16\"></pdm-icon>\n <span *ngIf=\"suffixText\" class=\"font-medium\">{{ suffixText }}</span>\n <ng-content select=\"[pdmInputGroupSuffix]\"></ng-content>\n </div>\n </div>\n\n <button\n *ngIf=\"buttonText\"\n type=\"button\"\n [disabled]=\"disabled\"\n class=\"inline-flex h-9 w-full shrink-0 appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm outline-none transition-colors focus-visible:ring-2 focus-visible:ring-ring/50 disabled:cursor-not-allowed sm:w-auto\"\n (click)=\"onButtonClick($event)\"\n >\n {{ buttonText }}\n </button>\n</div>\n", styles: [":host{display:block}\n"] }]
4283
4764
  }], propDecorators: { id: [{
4284
4765
  type: Input
4285
4766
  }], type: [{
@@ -4464,35 +4945,57 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
4464
4945
  }] } });
4465
4946
 
4466
4947
  class PdmMenubarComponent {
4467
- constructor(elementRef, cdr) {
4948
+ constructor(overlay, viewContainerRef, elementRef, cdr) {
4949
+ this.overlay = overlay;
4950
+ this.viewContainerRef = viewContainerRef;
4468
4951
  this.elementRef = elementRef;
4469
4952
  this.cdr = cdr;
4470
4953
  this.menus = [];
4471
- this.className = '';
4954
+ this.className = "";
4955
+ this.panelClassName = "";
4472
4956
  this.itemSelect = new EventEmitter();
4473
4957
  this.openIndex = -1;
4958
+ this.overlayRef = null;
4959
+ this.outsideClickSub = null;
4474
4960
  }
4475
- ngOnInit() {
4476
- this.boundPointerDown = (event) => this.onDocumentPointerDown(event);
4477
- document.addEventListener('pointerdown', this.boundPointerDown, { capture: true });
4478
- }
4961
+ ngOnInit() { }
4479
4962
  ngOnDestroy() {
4480
- if (this.boundPointerDown) {
4481
- document.removeEventListener('pointerdown', this.boundPointerDown, { capture: true });
4482
- }
4963
+ this.destroyOverlay();
4483
4964
  }
4484
- onEsc() {
4965
+ onDocumentClickOrEsc(event) {
4966
+ // Close on escape
4967
+ if (event.type === "keydown") {
4968
+ if (this.openIndex >= 0) {
4969
+ this.openIndex = -1;
4970
+ this.cdr.markForCheck();
4971
+ }
4972
+ return;
4973
+ }
4974
+ // Close on click outside
4485
4975
  if (this.openIndex >= 0) {
4486
- this.openIndex = -1;
4487
- this.cdr.markForCheck();
4976
+ const target = event.target;
4977
+ if (!this.elementRef.nativeElement.contains(target)) {
4978
+ this.openIndex = -1;
4979
+ this.cdr.markForCheck();
4980
+ }
4488
4981
  }
4489
4982
  }
4490
- toggle(index) {
4983
+ toggle(index, event) {
4984
+ event.stopPropagation();
4491
4985
  this.openIndex = this.openIndex === index ? -1 : index;
4986
+ this.cdr.markForCheck();
4987
+ if (this.openIndex >= 0) {
4988
+ this.createOverlay(event);
4989
+ }
4990
+ else {
4991
+ this.destroyOverlay();
4992
+ }
4492
4993
  }
4493
4994
  select(value) {
4494
4995
  this.itemSelect.emit(value);
4495
4996
  this.openIndex = -1;
4997
+ this.cdr.markForCheck();
4998
+ this.destroyOverlay();
4496
4999
  }
4497
5000
  selectItem(item) {
4498
5001
  if (item.disabled || !item.value) {
@@ -4500,32 +5003,83 @@ class PdmMenubarComponent {
4500
5003
  }
4501
5004
  this.select(item.value);
4502
5005
  }
4503
- onDocumentPointerDown(event) {
4504
- if (this.openIndex < 0)
4505
- return;
4506
- const target = event.target;
4507
- if (!target)
4508
- return;
4509
- if (!this.elementRef.nativeElement.contains(target)) {
5006
+ createOverlay(event) {
5007
+ this.destroyOverlay();
5008
+ const triggerEl = event.currentTarget;
5009
+ const positionStrategy = this.overlay
5010
+ .position()
5011
+ .flexibleConnectedTo(triggerEl)
5012
+ .withPositions(this.getPositionConfigs())
5013
+ .withFlexibleDimensions(false)
5014
+ .withPush(true);
5015
+ const panelClass = mergeOverlayPanelClass(OVERLAY_BASE_Z_INDEX, this.panelClassName);
5016
+ this.overlayRef = this.overlay.create({
5017
+ positionStrategy,
5018
+ panelClass,
5019
+ });
5020
+ const portal = new TemplatePortal(this.menuTemplateRef, this.viewContainerRef);
5021
+ this.overlayRef.attach(portal);
5022
+ // Close on click outside
5023
+ this.outsideClickSub = this.overlayRef
5024
+ .outsidePointerEvents()
5025
+ .subscribe(() => {
4510
5026
  this.openIndex = -1;
4511
5027
  this.cdr.markForCheck();
5028
+ this.destroyOverlay();
5029
+ });
5030
+ }
5031
+ destroyOverlay() {
5032
+ if (this.outsideClickSub) {
5033
+ this.outsideClickSub.unsubscribe();
5034
+ this.outsideClickSub = null;
5035
+ }
5036
+ if (this.overlayRef) {
5037
+ this.overlayRef.detach();
5038
+ this.overlayRef.dispose();
5039
+ this.overlayRef = null;
4512
5040
  }
4513
5041
  }
5042
+ getPositionConfigs() {
5043
+ return [
5044
+ {
5045
+ originX: "start",
5046
+ originY: "bottom",
5047
+ overlayX: "start",
5048
+ overlayY: "top",
5049
+ offsetY: 4,
5050
+ },
5051
+ {
5052
+ originX: "start",
5053
+ originY: "top",
5054
+ overlayX: "start",
5055
+ overlayY: "bottom",
5056
+ offsetY: -4,
5057
+ },
5058
+ ];
5059
+ }
4514
5060
  }
4515
- PdmMenubarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmMenubarComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4516
- PdmMenubarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmMenubarComponent, selector: "pdm-menubar", inputs: { menus: "menus", className: "className" }, outputs: { itemSelect: "itemSelect" }, host: { listeners: { "document:keydown.escape": "onEsc()" } }, ngImport: i0, template: "<nav role=\"menubar\" [ngClass]=\"['inline-flex h-9 items-center gap-0.5 rounded-md border border-border bg-background p-1 shadow-sm', className]\">\n <div *ngFor=\"let menu of menus; let i = index\" class=\"relative\">\n <button type=\"button\" class=\"inline-flex h-7 appearance-none items-center rounded-sm border-0 bg-transparent px-3 text-sm 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\" (click)=\"toggle(i)\">{{ menu.label }}</button>\n <div *ngIf=\"openIndex === i\" class=\"absolute left-0 top-full z-[70] mt-1 min-w-40 rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md sm:min-w-48\">\n <button\n *ngFor=\"let item of menu.items\"\n type=\"button\"\n [disabled]=\"item.disabled || !item.value\"\n class=\"relative flex w-full appearance-none cursor-default select-none items-center rounded-sm border-0 bg-transparent px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground disabled:pointer-events-none disabled:opacity-50\"\n (click)=\"selectItem(item)\"\n >\n {{ item.label }}\n </button>\n </div>\n </div>\n</nav>\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 });
5061
+ PdmMenubarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmMenubarComponent, deps: [{ token: i1$1.Overlay }, { token: i0.ViewContainerRef }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
5062
+ PdmMenubarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmMenubarComponent, selector: "pdm-menubar", inputs: { menus: "menus", className: "className", panelClassName: "panelClassName" }, outputs: { itemSelect: "itemSelect" }, host: { listeners: { "document:click": "onDocumentClickOrEsc()", "document:keydown.escape": "onDocumentClickOrEsc()" } }, viewQueries: [{ propertyName: "menuTemplateRef", first: true, predicate: ["menuTemplate"], descendants: true }], ngImport: i0, template: "<nav\n role=\"menubar\"\n [ngClass]=\"[\n 'inline-flex h-9 items-center gap-0.5 rounded-md border border-border bg-background p-1 shadow-sm',\n className,\n ]\"\n>\n <div *ngFor=\"let menu of menus; let i = index\" class=\"relative\">\n <button\n type=\"button\"\n class=\"inline-flex h-7 appearance-none items-center rounded-sm border-0 bg-transparent px-3 text-sm 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\"\n [attr.aria-expanded]=\"openIndex === i\"\n (click)=\"toggle(i, $event)\"\n >\n {{ menu.label }}\n </button>\n </div>\n\n <!-- Template for CDK Overlay -->\n <ng-template #menuTemplate>\n <div\n class=\"min-w-40 rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md sm:min-w-48\"\n >\n <button\n *ngFor=\"let item of menus[openIndex]?.items || []\"\n type=\"button\"\n [disabled]=\"item.disabled || !item.value\"\n class=\"relative flex w-full appearance-none cursor-default select-none items-center rounded-sm border-0 bg-transparent px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground disabled:pointer-events-none disabled:opacity-50\"\n (click)=\"selectItem(item)\"\n >\n {{ item.label }}\n </button>\n </div>\n </ng-template>\n</nav>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4517
5063
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmMenubarComponent, decorators: [{
4518
5064
  type: Component,
4519
- args: [{ selector: 'pdm-menubar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav role=\"menubar\" [ngClass]=\"['inline-flex h-9 items-center gap-0.5 rounded-md border border-border bg-background p-1 shadow-sm', className]\">\n <div *ngFor=\"let menu of menus; let i = index\" class=\"relative\">\n <button type=\"button\" class=\"inline-flex h-7 appearance-none items-center rounded-sm border-0 bg-transparent px-3 text-sm 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\" (click)=\"toggle(i)\">{{ menu.label }}</button>\n <div *ngIf=\"openIndex === i\" class=\"absolute left-0 top-full z-[70] mt-1 min-w-40 rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md sm:min-w-48\">\n <button\n *ngFor=\"let item of menu.items\"\n type=\"button\"\n [disabled]=\"item.disabled || !item.value\"\n class=\"relative flex w-full appearance-none cursor-default select-none items-center rounded-sm border-0 bg-transparent px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground disabled:pointer-events-none disabled:opacity-50\"\n (click)=\"selectItem(item)\"\n >\n {{ item.label }}\n </button>\n </div>\n </div>\n</nav>\n" }]
4520
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { menus: [{
5065
+ args: [{ selector: "pdm-menubar", changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav\n role=\"menubar\"\n [ngClass]=\"[\n 'inline-flex h-9 items-center gap-0.5 rounded-md border border-border bg-background p-1 shadow-sm',\n className,\n ]\"\n>\n <div *ngFor=\"let menu of menus; let i = index\" class=\"relative\">\n <button\n type=\"button\"\n class=\"inline-flex h-7 appearance-none items-center rounded-sm border-0 bg-transparent px-3 text-sm 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\"\n [attr.aria-expanded]=\"openIndex === i\"\n (click)=\"toggle(i, $event)\"\n >\n {{ menu.label }}\n </button>\n </div>\n\n <!-- Template for CDK Overlay -->\n <ng-template #menuTemplate>\n <div\n class=\"min-w-40 rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md sm:min-w-48\"\n >\n <button\n *ngFor=\"let item of menus[openIndex]?.items || []\"\n type=\"button\"\n [disabled]=\"item.disabled || !item.value\"\n class=\"relative flex w-full appearance-none cursor-default select-none items-center rounded-sm border-0 bg-transparent px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground disabled:pointer-events-none disabled:opacity-50\"\n (click)=\"selectItem(item)\"\n >\n {{ item.label }}\n </button>\n </div>\n </ng-template>\n</nav>\n", styles: [":host{display:block}\n"] }]
5066
+ }], ctorParameters: function () { return [{ type: i1$1.Overlay }, { type: i0.ViewContainerRef }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { menus: [{
4521
5067
  type: Input
4522
5068
  }], className: [{
4523
5069
  type: Input
5070
+ }], panelClassName: [{
5071
+ type: Input
4524
5072
  }], itemSelect: [{
4525
5073
  type: Output
4526
- }], onEsc: [{
5074
+ }], menuTemplateRef: [{
5075
+ type: ViewChild,
5076
+ args: ["menuTemplate"]
5077
+ }], onDocumentClickOrEsc: [{
4527
5078
  type: HostListener,
4528
- args: ['document:keydown.escape']
5079
+ args: ["document:click"]
5080
+ }, {
5081
+ type: HostListener,
5082
+ args: ["document:keydown.escape"]
4529
5083
  }] } });
4530
5084
 
4531
5085
  class PdmNativeSelectComponent {
@@ -4744,18 +5298,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
4744
5298
  }] } });
4745
5299
 
4746
5300
  class PdmSelectComponent {
4747
- constructor(elementRef, cdr, overlay, viewContainerRef) {
4748
- this.elementRef = elementRef;
5301
+ constructor(cdr, overlay, viewContainerRef) {
4749
5302
  this.cdr = cdr;
4750
5303
  this.overlay = overlay;
4751
5304
  this.viewContainerRef = viewContainerRef;
4752
- this.id = '';
4753
- this.value = '';
5305
+ this.id = "";
5306
+ this.value = "";
4754
5307
  this.options = [];
4755
5308
  this.disabled = false;
4756
5309
  this.invalid = false;
4757
- this.className = '';
4758
- this.placeholder = 'Select an option';
5310
+ this.className = "";
5311
+ this.placeholder = "Select an option";
4759
5312
  this.open = false;
4760
5313
  this.valueChange = new EventEmitter();
4761
5314
  this.overlayRef = null;
@@ -4778,7 +5331,7 @@ class PdmSelectComponent {
4778
5331
  return this.projectedOptions.map((d) => ({
4779
5332
  label: d.resolvedLabel,
4780
5333
  value: d.value,
4781
- disabled: d.disabled
5334
+ disabled: d.disabled,
4782
5335
  }));
4783
5336
  }
4784
5337
  return this.options;
@@ -4830,7 +5383,9 @@ class PdmSelectComponent {
4830
5383
  panelClass: [Z_INDEX.popover], positionStrategy, scrollStrategy: this.overlay.scrollStrategies.reposition(), width: triggerEl.offsetWidth }, this.overlayOptions));
4831
5384
  const portal = new TemplatePortal(this.panelTemplateRef, this.viewContainerRef);
4832
5385
  this.overlayRef.attach(portal);
4833
- this.backdropSub = this.overlayRef.outsidePointerEvents().subscribe((event) => {
5386
+ this.backdropSub = this.overlayRef
5387
+ .outsidePointerEvents()
5388
+ .subscribe((event) => {
4834
5389
  const target = event.target;
4835
5390
  if (!triggerEl.contains(target)) {
4836
5391
  this.closePanel();
@@ -4856,12 +5411,12 @@ class PdmSelectComponent {
4856
5411
  }
4857
5412
  }
4858
5413
  }
4859
- PdmSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmSelectComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i1$2.Overlay }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component });
4860
- 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", overlayOptions: "overlayOptions" }, outputs: { valueChange: "valueChange" }, host: { listeners: { "document:keydown.escape": "onEscape()" } }, queries: [{ propertyName: "projectedOptions", predicate: PdmSelectOptionDirective }], viewQueries: [{ propertyName: "triggerRef", first: true, predicate: ["triggerEl"], descendants: true }, { propertyName: "panelTemplateRef", first: true, predicate: ["panelTemplate"], 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 <!-- Hidden native select kept for screen-reader / form fallback -->\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 resolvedOptions\"\n [value]=\"option.value\"\n [disabled]=\"option.disabled\"\n >\n {{ option.label }}\n </option>\n </select>\n\n <!-- Slot for content-projected pdm-select-option elements (hidden from layout) -->\n <span class=\"hidden\">\n <ng-content select=\"pdm-select-option\"></ng-content>\n </span>\n</div>\n\n<ng-template #panelTemplate>\n <div\n role=\"listbox\"\n [attr.aria-labelledby]=\"id || null\"\n class=\"overflow-y-auto rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md max-h-96\"\n >\n <button\n *ngFor=\"let option of resolvedOptions\"\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</ng-template>\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 });
5414
+ PdmSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmSelectComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$1.Overlay }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component });
5415
+ 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", overlayOptions: "overlayOptions" }, outputs: { valueChange: "valueChange" }, host: { listeners: { "document:keydown.escape": "onEscape()" } }, queries: [{ propertyName: "projectedOptions", predicate: PdmSelectOptionDirective }], viewQueries: [{ propertyName: "triggerRef", first: true, predicate: ["triggerEl"], descendants: true }, { propertyName: "panelTemplateRef", first: true, predicate: ["panelTemplate"], 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 <!-- Hidden native select kept for screen-reader / form fallback -->\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 resolvedOptions\"\n [value]=\"option.value\"\n [disabled]=\"option.disabled\"\n >\n {{ option.label }}\n </option>\n </select>\n\n <!-- Slot for content-projected pdm-select-option elements (hidden from layout) -->\n <span class=\"hidden\">\n <ng-content select=\"pdm-select-option\"></ng-content>\n </span>\n</div>\n\n<ng-template #panelTemplate>\n <div\n role=\"listbox\"\n [attr.aria-labelledby]=\"id || null\"\n class=\"w-full overflow-y-auto rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md max-h-96\"\n >\n <button\n *ngFor=\"let option of resolvedOptions\"\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</ng-template>\n", styles: [":host{display:block}\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 });
4861
5416
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmSelectComponent, decorators: [{
4862
5417
  type: Component,
4863
- 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 <!-- Hidden native select kept for screen-reader / form fallback -->\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 resolvedOptions\"\n [value]=\"option.value\"\n [disabled]=\"option.disabled\"\n >\n {{ option.label }}\n </option>\n </select>\n\n <!-- Slot for content-projected pdm-select-option elements (hidden from layout) -->\n <span class=\"hidden\">\n <ng-content select=\"pdm-select-option\"></ng-content>\n </span>\n</div>\n\n<ng-template #panelTemplate>\n <div\n role=\"listbox\"\n [attr.aria-labelledby]=\"id || null\"\n class=\"overflow-y-auto rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md max-h-96\"\n >\n <button\n *ngFor=\"let option of resolvedOptions\"\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</ng-template>\n" }]
4864
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i1$2.Overlay }, { type: i0.ViewContainerRef }]; }, propDecorators: { id: [{
5418
+ 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 <!-- Hidden native select kept for screen-reader / form fallback -->\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 resolvedOptions\"\n [value]=\"option.value\"\n [disabled]=\"option.disabled\"\n >\n {{ option.label }}\n </option>\n </select>\n\n <!-- Slot for content-projected pdm-select-option elements (hidden from layout) -->\n <span class=\"hidden\">\n <ng-content select=\"pdm-select-option\"></ng-content>\n </span>\n</div>\n\n<ng-template #panelTemplate>\n <div\n role=\"listbox\"\n [attr.aria-labelledby]=\"id || null\"\n class=\"w-full overflow-y-auto rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md max-h-96\"\n >\n <button\n *ngFor=\"let option of resolvedOptions\"\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</ng-template>\n", styles: [":host{display:block}\n"] }]
5419
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i1$1.Overlay }, { type: i0.ViewContainerRef }]; }, propDecorators: { id: [{
4865
5420
  type: Input
4866
5421
  }], value: [{
4867
5422
  type: Input
@@ -4881,16 +5436,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
4881
5436
  type: Output
4882
5437
  }], triggerRef: [{
4883
5438
  type: ViewChild,
4884
- args: ['triggerEl']
5439
+ args: ["triggerEl"]
4885
5440
  }], panelTemplateRef: [{
4886
5441
  type: ViewChild,
4887
- args: ['panelTemplate']
5442
+ args: ["panelTemplate"]
4888
5443
  }], projectedOptions: [{
4889
5444
  type: ContentChildren,
4890
5445
  args: [PdmSelectOptionDirective]
4891
5446
  }], onEscape: [{
4892
5447
  type: HostListener,
4893
- args: ['document:keydown.escape']
5448
+ args: ["document:keydown.escape"]
4894
5449
  }] } });
4895
5450
 
4896
5451
  class PdmPaginationComponent {
@@ -4961,51 +5516,39 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
4961
5516
  }] } });
4962
5517
 
4963
5518
  class PdmPopoverComponent {
4964
- constructor(elementRef, cdr) {
5519
+ constructor(overlay, viewContainerRef, elementRef, cdr) {
5520
+ this.overlay = overlay;
5521
+ this.viewContainerRef = viewContainerRef;
4965
5522
  this.elementRef = elementRef;
4966
5523
  this.cdr = cdr;
4967
5524
  this._open = false;
4968
- this.triggerText = 'Open';
4969
- this.className = '';
4970
- this.panelClassName = '';
5525
+ this.triggerText = "Open";
5526
+ this.className = "";
5527
+ this.panelClassName = "";
4971
5528
  this.showTrigger = true;
4972
5529
  this.openChange = new EventEmitter();
4973
- this.panelPlacement = 'bottom';
4974
- }
4975
- ngOnInit() {
4976
- this.boundPointerDown = (event) => this.onDocumentPointerDown(event);
4977
- document.addEventListener('pointerdown', this.boundPointerDown, { capture: true });
5530
+ this.overlayRef = null;
5531
+ this.outsideClickSub = null;
4978
5532
  }
5533
+ ngOnInit() { }
4979
5534
  ngOnDestroy() {
4980
- if (this.boundPointerDown) {
4981
- document.removeEventListener('pointerdown', this.boundPointerDown, { capture: true });
4982
- }
5535
+ this.destroyOverlay();
4983
5536
  }
4984
5537
  set open(value) {
4985
- this._open = !!value;
4986
- if (this._open) {
4987
- this.schedulePanelPlacementUpdate();
5538
+ if (this._open === !!value)
5539
+ return;
5540
+ if (value) {
5541
+ this.openPanel();
4988
5542
  }
4989
5543
  else {
4990
- this.panelPlacement = 'bottom';
5544
+ this.closePanel();
4991
5545
  }
4992
- this.cdr.markForCheck();
4993
5546
  }
4994
5547
  get open() {
4995
5548
  return this._open;
4996
5549
  }
4997
- get panelClasses() {
4998
- const baseClasses = 'min-w-80 rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md';
4999
- return [
5000
- this.panelPlacement === 'top'
5001
- ? `absolute bottom-full left-0 ${Z_INDEX.popover} mb-2 ${baseClasses}`
5002
- : `absolute left-0 top-full ${Z_INDEX.popover} mt-2 ${baseClasses}`,
5003
- this.panelClassName
5004
- ];
5005
- }
5006
5550
  toggle() {
5007
5551
  this.open = !this.open;
5008
- this.openChange.emit(this.open);
5009
5552
  }
5010
5553
  onEsc() {
5011
5554
  if (this.open) {
@@ -5013,49 +5556,100 @@ class PdmPopoverComponent {
5013
5556
  this.openChange.emit(false);
5014
5557
  }
5015
5558
  }
5016
- onViewportChange() {
5017
- this.updatePanelPlacement();
5018
- }
5019
- onDocumentPointerDown(event) {
5020
- if (!this.open)
5559
+ openPanel() {
5560
+ var _a;
5561
+ if (this.overlayRef)
5021
5562
  return;
5022
- const target = event.target;
5023
- if (target && !this.elementRef.nativeElement.contains(target)) {
5563
+ const triggerEl = (_a = this.triggerRef) === null || _a === void 0 ? void 0 : _a.nativeElement;
5564
+ if (!triggerEl)
5565
+ return;
5566
+ this._open = true;
5567
+ this.openChange.emit(true);
5568
+ this.cdr.markForCheck();
5569
+ const positionStrategy = this.overlay
5570
+ .position()
5571
+ .flexibleConnectedTo(triggerEl)
5572
+ .withPositions(this.getPositionConfigs())
5573
+ .withFlexibleDimensions(false)
5574
+ .withPush(true);
5575
+ const panelClass = mergeOverlayPanelClass(OVERLAY_BASE_Z_INDEX, this.panelClassName);
5576
+ this.overlayRef = this.overlay.create({
5577
+ positionStrategy,
5578
+ panelClass,
5579
+ });
5580
+ const portal = new TemplatePortal(this.panelTemplateRef, this.viewContainerRef);
5581
+ this.overlayRef.attach(portal);
5582
+ // Close on click outside
5583
+ this.outsideClickSub = this.overlayRef
5584
+ .outsidePointerEvents()
5585
+ .subscribe(() => {
5024
5586
  this.open = false;
5025
5587
  this.openChange.emit(false);
5026
- }
5027
- }
5028
- schedulePanelPlacementUpdate() {
5029
- setTimeout(() => this.updatePanelPlacement());
5588
+ });
5589
+ this.cdr.markForCheck();
5030
5590
  }
5031
- updatePanelPlacement() {
5032
- var _a, _b, _c;
5033
- if (!this.open)
5034
- return;
5035
- const anchorEl = ((_a = this.triggerRef) === null || _a === void 0 ? void 0 : _a.nativeElement) || ((_b = this.anchorRef) === null || _b === void 0 ? void 0 : _b.nativeElement);
5036
- const panelEl = (_c = this.panelRef) === null || _c === void 0 ? void 0 : _c.nativeElement;
5037
- if (!anchorEl || !panelEl || typeof window === 'undefined') {
5591
+ closePanel() {
5592
+ if (!this.overlayRef)
5038
5593
  return;
5594
+ this._open = false;
5595
+ this.openChange.emit(false);
5596
+ this.cdr.markForCheck();
5597
+ this.destroyOverlay();
5598
+ }
5599
+ destroyOverlay() {
5600
+ if (this.outsideClickSub) {
5601
+ this.outsideClickSub.unsubscribe();
5602
+ this.outsideClickSub = null;
5039
5603
  }
5040
- const viewportHeight = window.innerHeight;
5041
- const gap = 8;
5042
- const anchorRect = anchorEl.getBoundingClientRect();
5043
- const panelHeight = panelEl.offsetHeight;
5044
- const spaceBelow = Math.max(0, viewportHeight - anchorRect.bottom - gap);
5045
- const spaceAbove = Math.max(0, anchorRect.top - gap);
5046
- const nextPlacement = spaceBelow < panelHeight && spaceAbove > spaceBelow ? 'top' : 'bottom';
5047
- if (this.panelPlacement !== nextPlacement) {
5048
- this.panelPlacement = nextPlacement;
5049
- this.cdr.markForCheck();
5604
+ if (this.overlayRef) {
5605
+ this.overlayRef.detach();
5606
+ this.overlayRef.dispose();
5607
+ this.overlayRef = null;
5050
5608
  }
5051
5609
  }
5610
+ getPositionConfigs() {
5611
+ return [
5612
+ // Bottom (default)
5613
+ {
5614
+ originX: "start",
5615
+ originY: "bottom",
5616
+ overlayX: "start",
5617
+ overlayY: "top",
5618
+ offsetY: 8,
5619
+ },
5620
+ // Top (fallback)
5621
+ {
5622
+ originX: "start",
5623
+ originY: "top",
5624
+ overlayX: "start",
5625
+ overlayY: "bottom",
5626
+ offsetY: -8,
5627
+ },
5628
+ // Right
5629
+ {
5630
+ originX: "end",
5631
+ originY: "bottom",
5632
+ overlayX: "start",
5633
+ overlayY: "top",
5634
+ offsetY: 8,
5635
+ },
5636
+ // Left
5637
+ {
5638
+ originX: "start",
5639
+ originY: "bottom",
5640
+ overlayX: "end",
5641
+ overlayY: "top",
5642
+ offsetY: 8,
5643
+ },
5644
+ ];
5645
+ }
5052
5646
  }
5053
- 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 });
5054
- 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()", "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 });
5647
+ PdmPopoverComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmPopoverComponent, deps: [{ token: i1$1.Overlay }, { token: i0.ViewContainerRef }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
5648
+ 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()" } }, viewQueries: [{ propertyName: "triggerRef", first: true, predicate: ["triggerEl"], descendants: true }, { propertyName: "panelTemplateRef", first: true, predicate: ["panelTemplate"], descendants: true }], ngImport: i0, template: "<div class=\"relative inline-block\" [ngClass]=\"className\">\n <button\n #triggerEl\n *ngIf=\"showTrigger\"\n type=\"button\"\n 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\"\n [attr.aria-expanded]=\"open\"\n [attr.aria-haspopup]=\"'dialog'\"\n (click)=\"toggle()\"\n >\n {{ triggerText }}\n </button>\n\n <!-- Trigger slot for custom trigger -->\n <ng-content select=\"[pdmPopoverTrigger]\"></ng-content>\n\n <!-- Template for CDK Overlay -->\n <ng-template #panelTemplate>\n <div\n class=\"min-w-80 rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md\"\n >\n <ng-content></ng-content>\n </div>\n </ng-template>\n</div>\n", styles: [":host{display:inline-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 });
5055
5649
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmPopoverComponent, decorators: [{
5056
5650
  type: Component,
5057
- 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" }]
5058
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { triggerText: [{
5651
+ args: [{ selector: "pdm-popover", changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"relative inline-block\" [ngClass]=\"className\">\n <button\n #triggerEl\n *ngIf=\"showTrigger\"\n type=\"button\"\n 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\"\n [attr.aria-expanded]=\"open\"\n [attr.aria-haspopup]=\"'dialog'\"\n (click)=\"toggle()\"\n >\n {{ triggerText }}\n </button>\n\n <!-- Trigger slot for custom trigger -->\n <ng-content select=\"[pdmPopoverTrigger]\"></ng-content>\n\n <!-- Template for CDK Overlay -->\n <ng-template #panelTemplate>\n <div\n class=\"min-w-80 rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md\"\n >\n <ng-content></ng-content>\n </div>\n </ng-template>\n</div>\n", styles: [":host{display:inline-block}\n"] }]
5652
+ }], ctorParameters: function () { return [{ type: i1$1.Overlay }, { type: i0.ViewContainerRef }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { triggerText: [{
5059
5653
  type: Input
5060
5654
  }], className: [{
5061
5655
  type: Input
@@ -5065,26 +5659,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
5065
5659
  type: Input
5066
5660
  }], openChange: [{
5067
5661
  type: Output
5068
- }], anchorRef: [{
5069
- type: ViewChild,
5070
- args: ['anchorEl']
5071
5662
  }], triggerRef: [{
5072
5663
  type: ViewChild,
5073
- args: ['triggerEl']
5074
- }], panelRef: [{
5664
+ args: ["triggerEl"]
5665
+ }], panelTemplateRef: [{
5075
5666
  type: ViewChild,
5076
- args: ['panelEl']
5667
+ args: ["panelTemplate"]
5077
5668
  }], open: [{
5078
5669
  type: Input
5079
5670
  }], onEsc: [{
5080
5671
  type: HostListener,
5081
- args: ['document:keydown.escape']
5082
- }], onViewportChange: [{
5083
- type: HostListener,
5084
- args: ['window:resize']
5085
- }, {
5086
- type: HostListener,
5087
- args: ['window:scroll']
5672
+ args: ["document:keydown.escape"]
5088
5673
  }] } });
5089
5674
 
5090
5675
  class PdmProgressComponent {
@@ -5536,8 +6121,8 @@ class PdmTabsComponent {
5536
6121
  constructor(cdr) {
5537
6122
  this.cdr = cdr;
5538
6123
  this.items = [];
5539
- this.value = '';
5540
- this.className = '';
6124
+ this.value = "";
6125
+ this.className = "";
5541
6126
  this.valueChange = new EventEmitter();
5542
6127
  }
5543
6128
  select(item) {
@@ -5549,10 +6134,10 @@ class PdmTabsComponent {
5549
6134
  }
5550
6135
  }
5551
6136
  PdmTabsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTabsComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
5552
- PdmTabsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmTabsComponent, selector: "pdm-tabs", inputs: { items: "items", value: "value", className: "className" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div [ngClass]=\"['w-full', className]\">\n <div\n role=\"tablist\"\n class=\"inline-flex h-8 w-full items-center overflow-x-auto scrollbar-thin rounded-lg bg-muted p-[3px] text-muted-foreground md:w-fit\"\n >\n <button\n *ngFor=\"let item of items\"\n role=\"tab\"\n [attr.aria-selected]=\"value === item.value\"\n [disabled]=\"item.disabled\"\n [ngClass]=\"[\n 'relative inline-flex h-[calc(100%-1px)] appearance-none flex-1 items-center justify-center gap-1.5 whitespace-nowrap rounded-md border border-transparent px-3 py-0.5 text-sm font-medium transition-all focus-visible:border-ring focus-visible:outline-none focus-visible:outline-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 md:flex-initial md:px-4',\n value === item.value ? 'bg-background text-foreground shadow-sm' : 'bg-transparent text-muted-foreground'\n ]\"\n (click)=\"select(item)\"\n type=\"button\"\n >\n {{ item.label }}\n </button>\n </div>\n <div class=\"mt-4\">\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.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
6137
+ PdmTabsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmTabsComponent, selector: "pdm-tabs", inputs: { items: "items", value: "value", className: "className" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div [ngClass]=\"['w-full', className]\">\n <div\n role=\"tablist\"\n class=\"inline-flex h-8 w-full items-center overflow-x-auto scrollbar-thin rounded-lg bg-muted p-[3px] text-muted-foreground md:w-fit\"\n >\n <button\n *ngFor=\"let item of items\"\n role=\"tab\"\n [attr.aria-selected]=\"value === item.value\"\n [disabled]=\"item.disabled\"\n [ngClass]=\"[\n 'relative inline-flex h-[calc(100%-1px)] appearance-none flex-1 items-center justify-center gap-1.5 whitespace-nowrap rounded-md border border-transparent px-3 py-0.5 text-sm font-medium transition-all focus-visible:border-ring focus-visible:outline-none focus-visible:outline-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 md:flex-initial md:px-4',\n value === item.value ? 'bg-background text-foreground shadow-sm' : 'bg-transparent text-muted-foreground'\n ]\"\n (click)=\"select(item)\"\n type=\"button\"\n >\n {{ item.label }}\n </button>\n </div>\n <div class=\"mt-4\">\n <ng-content></ng-content>\n </div>\n</div>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5553
6138
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTabsComponent, decorators: [{
5554
6139
  type: Component,
5555
- args: [{ selector: 'pdm-tabs', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"['w-full', className]\">\n <div\n role=\"tablist\"\n class=\"inline-flex h-8 w-full items-center overflow-x-auto scrollbar-thin rounded-lg bg-muted p-[3px] text-muted-foreground md:w-fit\"\n >\n <button\n *ngFor=\"let item of items\"\n role=\"tab\"\n [attr.aria-selected]=\"value === item.value\"\n [disabled]=\"item.disabled\"\n [ngClass]=\"[\n 'relative inline-flex h-[calc(100%-1px)] appearance-none flex-1 items-center justify-center gap-1.5 whitespace-nowrap rounded-md border border-transparent px-3 py-0.5 text-sm font-medium transition-all focus-visible:border-ring focus-visible:outline-none focus-visible:outline-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 md:flex-initial md:px-4',\n value === item.value ? 'bg-background text-foreground shadow-sm' : 'bg-transparent text-muted-foreground'\n ]\"\n (click)=\"select(item)\"\n type=\"button\"\n >\n {{ item.label }}\n </button>\n </div>\n <div class=\"mt-4\">\n <ng-content></ng-content>\n </div>\n</div>\n" }]
6140
+ args: [{ selector: "pdm-tabs", changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"['w-full', className]\">\n <div\n role=\"tablist\"\n class=\"inline-flex h-8 w-full items-center overflow-x-auto scrollbar-thin rounded-lg bg-muted p-[3px] text-muted-foreground md:w-fit\"\n >\n <button\n *ngFor=\"let item of items\"\n role=\"tab\"\n [attr.aria-selected]=\"value === item.value\"\n [disabled]=\"item.disabled\"\n [ngClass]=\"[\n 'relative inline-flex h-[calc(100%-1px)] appearance-none flex-1 items-center justify-center gap-1.5 whitespace-nowrap rounded-md border border-transparent px-3 py-0.5 text-sm font-medium transition-all focus-visible:border-ring focus-visible:outline-none focus-visible:outline-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 md:flex-initial md:px-4',\n value === item.value ? 'bg-background text-foreground shadow-sm' : 'bg-transparent text-muted-foreground'\n ]\"\n (click)=\"select(item)\"\n type=\"button\"\n >\n {{ item.label }}\n </button>\n </div>\n <div class=\"mt-4\">\n <ng-content></ng-content>\n </div>\n</div>\n", styles: [":host{display:block}\n"] }]
5556
6141
  }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { items: [{
5557
6142
  type: Input
5558
6143
  }], value: [{
@@ -5660,8 +6245,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
5660
6245
  class PdmToggleGroupComponent {
5661
6246
  constructor() {
5662
6247
  this.items = [];
5663
- this.value = '';
5664
- this.className = '';
6248
+ this.value = "";
6249
+ this.className = "";
5665
6250
  this.valueChange = new EventEmitter();
5666
6251
  }
5667
6252
  onSelect(next, disabled) {
@@ -5671,10 +6256,10 @@ class PdmToggleGroupComponent {
5671
6256
  }
5672
6257
  }
5673
6258
  PdmToggleGroupComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmToggleGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5674
- PdmToggleGroupComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmToggleGroupComponent, selector: "pdm-toggle-group", inputs: { items: "items", value: "value", className: "className" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div [ngClass]=\"['inline-flex items-center rounded-md border border-border p-1', className]\" role=\"group\">\n <button\n *ngFor=\"let item of items\"\n type=\"button\"\n [disabled]=\"item.disabled\"\n [attr.aria-pressed]=\"item.value === value\"\n [ngClass]=\"[\n 'inline-flex h-8 appearance-none items-center justify-center rounded-sm border-0 bg-transparent px-2.5 text-sm font-medium transition-colors disabled:pointer-events-none disabled:opacity-50 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n item.value === value\n ? 'bg-accent text-accent-foreground'\n : 'text-foreground hover:bg-accent hover:text-accent-foreground'\n ]\"\n (click)=\"onSelect(item.value, item.disabled)\"\n >\n {{ item.label }}\n </button>\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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
6259
+ PdmToggleGroupComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmToggleGroupComponent, selector: "pdm-toggle-group", inputs: { items: "items", value: "value", className: "className" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div\n [ngClass]=\"[\n 'flex flex-wrap items-center rounded-md border border-border p-1 gap-1',\n className,\n ]\"\n role=\"group\"\n>\n <button\n *ngFor=\"let item of items\"\n type=\"button\"\n [disabled]=\"item.disabled\"\n [attr.aria-pressed]=\"item.value === value\"\n [ngClass]=\"[\n 'inline-flex h-8 appearance-none items-center justify-center rounded-sm border-0 bg-transparent px-2.5 text-sm font-medium transition-colors disabled:pointer-events-none disabled:opacity-50 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n item.value === value\n ? 'bg-accent text-accent-foreground'\n : 'text-foreground hover:bg-accent hover:text-accent-foreground',\n ]\"\n (click)=\"onSelect(item.value, item.disabled)\"\n >\n {{ item.label }}\n </button>\n</div>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5675
6260
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmToggleGroupComponent, decorators: [{
5676
6261
  type: Component,
5677
- args: [{ selector: 'pdm-toggle-group', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"['inline-flex items-center rounded-md border border-border p-1', className]\" role=\"group\">\n <button\n *ngFor=\"let item of items\"\n type=\"button\"\n [disabled]=\"item.disabled\"\n [attr.aria-pressed]=\"item.value === value\"\n [ngClass]=\"[\n 'inline-flex h-8 appearance-none items-center justify-center rounded-sm border-0 bg-transparent px-2.5 text-sm font-medium transition-colors disabled:pointer-events-none disabled:opacity-50 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n item.value === value\n ? 'bg-accent text-accent-foreground'\n : 'text-foreground hover:bg-accent hover:text-accent-foreground'\n ]\"\n (click)=\"onSelect(item.value, item.disabled)\"\n >\n {{ item.label }}\n </button>\n</div>\n" }]
6262
+ args: [{ selector: "pdm-toggle-group", changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n [ngClass]=\"[\n 'flex flex-wrap items-center rounded-md border border-border p-1 gap-1',\n className,\n ]\"\n role=\"group\"\n>\n <button\n *ngFor=\"let item of items\"\n type=\"button\"\n [disabled]=\"item.disabled\"\n [attr.aria-pressed]=\"item.value === value\"\n [ngClass]=\"[\n 'inline-flex h-8 appearance-none items-center justify-center rounded-sm border-0 bg-transparent px-2.5 text-sm font-medium transition-colors disabled:pointer-events-none disabled:opacity-50 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n item.value === value\n ? 'bg-accent text-accent-foreground'\n : 'text-foreground hover:bg-accent hover:text-accent-foreground',\n ]\"\n (click)=\"onSelect(item.value, item.disabled)\"\n >\n {{ item.label }}\n </button>\n</div>\n", styles: [":host{display:block}\n"] }]
5678
6263
  }], propDecorators: { items: [{
5679
6264
  type: Input
5680
6265
  }], value: [{
@@ -5686,33 +6271,173 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
5686
6271
  }] } });
5687
6272
 
5688
6273
  class PdmTooltipComponent {
5689
- constructor() {
5690
- this.text = '';
5691
- this.side = 'top';
5692
- this.className = '';
6274
+ constructor(overlay, viewContainerRef, elementRef, cdr) {
6275
+ this.overlay = overlay;
6276
+ this.viewContainerRef = viewContainerRef;
6277
+ this.elementRef = elementRef;
6278
+ this.cdr = cdr;
6279
+ this.text = "";
6280
+ this.side = "top";
6281
+ this.className = "";
5693
6282
  this.open = false;
6283
+ this.overlayRef = null;
6284
+ }
6285
+ ngOnDestroy() {
6286
+ this.destroyOverlay();
6287
+ }
6288
+ onMouseEnter() {
6289
+ this.show();
6290
+ }
6291
+ onMouseLeave() {
6292
+ this.hide();
5694
6293
  }
5695
- get positionClass() {
5696
- if (this.side === 'bottom')
5697
- return 'top-full left-1/2 -translate-x-1/2 mt-2';
5698
- if (this.side === 'left')
5699
- return 'right-full top-1/2 -translate-y-1/2 mr-2';
5700
- if (this.side === 'right')
5701
- return 'left-full top-1/2 -translate-y-1/2 ml-2';
5702
- return 'bottom-full left-1/2 -translate-x-1/2 mb-2';
6294
+ onFocusIn() {
6295
+ this.show();
6296
+ }
6297
+ onFocusOut() {
6298
+ this.hide();
6299
+ }
6300
+ show() {
6301
+ if (this.open || !this.text)
6302
+ return;
6303
+ this.open = true;
6304
+ this.cdr.markForCheck();
6305
+ this.createOverlay();
6306
+ }
6307
+ hide() {
6308
+ if (!this.open)
6309
+ return;
6310
+ this.open = false;
6311
+ this.cdr.markForCheck();
6312
+ this.destroyOverlay();
6313
+ }
6314
+ createOverlay() {
6315
+ if (this.overlayRef)
6316
+ return;
6317
+ const triggerEl = this.elementRef.nativeElement.querySelector(":scope > *") ||
6318
+ this.elementRef.nativeElement;
6319
+ const positionStrategy = this.overlay
6320
+ .position()
6321
+ .flexibleConnectedTo(triggerEl)
6322
+ .withPositions(this.getPositionConfigs())
6323
+ .withFlexibleDimensions(false)
6324
+ .withPush(true);
6325
+ const panelClass = mergeOverlayPanelClass(OVERLAY_BASE_Z_INDEX);
6326
+ this.overlayRef = this.overlay.create({
6327
+ positionStrategy,
6328
+ panelClass,
6329
+ });
6330
+ const portal = new TemplatePortal(this.tooltipTemplate, this.viewContainerRef);
6331
+ this.overlayRef.attach(portal);
6332
+ }
6333
+ destroyOverlay() {
6334
+ if (this.overlayRef) {
6335
+ this.overlayRef.detach();
6336
+ this.overlayRef.dispose();
6337
+ this.overlayRef = null;
6338
+ }
6339
+ }
6340
+ getPositionConfigs() {
6341
+ const offset = 4;
6342
+ switch (this.side) {
6343
+ case "bottom":
6344
+ return [
6345
+ {
6346
+ originX: "center",
6347
+ originY: "bottom",
6348
+ overlayX: "center",
6349
+ overlayY: "top",
6350
+ offsetY: offset,
6351
+ },
6352
+ {
6353
+ originX: "center",
6354
+ originY: "top",
6355
+ overlayX: "center",
6356
+ overlayY: "bottom",
6357
+ offsetY: -offset,
6358
+ },
6359
+ ];
6360
+ case "left":
6361
+ return [
6362
+ {
6363
+ originX: "start",
6364
+ originY: "center",
6365
+ overlayX: "end",
6366
+ overlayY: "center",
6367
+ offsetX: -offset,
6368
+ },
6369
+ {
6370
+ originX: "end",
6371
+ originY: "center",
6372
+ overlayX: "start",
6373
+ overlayY: "center",
6374
+ offsetX: offset,
6375
+ },
6376
+ ];
6377
+ case "right":
6378
+ return [
6379
+ {
6380
+ originX: "end",
6381
+ originY: "center",
6382
+ overlayX: "start",
6383
+ overlayY: "center",
6384
+ offsetX: offset,
6385
+ },
6386
+ {
6387
+ originX: "start",
6388
+ originY: "center",
6389
+ overlayX: "end",
6390
+ overlayY: "center",
6391
+ offsetX: -offset,
6392
+ },
6393
+ ];
6394
+ case "top":
6395
+ default:
6396
+ return [
6397
+ {
6398
+ originX: "center",
6399
+ originY: "top",
6400
+ overlayX: "center",
6401
+ overlayY: "bottom",
6402
+ offsetY: -offset,
6403
+ },
6404
+ {
6405
+ originX: "center",
6406
+ originY: "bottom",
6407
+ overlayX: "center",
6408
+ overlayY: "top",
6409
+ offsetY: offset,
6410
+ },
6411
+ ];
6412
+ }
5703
6413
  }
5704
6414
  }
5705
- PdmTooltipComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
5706
- PdmTooltipComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmTooltipComponent, selector: "pdm-tooltip", inputs: { text: "text", side: "side", className: "className" }, ngImport: i0, template: "<span class=\"relative inline-flex\" [ngClass]=\"className\" (mouseenter)=\"open = true\" (mouseleave)=\"open = false\" (focusin)=\"open = true\" (focusout)=\"open = false\">\n <ng-content></ng-content>\n <span *ngIf=\"open\" [ngClass]=\"['pointer-events-none absolute z-[70] overflow-hidden rounded-md bg-foreground px-3 py-1.5 text-xs text-background animate-in fade-in-0 zoom-in-95', positionClass]\">\n {{ text }}\n </span>\n</span>\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 });
6415
+ PdmTooltipComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTooltipComponent, deps: [{ token: i1$1.Overlay }, { token: i0.ViewContainerRef }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
6416
+ PdmTooltipComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmTooltipComponent, selector: "pdm-tooltip", inputs: { text: "text", side: "side", className: "className" }, host: { listeners: { "mouseenter": "onMouseEnter()", "mouseleave": "onMouseLeave()", "focusin": "onFocusIn()", "focusout": "onFocusOut()" } }, viewQueries: [{ propertyName: "tooltipTemplate", first: true, predicate: ["tooltipTemplate"], descendants: true }], ngImport: i0, template: "<span\n class=\"relative inline-flex\"\n [ngClass]=\"className\"\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n (focusin)=\"onFocusIn()\"\n (focusout)=\"onFocusOut()\"\n>\n <ng-content></ng-content>\n\n <!-- Template for CDK Overlay -->\n <ng-template #tooltipTemplate>\n <span\n class=\"pointer-events-none overflow-hidden rounded-md bg-foreground px-3 py-1.5 text-xs text-background animate-in fade-in-0 zoom-in-95\"\n >\n {{ text }}\n </span>\n </ng-template>\n</span>\n", styles: [":host{display:inline-flex}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5707
6417
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTooltipComponent, decorators: [{
5708
6418
  type: Component,
5709
- args: [{ selector: 'pdm-tooltip', changeDetection: ChangeDetectionStrategy.OnPush, template: "<span class=\"relative inline-flex\" [ngClass]=\"className\" (mouseenter)=\"open = true\" (mouseleave)=\"open = false\" (focusin)=\"open = true\" (focusout)=\"open = false\">\n <ng-content></ng-content>\n <span *ngIf=\"open\" [ngClass]=\"['pointer-events-none absolute z-[70] overflow-hidden rounded-md bg-foreground px-3 py-1.5 text-xs text-background animate-in fade-in-0 zoom-in-95', positionClass]\">\n {{ text }}\n </span>\n</span>\n" }]
5710
- }], propDecorators: { text: [{
6419
+ args: [{ selector: "pdm-tooltip", changeDetection: ChangeDetectionStrategy.OnPush, template: "<span\n class=\"relative inline-flex\"\n [ngClass]=\"className\"\n (mouseenter)=\"onMouseEnter()\"\n (mouseleave)=\"onMouseLeave()\"\n (focusin)=\"onFocusIn()\"\n (focusout)=\"onFocusOut()\"\n>\n <ng-content></ng-content>\n\n <!-- Template for CDK Overlay -->\n <ng-template #tooltipTemplate>\n <span\n class=\"pointer-events-none overflow-hidden rounded-md bg-foreground px-3 py-1.5 text-xs text-background animate-in fade-in-0 zoom-in-95\"\n >\n {{ text }}\n </span>\n </ng-template>\n</span>\n", styles: [":host{display:inline-flex}\n"] }]
6420
+ }], ctorParameters: function () { return [{ type: i1$1.Overlay }, { type: i0.ViewContainerRef }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { text: [{
5711
6421
  type: Input
5712
6422
  }], side: [{
5713
6423
  type: Input
5714
6424
  }], className: [{
5715
6425
  type: Input
6426
+ }], tooltipTemplate: [{
6427
+ type: ViewChild,
6428
+ args: ["tooltipTemplate"]
6429
+ }], onMouseEnter: [{
6430
+ type: HostListener,
6431
+ args: ["mouseenter"]
6432
+ }], onMouseLeave: [{
6433
+ type: HostListener,
6434
+ args: ["mouseleave"]
6435
+ }], onFocusIn: [{
6436
+ type: HostListener,
6437
+ args: ["focusin"]
6438
+ }], onFocusOut: [{
6439
+ type: HostListener,
6440
+ args: ["focusout"]
5716
6441
  }] } });
5717
6442
 
5718
6443
  const COMPONENTS = [
@@ -5913,5 +6638,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
5913
6638
  * Generated bundle index. Do not edit.
5914
6639
  */
5915
6640
 
5916
- export { BREAKPOINTS, PdmAccordionComponent, PdmAlertComponent, PdmAlertDialogComponent, PdmAspectRatioComponent, PdmAvatarComponent, PdmBadgeComponent, PdmBreadcrumbComponent, PdmButtonComponent, PdmButtonGroupComponent, PdmCalendarComponent, PdmCardComponent, PdmCarouselComponent, PdmChartComponent, PdmCheckboxComponent, PdmCollapsibleComponent, PdmComboboxComponent, PdmCommandComponent, PdmContextMenuComponent, PdmDataTableComponent, PdmDatePickerComponent, PdmDialogComponent, PdmDraggableTableComponent, PdmDrawerComponent, PdmDropdownMenuComponent, PdmEmptyComponent, PdmFieldComponent, PdmHoverCardComponent, PdmIconComponent, PdmInputComponent, PdmInputGroupComponent, PdmInputOtpComponent, PdmInputPasswordComponent, PdmItemComponent, PdmKbdComponent, PdmLabelComponent, PdmMenubarComponent, PdmNativeSelectComponent, PdmNavigationMenuComponent, PdmOutsideClickDirective, PdmPaginationComponent, PdmPopoverComponent, PdmProgressComponent, PdmRadioGroupComponent, PdmScrollAreaComponent, PdmSelectComponent, PdmSelectOptionDirective, PdmSeparatorComponent, PdmSheetComponent, PdmSidebarComponent, PdmSkeletonComponent, PdmSliderComponent, PdmSonnerComponent, PdmSpinnerComponent, PdmSwitchComponent, PdmTableComponent, PdmTabsComponent, PdmTextareaComponent, PdmToggleComponent, PdmToggleGroupComponent, PdmTooltipComponent, PdmUiKitModule, RESPONSIVE_CONTAINER, RESPONSIVE_DISPLAY, TABLE_RESPONSIVE, Z_INDEX, createFlexiblePositionStrategy, logZIndexStack, overflowResponsive, responsive, spacingResponsive, widthResponsive };
6641
+ export { BREAKPOINTS, OVERLAY_BASE_Z_INDEX, PdmAccordionComponent, PdmAlertComponent, PdmAlertDialogComponent, PdmAspectRatioComponent, PdmAvatarComponent, PdmBadgeComponent, PdmBreadcrumbComponent, PdmButtonComponent, PdmButtonGroupComponent, PdmCalendarComponent, PdmCardComponent, PdmCarouselComponent, PdmChartComponent, PdmCheckboxComponent, PdmCollapsibleComponent, PdmComboboxComponent, PdmCommandComponent, PdmContextMenuComponent, PdmDataTableComponent, PdmDatePickerComponent, PdmDialogComponent, PdmDraggableTableComponent, PdmDrawerComponent, PdmDropdownMenuComponent, PdmEmptyComponent, PdmFieldComponent, PdmHoverCardComponent, PdmIconComponent, PdmInputComponent, PdmInputGroupComponent, PdmInputOtpComponent, PdmInputPasswordComponent, PdmItemComponent, PdmKbdComponent, PdmLabelComponent, PdmMenubarComponent, PdmNativeSelectComponent, PdmNavigationMenuComponent, PdmOutsideClickDirective, PdmPaginationComponent, PdmPopoverComponent, PdmProgressComponent, PdmRadioGroupComponent, PdmScrollAreaComponent, PdmSelectComponent, PdmSelectOptionDirective, PdmSeparatorComponent, PdmSheetComponent, PdmSidebarComponent, PdmSkeletonComponent, PdmSliderComponent, PdmSonnerComponent, PdmSpinnerComponent, PdmSwitchComponent, PdmTableComponent, PdmTabsComponent, PdmTextareaComponent, PdmToggleComponent, PdmToggleGroupComponent, PdmTooltipComponent, PdmUiKitModule, RESPONSIVE_CONTAINER, RESPONSIVE_DISPLAY, TABLE_RESPONSIVE, Z_INDEX, createFlexiblePositionStrategy, createZIndexEnforcedOverlay, extractZIndex, logZIndexStack, mergeOverlayPanelClass, overflowResponsive, responsive, spacingResponsive, widthResponsive };
5917
6642
  //# sourceMappingURL=pdm-ui-kit.mjs.map