pdm-ui-kit 0.2.0 → 0.3.0

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 +208 -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 +1376 -654
  22. package/fesm2015/pdm-ui-kit.mjs.map +1 -1
  23. package/fesm2020/pdm-ui-kit.mjs +1380 -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,225 @@ 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: "flex flex-col sm:flex-row sm:items-center sm:flex-wrap",
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>div]:w-full",
348
+ "[&>pdm-input>div]:!rounded-none",
349
+ "[&>pdm-input>div]:shadow-none",
350
+ "[&>pdm-input>div>input]:!rounded-none",
351
+ "[&>pdm-input>div>input]:bg-background",
352
+ "[&>pdm-input>div>input]:shadow-none",
353
+ "[&>pdm-input:first-child>div]:!rounded-l-md",
354
+ "[&>pdm-input:last-child>div]:!rounded-r-md",
355
+ "[&>pdm-input:first-child>div>input]:!rounded-l-md",
356
+ "[&>pdm-input:last-child>div>input]:!rounded-r-md",
357
+ "[&>pdm-input-group>div]:!rounded-none",
358
+ "[&>pdm-input-group>div]:shadow-none",
359
+ "[&>pdm-input-group:first-child>div]:!rounded-l-md",
360
+ "[&>pdm-input-group:last-child>div]:!rounded-r-md",
361
+ "[&>pdm-select>select]:!rounded-none",
362
+ "[&>pdm-select>select]:shadow-none",
363
+ "[&>pdm-select>div>button]:!rounded-none",
364
+ "[&>pdm-select>div>button]:shadow-none",
365
+ "[&>pdm-select:first-child>select]:!rounded-l-md",
366
+ "[&>pdm-select:last-child>select]:!rounded-r-md",
367
+ "[&>pdm-select:first-child>div>button]:!rounded-l-md",
368
+ "[&>pdm-select:last-child>div>button]:!rounded-r-md",
369
+ "[&>pdm-select:not(:first-child)>div>button]:!rounded-l-none",
370
+ "[&>pdm-select:not(:last-child)>div>button]:!rounded-r-none",
371
+ "[&>pdm-tooltip>span>*]:rounded-none",
372
+ "[&>pdm-tooltip>span>*]:shadow-none",
373
+ "[&>pdm-tooltip:not(:first-child)>span>*]:border-l-0",
374
+ "[&>pdm-tooltip>span>button]:!rounded-none",
375
+ "[&>pdm-tooltip>span>button]:shadow-none",
376
+ "[&>pdm-tooltip:first-child>span>button]:!rounded-l-md",
377
+ "[&>pdm-tooltip:last-child>span>button]:!rounded-r-md",
378
+ "[&>pdm-tooltip>span>input]:!rounded-none",
379
+ "[&>pdm-tooltip>span>input]:bg-background",
380
+ "[&>pdm-tooltip>span>input]:shadow-none",
381
+ "[&>pdm-tooltip:first-child>span>input]:!rounded-l-md",
382
+ "[&>pdm-tooltip:last-child>span>input]:!rounded-r-md",
383
+ "[&>pdm-tooltip>span>select]:!rounded-none",
384
+ "[&>pdm-tooltip>span>select]:shadow-none",
385
+ "[&>pdm-tooltip:first-child>span>select]:!rounded-l-md",
386
+ "[&>pdm-tooltip:last-child>span>select]:!rounded-r-md",
387
+ "[&>pdm-tooltip>span>pdm-button>button]:!rounded-none",
388
+ "[&>pdm-tooltip>span>pdm-button>button]:shadow-none",
389
+ "[&>pdm-tooltip:first-child>span>pdm-button>button]:!rounded-l-md",
390
+ "[&>pdm-tooltip:last-child>span>pdm-button>button]:!rounded-r-md",
391
+ "[&>pdm-tooltip>span>pdm-input>div]:!rounded-none",
392
+ "[&>pdm-tooltip>span>pdm-input>div]:shadow-none",
393
+ "[&>pdm-tooltip>span>pdm-input>div>input]:!rounded-none",
394
+ "[&>pdm-tooltip>span>pdm-input>div>input]:bg-background",
395
+ "[&>pdm-tooltip>span>pdm-input>div>input]:shadow-none",
396
+ "[&>pdm-tooltip:first-child>span>pdm-input>div]:!rounded-l-md",
397
+ "[&>pdm-tooltip:last-child>span>pdm-input>div]:!rounded-r-md",
398
+ "[&>pdm-tooltip:first-child>span>pdm-input>div>input]:!rounded-l-md",
399
+ "[&>pdm-tooltip:last-child>span>pdm-input>div>input]:!rounded-r-md",
400
+ "[&>pdm-tooltip>span>pdm-input-group>div]:!rounded-none",
401
+ "[&>pdm-tooltip>span>pdm-input-group>div]:shadow-none",
402
+ "[&>pdm-tooltip:first-child>span>pdm-input-group>div]:!rounded-l-md",
403
+ "[&>pdm-tooltip:last-child>span>pdm-input-group>div]:!rounded-r-md",
404
+ "[&>pdm-tooltip>span>pdm-select>select]:!rounded-none",
405
+ "[&>pdm-tooltip>span>pdm-select>select]:shadow-none",
406
+ "[&>pdm-tooltip>span>pdm-select>div>button]:!rounded-none",
407
+ "[&>pdm-tooltip>span>pdm-select>div>button]:shadow-none",
408
+ "[&>pdm-tooltip:first-child>span>pdm-select>select]:!rounded-l-md",
409
+ "[&>pdm-tooltip:last-child>span>pdm-select>select]:!rounded-r-md",
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
+ ],
415
+ vertical: [
416
+ "[&>*]:rounded-none",
417
+ "[&>*:first-child]:rounded-t-md",
418
+ "[&>*:last-child]:rounded-b-md",
419
+ "[&>*:not(:first-child)]:border-t-0",
420
+ "[&>*:not(:first-child)]:-mt-px",
421
+ "[&>pdm-button]:flex",
422
+ "[&>pdm-button>button]:h-9",
423
+ "[&>pdm-button>button]:!rounded-none",
424
+ "[&>pdm-button>button]:shadow-none",
425
+ "[&>pdm-button:first-child>button]:!rounded-t-md",
426
+ "[&>pdm-button:last-child>button]:!rounded-b-md",
427
+ "[&>pdm-input>div]:!rounded-none",
428
+ "[&>pdm-input>div]:shadow-none",
429
+ "[&>pdm-input>div>input]:!rounded-none",
430
+ "[&>pdm-input>div>input]:bg-background",
431
+ "[&>pdm-input>div>input]:shadow-none",
432
+ "[&>pdm-input:first-child>div]:!rounded-t-md",
433
+ "[&>pdm-input:last-child>div]:!rounded-b-md",
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>div]:shadow-none",
438
+ "[&>pdm-input-group:first-child>div]:!rounded-t-md",
439
+ "[&>pdm-input-group:last-child>div]:!rounded-b-md",
440
+ "[&>pdm-select>select]:!rounded-none",
441
+ "[&>pdm-select>select]:shadow-none",
442
+ "[&>pdm-select>div>button]:!rounded-none",
443
+ "[&>pdm-select>div>button]:shadow-none",
444
+ "[&>pdm-select:first-child>select]:!rounded-t-md",
445
+ "[&>pdm-select:last-child>select]:!rounded-b-md",
446
+ "[&>pdm-select:first-child>div>button]:!rounded-t-md",
447
+ "[&>pdm-select:last-child>div>button]:!rounded-b-md",
448
+ "[&>pdm-select:not(:first-child)>div>button]:!rounded-t-none",
449
+ "[&>pdm-select:not(:last-child)>div>button]:!rounded-b-none",
450
+ "[&>pdm-tooltip>span>*]:rounded-none",
451
+ "[&>pdm-tooltip>span>*]:shadow-none",
452
+ "[&>pdm-tooltip:not(:first-child)>span>*]:border-t-0",
453
+ "[&>pdm-tooltip>span>button]:!rounded-none",
454
+ "[&>pdm-tooltip>span>button]:shadow-none",
455
+ "[&>pdm-tooltip:first-child>span>button]:!rounded-t-md",
456
+ "[&>pdm-tooltip:last-child>span>button]:!rounded-b-md",
457
+ "[&>pdm-tooltip>span>input]:!rounded-none",
458
+ "[&>pdm-tooltip>span>input]:bg-background",
459
+ "[&>pdm-tooltip>span>input]:shadow-none",
460
+ "[&>pdm-tooltip:first-child>span>input]:!rounded-t-md",
461
+ "[&>pdm-tooltip:last-child>span>input]:!rounded-b-md",
462
+ "[&>pdm-tooltip>span>select]:!rounded-none",
463
+ "[&>pdm-tooltip>span>select]:shadow-none",
464
+ "[&>pdm-tooltip:first-child>span>select]:!rounded-t-md",
465
+ "[&>pdm-tooltip:last-child>span>select]:!rounded-b-md",
466
+ "[&>pdm-tooltip>span>pdm-button>button]:!rounded-none",
467
+ "[&>pdm-tooltip>span>pdm-button>button]:shadow-none",
468
+ "[&>pdm-tooltip:first-child>span>pdm-button>button]:!rounded-t-md",
469
+ "[&>pdm-tooltip:last-child>span>pdm-button>button]:!rounded-b-md",
470
+ "[&>pdm-tooltip>span>pdm-input>div]:!rounded-none",
471
+ "[&>pdm-tooltip>span>pdm-input>div]:shadow-none",
472
+ "[&>pdm-tooltip>span>pdm-input>div>input]:!rounded-none",
473
+ "[&>pdm-tooltip>span>pdm-input>div>input]:bg-background",
474
+ "[&>pdm-tooltip>span>pdm-input>div>input]:shadow-none",
475
+ "[&>pdm-tooltip:first-child>span>pdm-input>div]:!rounded-t-md",
476
+ "[&>pdm-tooltip:last-child>span>pdm-input>div]:!rounded-b-md",
477
+ "[&>pdm-tooltip:first-child>span>pdm-input>div>input]:!rounded-t-md",
478
+ "[&>pdm-tooltip:last-child>span>pdm-input>div>input]:!rounded-b-md",
479
+ "[&>pdm-tooltip>span>pdm-input-group>div]:!rounded-none",
480
+ "[&>pdm-tooltip>span>pdm-input-group>div]:shadow-none",
481
+ "[&>pdm-tooltip:first-child>span>pdm-input-group>div]:!rounded-t-md",
482
+ "[&>pdm-tooltip:last-child>span>pdm-input-group>div]:!rounded-b-md",
483
+ "[&>pdm-tooltip>span>pdm-select>select]:!rounded-none",
484
+ "[&>pdm-tooltip>span>pdm-select>select]:shadow-none",
485
+ "[&>pdm-tooltip>span>pdm-select>div>button]:!rounded-none",
486
+ "[&>pdm-tooltip>span>pdm-select>div>button]:shadow-none",
487
+ "[&>pdm-tooltip:first-child>span>pdm-select>select]:!rounded-t-md",
488
+ "[&>pdm-tooltip:last-child>span>pdm-select>select]:!rounded-b-md",
489
+ "[&>pdm-tooltip:first-child>span>pdm-select>div>button]:!rounded-t-md",
490
+ "[&>pdm-tooltip:last-child>span>pdm-select>div>button]:!rounded-b-md",
491
+ "[&>pdm-tooltip:not(:first-child)>span>pdm-select>div>button]:!rounded-t-none",
492
+ "[&>pdm-tooltip:not(:last-child)>span>pdm-select>div>button]:!rounded-b-none",
493
+ ],
494
+ };
495
+ const FOCUS_STACKING_CLASS = "*:focus-visible:relative *:focus-visible:z-10";
496
+ const SEPARATOR_CLASSES = "overflow-hidden rounded-md border border-border bg-secondary shadow-sm";
318
497
  class PdmButtonGroupComponent {
319
498
  constructor() {
320
- this.variant = 'default';
499
+ this.variant = "default";
321
500
  this.separated = true;
322
- this.className = '';
501
+ this.className = "";
323
502
  }
324
- get rootClasses() {
503
+ get axis() {
325
504
  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
- : '';
505
+ return (_b = (_a = this.orientation) !== null && _a !== void 0 ? _a : this.direction) !== null && _b !== void 0 ? _b : "horizontal";
506
+ }
507
+ get isVertical() {
508
+ return this.variant === "orientation" || this.axis === "vertical";
509
+ }
510
+ get shouldAttach() {
511
+ return !this.separated && this.variant !== "default";
512
+ }
513
+ get ariaOrientation() {
514
+ return this.isVertical ? "vertical" : "horizontal";
515
+ }
516
+ get rootClasses() {
491
517
  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
518
+ ROOT_LAYOUT[this.isVertical ? "vertical" : "horizontal"],
519
+ this.variant === "default" || this.separated ? "gap-2" : "gap-0",
520
+ this.shouldAttach
521
+ ? ATTACHMENT_EDGE_CLASSES[this.isVertical ? "vertical" : "horizontal"].join(" ")
522
+ : "",
523
+ this.shouldAttach
524
+ ? ATTACHMENT_CONTROL_CLASSES[this.isVertical ? "vertical" : "horizontal"].join(" ")
525
+ : "",
526
+ this.shouldAttach ? FOCUS_STACKING_CLASS : "",
527
+ this.variant === "separator" ? SEPARATOR_CLASSES : "",
528
+ this.className,
503
529
  ];
504
530
  }
505
531
  }
506
532
  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 });
533
+ 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
534
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmButtonGroupComponent, decorators: [{
509
535
  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" }]
536
+ 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
537
  }], propDecorators: { variant: [{
512
538
  type: Input
513
539
  }], orientation: [{
@@ -1542,35 +1568,207 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
1542
1568
  type: Output
1543
1569
  }] } });
1544
1570
 
1571
+ /**
1572
+ * Z-Index helper for overlay components.
1573
+ *
1574
+ * CRITICAL: Consumer custom panelClass MUST NOT replace the base z-index.
1575
+ * This helper ensures z-index is preserved when merging custom classes.
1576
+ */
1577
+ /**
1578
+ * Base z-index class for overlays - MUST be included in any overlay panel.
1579
+ * This ensures overlays appear above modals (z-50) and drawers (z-40).
1580
+ */
1581
+ const OVERLAY_BASE_Z_INDEX = "z-[70]";
1582
+ /**
1583
+ * Merge consumer's panelClass with our base z-index.
1584
+ * Consumer classes are APPENDED, not replacing our z-index guarantee.
1585
+ *
1586
+ * @param baseZIndex - Base z-index class to enforce (default: OVERLAY_BASE_Z_INDEX)
1587
+ * @param consumerClasses - Optional additional classes from consumer
1588
+ * @returns Array of classes safe for CDK Overlay panelClass
1589
+ */
1590
+ function mergeOverlayPanelClass(baseZIndex = OVERLAY_BASE_Z_INDEX, consumerClasses) {
1591
+ const baseClasses = baseZIndex.split(" ");
1592
+ if (!consumerClasses) {
1593
+ return baseClasses;
1594
+ }
1595
+ const consumerClassArray = Array.isArray(consumerClasses)
1596
+ ? consumerClasses
1597
+ : consumerClasses.split(" ");
1598
+ // Consumer classes are appended AFTER base classes
1599
+ // This ensures z-index from baseClasses is preserved first
1600
+ return [...baseClasses, ...consumerClassArray];
1601
+ }
1602
+ /**
1603
+ * Create OverlayConfig with guaranteed z-index.
1604
+ * Use this instead of direct OverlayConfig to ensure z-index enforcement.
1605
+ *
1606
+ * @param baseConfig - Base overlay configuration
1607
+ * @param consumerPanelClass - Optional consumer panelClass to merge
1608
+ * @returns OverlayConfig with z-index guarantee
1609
+ */
1610
+ function createZIndexEnforcedOverlay(baseConfig, consumerPanelClass) {
1611
+ const mergedClasses = mergeOverlayPanelClass(OVERLAY_BASE_Z_INDEX, consumerPanelClass);
1612
+ const existingPanelClass = baseConfig.panelClass;
1613
+ if (existingPanelClass) {
1614
+ const existingArray = Array.isArray(existingPanelClass)
1615
+ ? existingPanelClass
1616
+ : existingPanelClass.split(" ");
1617
+ return Object.assign(Object.assign({}, baseConfig), { panelClass: [...mergedClasses, ...existingArray] });
1618
+ }
1619
+ return Object.assign(Object.assign({}, baseConfig), { panelClass: mergedClasses });
1620
+ }
1621
+ /**
1622
+ * Helper to extract z-index from a class string for debugging.
1623
+ */
1624
+ function extractZIndex(classes) {
1625
+ const classArray = Array.isArray(classes) ? classes : classes.split(" ");
1626
+ for (const cls of classArray) {
1627
+ if (cls.startsWith("z-") || cls.startsWith("z-[")) {
1628
+ return cls;
1629
+ }
1630
+ }
1631
+ return null;
1632
+ }
1633
+
1545
1634
  class PdmComboboxComponent {
1546
- constructor() {
1635
+ constructor(overlay, viewContainerRef, elementRef, cdr) {
1636
+ this.overlay = overlay;
1637
+ this.viewContainerRef = viewContainerRef;
1638
+ this.elementRef = elementRef;
1639
+ this.cdr = cdr;
1547
1640
  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 = '';
1641
+ this.placeholder = "Select framework...";
1642
+ this.searchPlaceholder = "Search framework";
1643
+ this.className = "";
1644
+ this.options = [
1645
+ "Next.js",
1646
+ "SvelteKit",
1647
+ "Nuxt.js",
1648
+ "Remix",
1649
+ "Astro",
1650
+ ];
1651
+ this.value = "";
1553
1652
  this.width = 200;
1653
+ this.panelClassName = "";
1554
1654
  this.openChange = new EventEmitter();
1555
1655
  this.valueChange = new EventEmitter();
1656
+ this.overlayRef = null;
1657
+ this.outsideClickSub = null;
1658
+ }
1659
+ ngOnDestroy() {
1660
+ this.destroyOverlay();
1556
1661
  }
1557
1662
  get selectedLabel() {
1558
1663
  return this.value || this.placeholder;
1559
1664
  }
1560
1665
  toggle() {
1561
- this.openChange.emit(!this.open);
1666
+ if (this.open) {
1667
+ this.close();
1668
+ }
1669
+ else {
1670
+ this.openPanel();
1671
+ }
1562
1672
  }
1563
1673
  select(option) {
1564
1674
  this.valueChange.emit(option);
1675
+ this.value = option;
1676
+ this.close();
1677
+ }
1678
+ onEscape() {
1679
+ if (this.open) {
1680
+ this.close();
1681
+ }
1682
+ }
1683
+ openPanel() {
1684
+ var _a;
1685
+ if (this.overlayRef)
1686
+ return;
1687
+ const triggerEl = (_a = this.triggerRef) === null || _a === void 0 ? void 0 : _a.nativeElement;
1688
+ if (!triggerEl)
1689
+ return;
1690
+ this.open = true;
1691
+ this.openChange.emit(true);
1692
+ this.cdr.markForCheck();
1693
+ const positionStrategy = this.overlay
1694
+ .position()
1695
+ .flexibleConnectedTo(triggerEl)
1696
+ .withPositions(this.getPositionConfigs())
1697
+ .withFlexibleDimensions(false)
1698
+ .withPush(true);
1699
+ const panelClass = mergeOverlayPanelClass(OVERLAY_BASE_Z_INDEX, this.panelClassName);
1700
+ this.overlayRef = this.overlay.create({
1701
+ positionStrategy,
1702
+ panelClass,
1703
+ });
1704
+ const portal = new TemplatePortal(this.panelTemplateRef, this.viewContainerRef);
1705
+ this.overlayRef.attach(portal);
1706
+ // Close on click outside
1707
+ this.outsideClickSub = this.overlayRef
1708
+ .outsidePointerEvents()
1709
+ .subscribe(() => {
1710
+ this.close();
1711
+ });
1712
+ this.cdr.markForCheck();
1713
+ }
1714
+ close() {
1715
+ if (!this.overlayRef)
1716
+ return;
1717
+ this.open = false;
1565
1718
  this.openChange.emit(false);
1719
+ this.cdr.markForCheck();
1720
+ this.destroyOverlay();
1721
+ }
1722
+ destroyOverlay() {
1723
+ if (this.outsideClickSub) {
1724
+ this.outsideClickSub.unsubscribe();
1725
+ this.outsideClickSub = null;
1726
+ }
1727
+ if (this.overlayRef) {
1728
+ this.overlayRef.detach();
1729
+ this.overlayRef.dispose();
1730
+ this.overlayRef = null;
1731
+ }
1732
+ }
1733
+ getPositionConfigs() {
1734
+ return [
1735
+ {
1736
+ originX: "start",
1737
+ originY: "bottom",
1738
+ overlayX: "start",
1739
+ overlayY: "top",
1740
+ offsetY: 4,
1741
+ },
1742
+ {
1743
+ originX: "start",
1744
+ originY: "top",
1745
+ overlayX: "start",
1746
+ overlayY: "bottom",
1747
+ offsetY: -4,
1748
+ },
1749
+ {
1750
+ originX: "end",
1751
+ originY: "bottom",
1752
+ overlayX: "end",
1753
+ overlayY: "top",
1754
+ offsetY: 4,
1755
+ },
1756
+ {
1757
+ originX: "start",
1758
+ originY: "bottom",
1759
+ overlayX: "end",
1760
+ overlayY: "top",
1761
+ offsetY: 4,
1762
+ },
1763
+ ];
1566
1764
  }
1567
1765
  }
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 });
1766
+ 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 });
1767
+ 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
1768
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmComboboxComponent, decorators: [{
1571
1769
  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: [{
1770
+ 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"] }]
1771
+ }], ctorParameters: function () { return [{ type: i1$1.Overlay }, { type: i0.ViewContainerRef }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { open: [{
1574
1772
  type: Input
1575
1773
  }], placeholder: [{
1576
1774
  type: Input
@@ -1584,10 +1782,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
1584
1782
  type: Input
1585
1783
  }], width: [{
1586
1784
  type: Input
1785
+ }], panelClassName: [{
1786
+ type: Input
1587
1787
  }], openChange: [{
1588
1788
  type: Output
1589
1789
  }], valueChange: [{
1590
1790
  type: Output
1791
+ }], triggerRef: [{
1792
+ type: ViewChild,
1793
+ args: ["triggerEl"]
1794
+ }], panelTemplateRef: [{
1795
+ type: ViewChild,
1796
+ args: ["panelTemplate"]
1797
+ }], onEscape: [{
1798
+ type: HostListener,
1799
+ args: ["document:keydown.escape"]
1591
1800
  }] } });
1592
1801
 
1593
1802
  const FALLBACK_NODE = [['circle', { cx: '12', cy: '12', r: '9' }]];
@@ -1709,12 +1918,12 @@ class PdmIconComponent {
1709
1918
  .replace(/>/g, '&gt;');
1710
1919
  }
1711
1920
  }
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 });
1921
+ 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
1922
  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
1923
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmIconComponent, decorators: [{
1715
1924
  type: Component,
1716
1925
  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: [{
1926
+ }], ctorParameters: function () { return [{ type: i1$2.DomSanitizer }]; }, propDecorators: { name: [{
1718
1927
  type: Input
1719
1928
  }], library: [{
1720
1929
  type: Input
@@ -1805,72 +2014,140 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
1805
2014
  }] } });
1806
2015
 
1807
2016
  class PdmContextMenuComponent {
1808
- constructor(elementRef) {
1809
- this.elementRef = elementRef;
2017
+ constructor(overlay, viewContainerRef, _elementRef, cdr) {
2018
+ this.overlay = overlay;
2019
+ this.viewContainerRef = viewContainerRef;
2020
+ this._elementRef = _elementRef;
2021
+ this.cdr = cdr;
1810
2022
  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 }
2023
+ { type: "item", label: "Back", value: "back", inset: true, shortcut: "⌘[" },
2024
+ {
2025
+ type: "item",
2026
+ label: "Forward",
2027
+ value: "forward",
2028
+ inset: true,
2029
+ shortcut: "⌘]",
2030
+ disabled: true,
2031
+ },
2032
+ {
2033
+ type: "item",
2034
+ label: "Reload",
2035
+ value: "reload",
2036
+ inset: true,
2037
+ shortcut: "⌘R",
2038
+ },
2039
+ {
2040
+ type: "item",
2041
+ label: "More Tools",
2042
+ value: "more-tools",
2043
+ inset: true,
2044
+ showChevron: true,
2045
+ },
2046
+ { type: "separator" },
2047
+ {
2048
+ type: "item",
2049
+ label: "Show Bookmarks Bar",
2050
+ value: "show-bookmarks",
2051
+ checked: true,
2052
+ },
2053
+ { type: "item", label: "Show Full URLs", value: "show-urls", inset: true },
2054
+ { type: "separator" },
2055
+ { type: "label", label: "People" },
2056
+ { type: "separator" },
2057
+ { type: "item", label: "Pedro Duarte", value: "pedro", selectedDot: true },
2058
+ { type: "item", label: "Colm Tuite", value: "colm", inset: true },
1823
2059
  ];
1824
- this.className = '';
1825
- this.triggerLabel = 'Right click here';
2060
+ this.className = "";
2061
+ this.triggerLabel = "Right click here";
1826
2062
  this.width = 300;
1827
2063
  this.height = 150;
2064
+ this.panelClassName = "";
1828
2065
  this.itemSelect = new EventEmitter();
1829
2066
  this.open = false;
1830
2067
  this.x = 0;
1831
2068
  this.y = 0;
2069
+ this.overlayRef = null;
2070
+ this.outsideClickSub = null;
1832
2071
  }
1833
- ngOnInit() {
1834
- this.boundPointerDown = (event) => this.onDocumentPointerDown(event);
1835
- document.addEventListener('pointerdown', this.boundPointerDown, { capture: true });
1836
- }
2072
+ ngOnInit() { }
1837
2073
  ngOnDestroy() {
1838
- if (this.boundPointerDown) {
1839
- document.removeEventListener('pointerdown', this.boundPointerDown, { capture: true });
1840
- }
2074
+ this.destroyOverlay();
1841
2075
  }
1842
2076
  onContextMenu(event) {
1843
2077
  event.preventDefault();
2078
+ event.stopPropagation();
1844
2079
  this.x = event.clientX;
1845
2080
  this.y = event.clientY;
1846
2081
  this.open = true;
2082
+ this.cdr.markForCheck();
2083
+ this.createOverlay();
1847
2084
  }
1848
2085
  select(item) {
1849
- if (item.disabled || item.type === 'separator' || item.type === 'label' || !item.value)
2086
+ if (item.disabled ||
2087
+ item.type === "separator" ||
2088
+ item.type === "label" ||
2089
+ !item.value)
1850
2090
  return;
1851
2091
  this.itemSelect.emit(item.value);
1852
2092
  this.open = false;
2093
+ this.cdr.markForCheck();
2094
+ this.destroyOverlay();
1853
2095
  }
1854
- onEsc() {
1855
- if (this.open) {
1856
- this.open = false;
2096
+ onDocumentClick(event) {
2097
+ if (this.open && event.type === "click") {
2098
+ // Don't close on click inside the menu
2099
+ if (this.overlayRef &&
2100
+ this.overlayRef.overlayElement.contains(event.target)) {
2101
+ return;
2102
+ }
2103
+ this.close();
1857
2104
  }
1858
2105
  }
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;
2106
+ createOverlay() {
2107
+ this.destroyOverlay();
2108
+ // Create global position strategy at cursor position
2109
+ const positionStrategy = this.overlay
2110
+ .position()
2111
+ .global()
2112
+ .left(`${this.x}px`)
2113
+ .top(`${this.y}px`);
2114
+ const panelClass = mergeOverlayPanelClass(OVERLAY_BASE_Z_INDEX, this.panelClassName);
2115
+ this.overlayRef = this.overlay.create({
2116
+ positionStrategy,
2117
+ panelClass,
2118
+ });
2119
+ const portal = new TemplatePortal(this.menuTemplateRef, this.viewContainerRef);
2120
+ this.overlayRef.attach(portal);
2121
+ // Close on click outside
2122
+ this.outsideClickSub = this.overlayRef
2123
+ .outsidePointerEvents()
2124
+ .subscribe(() => {
2125
+ this.close();
2126
+ });
2127
+ }
2128
+ close() {
2129
+ this.open = false;
2130
+ this.cdr.markForCheck();
2131
+ this.destroyOverlay();
2132
+ }
2133
+ destroyOverlay() {
2134
+ if (this.outsideClickSub) {
2135
+ this.outsideClickSub.unsubscribe();
2136
+ this.outsideClickSub = null;
2137
+ }
2138
+ if (this.overlayRef) {
2139
+ this.overlayRef.detach();
2140
+ this.overlayRef.dispose();
2141
+ this.overlayRef = null;
1865
2142
  }
1866
2143
  }
1867
2144
  }
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 });
2145
+ 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 });
2146
+ 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
2147
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmContextMenuComponent, decorators: [{
1871
2148
  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: [{
2149
+ 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"] }]
2150
+ }], ctorParameters: function () { return [{ type: i1$1.Overlay }, { type: i0.ViewContainerRef }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { items: [{
1874
2151
  type: Input
1875
2152
  }], className: [{
1876
2153
  type: Input
@@ -1880,11 +2157,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
1880
2157
  type: Input
1881
2158
  }], height: [{
1882
2159
  type: Input
2160
+ }], panelClassName: [{
2161
+ type: Input
1883
2162
  }], itemSelect: [{
1884
2163
  type: Output
1885
- }], onEsc: [{
2164
+ }], menuTemplateRef: [{
2165
+ type: ViewChild,
2166
+ args: ["menuTemplate"]
2167
+ }], onDocumentClick: [{
1886
2168
  type: HostListener,
1887
- args: ['document:keydown.escape']
2169
+ args: ["document:keydown.escape"]
2170
+ }, {
2171
+ type: HostListener,
2172
+ args: ["document:click"]
1888
2173
  }] } });
1889
2174
 
1890
2175
  /**
@@ -2056,7 +2341,7 @@ class PdmTableComponent {
2056
2341
  * - data: tabla con bordes y espaciado para data
2057
2342
  * - interactive: tabla con hover, sticky header y estilos interactivos
2058
2343
  */
2059
- this.variant = 'default';
2344
+ this.variant = "default";
2060
2345
  /**
2061
2346
  * Estrategia responsive para la tabla
2062
2347
  * - scroll: scroll horizontal en mobile (default, más simple)
@@ -2064,11 +2349,11 @@ class PdmTableComponent {
2064
2349
  * - stack: convierte filas en cards en mobile (requiere data-label en celdas)
2065
2350
  * - collapse: oculta columnas menos importantes en mobile
2066
2351
  */
2067
- this.responsiveStrategy = 'scroll';
2352
+ this.responsiveStrategy = "scroll";
2068
2353
  /**
2069
2354
  * Clases CSS adicionales para el wrapper
2070
2355
  */
2071
- this.className = '';
2356
+ this.className = "";
2072
2357
  /**
2073
2358
  * Si es true, aplica padding negativo en mobile para scroll edge-to-edge
2074
2359
  * Útil cuando la tabla está dentro de un container con padding
@@ -2076,119 +2361,128 @@ class PdmTableComponent {
2076
2361
  this.fullBleed = false;
2077
2362
  }
2078
2363
  get wrapperClasses() {
2079
- const baseClasses = ['relative', 'w-full'];
2364
+ const baseClasses = ["relative", "w-full"];
2080
2365
  const strategyClasses = this.getResponsiveStrategyClasses();
2081
2366
  const variantClasses = this.getVariantWrapperClasses();
2082
2367
  // 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');
2368
+ if (this.fullBleed && this.responsiveStrategy === "scroll") {
2369
+ baseClasses.push("-mx-4", "px-4", "sm:mx-0", "sm:px-0");
2085
2370
  }
2086
2371
  return [
2087
2372
  ...baseClasses,
2088
2373
  ...strategyClasses,
2089
2374
  ...variantClasses,
2090
- this.className
2375
+ this.className,
2091
2376
  ].filter(Boolean);
2092
2377
  }
2093
2378
  get tableClasses() {
2094
- const baseClasses = ['w-full', 'caption-bottom', 'text-sm'];
2379
+ const baseClasses = ["w-full", "caption-bottom", "text-sm"];
2095
2380
  const variantClasses = this.getVariantTableClasses();
2096
2381
  const cellClasses = this.getCellClasses();
2097
2382
  return [...baseClasses, ...variantClasses, ...cellClasses].filter(Boolean);
2098
2383
  }
2099
2384
  getResponsiveStrategyClasses() {
2100
2385
  const strategy = TABLE_RESPONSIVE[this.responsiveStrategy];
2101
- if (this.responsiveStrategy === 'scroll') {
2102
- return ['overflow-x-auto'];
2386
+ if (this.responsiveStrategy === "scroll") {
2387
+ return ["overflow-x-auto"];
2103
2388
  }
2104
- if (this.responsiveStrategy === 'wrap') {
2105
- return ['overflow-x-auto'];
2389
+ if (this.responsiveStrategy === "wrap") {
2390
+ return ["overflow-x-auto"];
2106
2391
  }
2107
- if (this.responsiveStrategy === 'stack') {
2392
+ if (this.responsiveStrategy === "stack") {
2108
2393
  // Stack requiere lógica en el template, aquí solo el wrapper
2109
2394
  return [];
2110
2395
  }
2111
- if (this.responsiveStrategy === 'collapse') {
2112
- return ['overflow-x-auto'];
2396
+ if (this.responsiveStrategy === "collapse") {
2397
+ return ["overflow-x-auto"];
2113
2398
  }
2114
- return ['overflow-auto'];
2399
+ return ["overflow-auto"];
2115
2400
  }
2116
2401
  getVariantWrapperClasses() {
2117
- if (this.variant === 'interactive') {
2118
- return ['rounded-xl', 'border', 'border-border', 'bg-background'];
2402
+ if (this.variant === "interactive") {
2403
+ return ["rounded-xl", "border", "border-border", "bg-background"];
2119
2404
  }
2120
- if (this.variant === 'data') {
2121
- return ['rounded-md', 'border', 'border-border', 'bg-background'];
2405
+ if (this.variant === "data") {
2406
+ return ["rounded-md", "border", "border-border", "bg-background"];
2122
2407
  }
2123
2408
  return [];
2124
2409
  }
2125
2410
  getVariantTableClasses() {
2126
- if (this.variant === 'data') {
2411
+ if (this.variant === "data") {
2127
2412
  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'
2413
+ "border-collapse",
2414
+ "text-foreground",
2415
+ "[&_thead_tr]:border-b",
2416
+ "[&_thead_tr]:border-border",
2417
+ "[&_tbody_tr]:border-b",
2418
+ "[&_tbody_tr]:border-border",
2419
+ "[&_tbody_tr:last-child]:border-b-0",
2420
+ "[&_th]:h-10",
2421
+ "[&_th]:px-2",
2422
+ "[&_th]:text-left",
2423
+ "[&_th]:align-middle",
2424
+ "[&_th]:font-medium",
2425
+ "[&_td]:p-2",
2426
+ "[&_td]:align-middle",
2142
2427
  ];
2143
2428
  }
2144
- if (this.variant === 'interactive') {
2429
+ if (this.variant === "interactive") {
2145
2430
  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'
2431
+ "text-foreground",
2432
+ "[&_thead]:sticky",
2433
+ "[&_thead]:top-0",
2434
+ "[&_thead]:z-10",
2435
+ "[&_thead]:bg-muted/70",
2436
+ "[&_thead_tr]:border-b",
2437
+ "[&_thead_tr]:border-border",
2438
+ "[&_th]:h-12",
2439
+ "[&_th]:px-4",
2440
+ "[&_th]:text-left",
2441
+ "[&_th]:align-middle",
2442
+ "[&_th]:text-sm",
2443
+ "[&_th]:font-medium",
2444
+ "[&_tbody_tr]:border-b",
2445
+ "[&_tbody_tr]:border-border",
2446
+ "[&_tbody_tr]:transition-colors",
2447
+ "[&_tbody_tr:hover]:bg-muted/50",
2448
+ "[&_tbody_tr:last-child]:border-b-0",
2449
+ "[&_td]:h-14",
2450
+ "[&_td]:px-4",
2451
+ "[&_td]:align-middle",
2452
+ "[&_td]:text-sm",
2453
+ "[&_svg]:text-muted-foreground",
2169
2454
  ];
2170
2455
  }
2171
2456
  return [];
2172
2457
  }
2173
2458
  getCellClasses() {
2174
2459
  // Manejo responsive de whitespace
2175
- if (this.responsiveStrategy === 'scroll') {
2460
+ if (this.responsiveStrategy === "scroll") {
2176
2461
  // 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'];
2462
+ return [
2463
+ "[&_td]:whitespace-normal",
2464
+ "[&_th]:whitespace-normal",
2465
+ "sm:[&_td]:whitespace-nowrap",
2466
+ "sm:[&_th]:whitespace-nowrap",
2467
+ ];
2178
2468
  }
2179
- if (this.responsiveStrategy === 'wrap') {
2469
+ if (this.responsiveStrategy === "wrap") {
2180
2470
  // En wrap, siempre permitir wrap
2181
- return ['[&_td]:whitespace-normal', '[&_td]:break-words', '[&_th]:whitespace-normal'];
2471
+ return [
2472
+ "[&_td]:whitespace-normal",
2473
+ "[&_td]:break-words",
2474
+ "[&_th]:whitespace-normal",
2475
+ ];
2182
2476
  }
2183
2477
  // Default: nowrap (comportamiento anterior para backward compatibility)
2184
2478
  return [];
2185
2479
  }
2186
2480
  }
2187
2481
  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 });
2482
+ 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
2483
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTableComponent, decorators: [{
2190
2484
  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" }]
2485
+ 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
2486
  }], propDecorators: { variant: [{
2193
2487
  type: Input
2194
2488
  }], responsiveStrategy: [{
@@ -2434,10 +2728,10 @@ class PdmDataTableComponent {
2434
2728
  }
2435
2729
  }
2436
2730
  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 });
2731
+ 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
2732
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDataTableComponent, decorators: [{
2439
2733
  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" }]
2734
+ 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
2735
  }], propDecorators: { className: [{
2442
2736
  type: Input
2443
2737
  }], columns: [{
@@ -2570,8 +2864,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
2570
2864
 
2571
2865
  let nextDatePickerId = 0;
2572
2866
  class PdmDatePickerComponent {
2573
- constructor(elementRef, cdr, overlay, viewContainerRef) {
2574
- this.elementRef = elementRef;
2867
+ constructor(cdr, overlay, viewContainerRef) {
2575
2868
  this.cdr = cdr;
2576
2869
  this.overlay = overlay;
2577
2870
  this.viewContainerRef = viewContainerRef;
@@ -2582,21 +2875,21 @@ class PdmDatePickerComponent {
2582
2875
  this.triggerFocused = false;
2583
2876
  this.overlayRef = null;
2584
2877
  this.backdropSub = null;
2585
- this.id = '';
2586
- this.variant = 'single';
2587
- this.label = '';
2588
- this.labelClassName = '';
2589
- this.className = '';
2590
- this.triggerClassName = '';
2878
+ this.id = "";
2879
+ this.variant = "single";
2880
+ this.label = "";
2881
+ this.labelClassName = "";
2882
+ this.className = "";
2883
+ this.triggerClassName = "";
2591
2884
  /**
2592
2885
  * Additional CSS classes applied to the overlay panel.
2593
2886
  * Backward-compatible: mapped to `overlayOptions.panelClass` when `overlayOptions` is not set.
2594
2887
  * When both are supplied, `overlayOptions.panelClass` takes precedence.
2595
2888
  */
2596
- this.panelClassName = '';
2597
- this.placeholder = 'Pick a date';
2598
- this.rangePlaceholder = 'Pick a date range';
2599
- this.format = 'MMM d, yyyy';
2889
+ this.panelClassName = "";
2890
+ this.placeholder = "Pick a date";
2891
+ this.rangePlaceholder = "Pick a date range";
2892
+ this.format = "MMM d, yyyy";
2600
2893
  this.disabled = false;
2601
2894
  this.readonly = false;
2602
2895
  this.required = false;
@@ -2617,7 +2910,7 @@ class PdmDatePickerComponent {
2617
2910
  set open(value) {
2618
2911
  if (this._open === !!value)
2619
2912
  return;
2620
- if (!!value) {
2913
+ if (value) {
2621
2914
  this.openPanel();
2622
2915
  }
2623
2916
  else {
@@ -2638,7 +2931,7 @@ class PdmDatePickerComponent {
2638
2931
  this._rangeValue = value
2639
2932
  ? {
2640
2933
  start: this.normalizeDate(value.start),
2641
- end: this.normalizeDate(value.end)
2934
+ end: this.normalizeDate(value.end),
2642
2935
  }
2643
2936
  : null;
2644
2937
  this.cdr.markForCheck();
@@ -2650,7 +2943,7 @@ class PdmDatePickerComponent {
2650
2943
  this.destroyOverlay();
2651
2944
  }
2652
2945
  get resolvedVariant() {
2653
- return this.variant === 'range' ? 'range' : 'single';
2946
+ return this.variant === "range" ? "range" : "single";
2654
2947
  }
2655
2948
  get triggerId() {
2656
2949
  return this.id || `${this.instanceId}-trigger`;
@@ -2659,15 +2952,15 @@ class PdmDatePickerComponent {
2659
2952
  return `${this.id || this.instanceId}-panel`;
2660
2953
  }
2661
2954
  get hasSingleValue() {
2662
- return this.resolvedVariant === 'single' && !!this._value;
2955
+ return this.resolvedVariant === "single" && !!this._value;
2663
2956
  }
2664
2957
  get hasRangeValue() {
2665
2958
  var _a;
2666
- return this.resolvedVariant === 'range' && !!((_a = this._rangeValue) === null || _a === void 0 ? void 0 : _a.start);
2959
+ return this.resolvedVariant === "range" && !!((_a = this._rangeValue) === null || _a === void 0 ? void 0 : _a.start);
2667
2960
  }
2668
2961
  get displayText() {
2669
2962
  var _a, _b, _c, _d;
2670
- if (this.resolvedVariant === 'single') {
2963
+ if (this.resolvedVariant === "single") {
2671
2964
  return this._value ? this.formatDate(this._value) : this.placeholder;
2672
2965
  }
2673
2966
  const start = (_b = (_a = this._rangeValue) === null || _a === void 0 ? void 0 : _a.start) !== null && _b !== void 0 ? _b : null;
@@ -2681,29 +2974,29 @@ class PdmDatePickerComponent {
2681
2974
  return `${this.formatDate(start)} - ${this.formatDate(end)}`;
2682
2975
  }
2683
2976
  get textClasses() {
2684
- const hasValue = this.resolvedVariant === 'single' ? this.hasSingleValue : this.hasRangeValue;
2977
+ const hasValue = this.resolvedVariant === "single"
2978
+ ? this.hasSingleValue
2979
+ : this.hasRangeValue;
2685
2980
  return [
2686
- 'min-w-0 flex-1 truncate text-left text-sm leading-5',
2687
- hasValue ? 'text-foreground' : 'text-muted-foreground'
2981
+ "min-w-0 flex-1 truncate text-left text-sm leading-5",
2982
+ hasValue ? "text-foreground" : "text-muted-foreground",
2688
2983
  ];
2689
2984
  }
2690
2985
  get rootClasses() {
2691
2986
  return [
2692
- 'grid gap-2',
2693
- this.resolvedVariant === 'range' ? 'w-[280px]' : 'w-[197px]',
2694
- this.className
2987
+ "grid gap-2",
2988
+ this.resolvedVariant === "range" ? "w-[280px]" : "w-[197px]",
2989
+ this.className,
2695
2990
  ];
2696
2991
  }
2697
2992
  get triggerClasses() {
2698
2993
  const focusStyle = this._open || this.triggerFocused;
2699
2994
  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
2995
+ "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",
2996
+ "min-h-[36px] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
2997
+ focusStyle ? "border-ring ring-2 ring-ring/50" : "",
2998
+ this.invalid ? "border-destructive ring-destructive/20" : "",
2999
+ this.triggerClassName,
2707
3000
  ];
2708
3001
  }
2709
3002
  toggleOpen() {
@@ -2735,16 +3028,22 @@ class PdmDatePickerComponent {
2735
3028
  this._rangeValue = value
2736
3029
  ? {
2737
3030
  start: this.normalizeDate(value.start),
2738
- end: this.normalizeDate(value.end)
3031
+ end: this.normalizeDate(value.end),
2739
3032
  }
2740
3033
  : null;
2741
3034
  this.rangeValueChange.emit(this._rangeValue
2742
3035
  ? {
2743
- start: this._rangeValue.start ? this.cloneDate(this._rangeValue.start) : null,
2744
- end: this._rangeValue.end ? this.cloneDate(this._rangeValue.end) : null
3036
+ start: this._rangeValue.start
3037
+ ? this.cloneDate(this._rangeValue.start)
3038
+ : null,
3039
+ end: this._rangeValue.end
3040
+ ? this.cloneDate(this._rangeValue.end)
3041
+ : null,
2745
3042
  }
2746
3043
  : 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)) {
3044
+ if (this.closeOnSelect &&
3045
+ ((_a = this._rangeValue) === null || _a === void 0 ? void 0 : _a.start) &&
3046
+ ((_b = this._rangeValue) === null || _b === void 0 ? void 0 : _b.end)) {
2748
3047
  this.setOpen(false);
2749
3048
  return;
2750
3049
  }
@@ -2770,7 +3069,7 @@ class PdmDatePickerComponent {
2770
3069
  }
2771
3070
  }
2772
3071
  openPanel() {
2773
- var _a, _b, _c;
3072
+ var _a, _b;
2774
3073
  if (this.overlayRef)
2775
3074
  return;
2776
3075
  const triggerEl = (_a = this.triggerRef) === null || _a === void 0 ? void 0 : _a.nativeElement;
@@ -2780,14 +3079,21 @@ class PdmDatePickerComponent {
2780
3079
  this.openChange.emit(true);
2781
3080
  this.cdr.markForCheck();
2782
3081
  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']);
3082
+ // CRITICAL: Use mergeOverlayPanelClass to ensure z-index is never lost.
3083
+ // Consumer classes are appended AFTER base z-index.
3084
+ const zIndexEnforced = mergeOverlayPanelClass(OVERLAY_BASE_Z_INDEX, this.panelClassName);
3085
+ // Resolve panelClass: overlayOptions.panelClass wins; otherwise use z-index enforced.
3086
+ const resolvedPanelClass = ((_b = this.overlayOptions) === null || _b === void 0 ? void 0 : _b.panelClass)
3087
+ ? mergeOverlayPanelClass(OVERLAY_BASE_Z_INDEX, this.overlayOptions.panelClass)
3088
+ : zIndexEnforced;
2785
3089
  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.
3090
+ // panelClass always enforced last to preserve z-index.
2787
3091
  panelClass: resolvedPanelClass }));
2788
3092
  const portal = new TemplatePortal(this.panelTemplateRef, this.viewContainerRef);
2789
3093
  this.overlayRef.attach(portal);
2790
- this.backdropSub = this.overlayRef.outsidePointerEvents().subscribe((event) => {
3094
+ this.backdropSub = this.overlayRef
3095
+ .outsidePointerEvents()
3096
+ .subscribe((event) => {
2791
3097
  const target = event.target;
2792
3098
  if (!triggerEl.contains(target)) {
2793
3099
  this.closePanel();
@@ -2815,10 +3121,10 @@ class PdmDatePickerComponent {
2815
3121
  }
2816
3122
  formatDate(date) {
2817
3123
  try {
2818
- return format(date, this.format || 'MMM d, yyyy');
3124
+ return format(date, this.format || "MMM d, yyyy");
2819
3125
  }
2820
3126
  catch (_a) {
2821
- return format(date, 'MMM d, yyyy');
3127
+ return format(date, "MMM d, yyyy");
2822
3128
  }
2823
3129
  }
2824
3130
  normalizeDate(value) {
@@ -2831,17 +3137,17 @@ class PdmDatePickerComponent {
2831
3137
  return new Date(date.getFullYear(), date.getMonth(), date.getDate());
2832
3138
  }
2833
3139
  }
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 });
3140
+ 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
3141
  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
3142
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDatePickerComponent, decorators: [{
2837
3143
  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: [{
3144
+ 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" }]
3145
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i1$1.Overlay }, { type: i0.ViewContainerRef }]; }, propDecorators: { triggerRef: [{
2840
3146
  type: ViewChild,
2841
- args: ['triggerEl']
3147
+ args: ["triggerEl"]
2842
3148
  }], panelTemplateRef: [{
2843
3149
  type: ViewChild,
2844
- args: ['panelTemplate']
3150
+ args: ["panelTemplate"]
2845
3151
  }], id: [{
2846
3152
  type: Input
2847
3153
  }], variant: [{
@@ -2904,7 +3210,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
2904
3210
  type: Input
2905
3211
  }], onEscape: [{
2906
3212
  type: HostListener,
2907
- args: ['document:keydown.escape']
3213
+ args: ["document:keydown.escape"]
2908
3214
  }] } });
2909
3215
 
2910
3216
  /**
@@ -2914,15 +3220,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
2914
3220
  * 1. base (z-0) - Elementos normales del DOM
2915
3221
  * 2. dropdown (z-10) - Selects, combobox, date-pickers
2916
3222
  * 3. sticky (z-20) - Headers, navigation bars
2917
- * 4. overlay (z-30) - Popovers, hover cards, context menus
3223
+ * 4. drawerBackdrop (z-30) - Backdrop de drawers
2918
3224
  * 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
3225
+ * 6. modalBackdrop (z-40) - Backdrop de modals ( mismo nivel que drawer)
3226
+ * 7. modal (z-50) - Dialogs, alert-dialogs
3227
+ * 8. popover (z-[70]) - Tooltips, dropdowns DENTRO de modals
2922
3228
  * 9. toast (z-[100]) - Notificaciones que deben estar sobre TODO
2923
3229
  *
2924
3230
  * REGLA CRÍTICA:
2925
- * - Componentes overlay (select options, dropdown menu, tooltip) SIEMPRE z-60 o mayor
3231
+ * - Componentes overlay (select options, dropdown menu, tooltip) SIEMPRE z-[70] o mayor
2926
3232
  * - Esto permite que funcionen DENTRO de modals (z-50)
2927
3233
  * - Backdrop de modal debe ser z-40 para estar DEBAJO del contenido del modal (z-50)
2928
3234
  */
@@ -2930,57 +3236,53 @@ const Z_INDEX = {
2930
3236
  /**
2931
3237
  * Base - contenido normal del DOM
2932
3238
  */
2933
- base: 'z-0',
3239
+ base: "z-0",
2934
3240
  /**
2935
3241
  * Dropdown - Selects, combobox, date-pickers
2936
- * Debe estar SOBRE contenido normal pero BAJO modals
3242
+ * Debe estar SOBRE contenido normal pero BAJO overlays
2937
3243
  */
2938
- dropdown: 'z-10',
3244
+ dropdown: "z-10",
2939
3245
  /**
2940
3246
  * Sticky - Headers, navigation fija
2941
3247
  */
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',
3248
+ sticky: "z-20",
2948
3249
  /**
2949
3250
  * Drawer backdrop - Backdrop de sidebar drawer
2950
- * Debe estar DEBAJO del drawer panel
3251
+ * Debe estar DEBAJO del drawer panel y DEBAJO de modals
2951
3252
  */
2952
- drawerBackdrop: 'z-40',
3253
+ drawerBackdrop: "z-30",
2953
3254
  /**
2954
3255
  * Drawer - Sidebar drawer, sheets laterales
2955
3256
  * Debe estar SOBRE su backdrop pero BAJO modals
2956
3257
  */
2957
- drawer: 'z-50',
3258
+ drawer: "z-40",
2958
3259
  /**
2959
3260
  * Modal backdrop - Backdrop de dialogs
2960
- * Debe estar SOBRE drawers pero DEBAJO del contenido del modal
3261
+ * Mismo nivel que drawer backdrop (z-40)
2961
3262
  */
2962
- modalBackdrop: 'z-50',
3263
+ modalBackdrop: "z-40",
2963
3264
  /**
2964
- * Modal - Dialogs, alert-dialogs, sheets
3265
+ * Modal - Dialogs, alert-dialogs
2965
3266
  * Debe estar SOBRE su backdrop
2966
3267
  */
2967
- modal: 'z-[60]',
3268
+ modal: "z-50",
2968
3269
  /**
2969
3270
  * Popover - Tooltips, dropdowns, selects options DENTRO de modals
2970
3271
  * CRÍTICO: Debe ser MAYOR que modal (z-50) para aparecer sobre modals
3272
+ * USAR SIEMPRE mergeOverlayPanelClass() para asegurar este valor
2971
3273
  */
2972
- popover: 'z-[70]',
3274
+ popover: "z-[70]",
2973
3275
  /**
2974
3276
  * Toast - Notificaciones globales
2975
3277
  * Debe estar sobre TODO
2976
3278
  */
2977
- toast: 'z-[100]'
3279
+ toast: "z-[100]",
2978
3280
  };
2979
3281
  /**
2980
3282
  * Helper para debugging z-index issues
2981
3283
  */
2982
3284
  function logZIndexStack(element) {
2983
- if (typeof window === 'undefined')
3285
+ if (typeof window === "undefined")
2984
3286
  return;
2985
3287
  let current = element;
2986
3288
  const stack = [];
@@ -2988,11 +3290,12 @@ function logZIndexStack(element) {
2988
3290
  const computed = window.getComputedStyle(current);
2989
3291
  const zIndex = computed.zIndex;
2990
3292
  const position = computed.position;
2991
- if (zIndex !== 'auto') {
3293
+ if (zIndex !== "auto") {
2992
3294
  stack.push({
2993
- element: current.tagName + (current.className ? `.${current.className.split(' ')[0]}` : ''),
3295
+ element: current.tagName +
3296
+ (current.className ? `.${current.className.split(" ")[0]}` : ""),
2994
3297
  zIndex,
2995
- position
3298
+ position,
2996
3299
  });
2997
3300
  }
2998
3301
  current = current.parentElement;
@@ -3023,7 +3326,7 @@ function logZIndexStack(element) {
3023
3326
  class PdmDialogComponent {
3024
3327
  constructor() {
3025
3328
  this.open = false;
3026
- this.variant = 'default';
3329
+ this.variant = "default";
3027
3330
  /**
3028
3331
  * Tamaño del dialog
3029
3332
  * - responsive: fullscreen mobile, modal desktop (recomendado)
@@ -3033,21 +3336,21 @@ class PdmDialogComponent {
3033
3336
  * - xl: 800px max
3034
3337
  * - desktop/mobile/mobile-fullscreen: legacy, deprecado
3035
3338
  */
3036
- this.size = 'responsive';
3037
- this.title = 'Edit profile';
3038
- this.description = '';
3339
+ this.size = "responsive";
3340
+ this.title = "Edit profile";
3341
+ this.description = "";
3039
3342
  this.closeOnBackdrop = true;
3040
3343
  this.closeOnEsc = true;
3041
3344
  this.showCloseButton = true;
3042
3345
  this.showHeader = true;
3043
3346
  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 = '';
3347
+ this.primaryActionText = "Save changes";
3348
+ this.secondaryActionText = "Cancel";
3349
+ this.alignFooter = "right";
3350
+ this.headerClassName = "";
3351
+ this.bodyClassName = "";
3352
+ this.footerClassName = "";
3353
+ this.className = "";
3051
3354
  this.openChange = new EventEmitter();
3052
3355
  this.primaryAction = new EventEmitter();
3053
3356
  this.secondaryAction = new EventEmitter();
@@ -3073,131 +3376,148 @@ class PdmDialogComponent {
3073
3376
  }
3074
3377
  get panelClassName() {
3075
3378
  // Legacy sizes (backward compatibility)
3076
- if (this.size === 'desktop') {
3077
- return this.buildClasses(['max-w-[640px]', 'max-h-[calc(100vh-2rem)]', 'rounded-[10px]']);
3379
+ if (this.size === "desktop") {
3380
+ return this.buildPanelClasses([
3381
+ "max-w-[640px]",
3382
+ "max-h-[calc(100vh-2rem)]",
3383
+ "rounded-[10px]",
3384
+ ]);
3078
3385
  }
3079
- if (this.size === 'mobile') {
3080
- return this.buildClasses(['max-w-[320px]', 'min-h-[240px]', 'rounded-[10px]']);
3386
+ if (this.size === "mobile") {
3387
+ return this.buildPanelClasses([
3388
+ "max-w-[320px]",
3389
+ "min-h-[240px]",
3390
+ "rounded-[10px]",
3391
+ ]);
3081
3392
  }
3082
- if (this.size === 'mobile-fullscreen') {
3083
- return this.buildClasses(['max-w-[320px]', 'h-[min(100dvh,640px)]', 'rounded-none', 'sm:rounded-[10px]']);
3393
+ if (this.size === "mobile-fullscreen") {
3394
+ return this.buildPanelClasses([
3395
+ "max-w-[320px]",
3396
+ "h-[min(100dvh,640px)]",
3397
+ "rounded-none",
3398
+ "sm:rounded-[10px]",
3399
+ ]);
3084
3400
  }
3085
3401
  // New responsive mode (recomendado)
3086
- if (this.size === 'responsive') {
3087
- return this.buildClasses([
3402
+ if (this.size === "responsive") {
3403
+ return this.buildPanelClasses([
3088
3404
  // 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]',
3405
+ "w-full",
3406
+ "h-full",
3407
+ "max-h-[100dvh]",
3408
+ "rounded-t-[10px]",
3409
+ "sm:rounded-[10px]",
3094
3410
  // Desktop: modal centrado
3095
- 'sm:w-auto',
3096
- 'sm:h-auto',
3097
- 'sm:max-w-[640px]',
3098
- 'sm:max-h-[calc(100vh-4rem)]'
3411
+ "sm:w-auto",
3412
+ "sm:h-auto",
3413
+ "sm:max-w-[640px]",
3414
+ "sm:max-h-[calc(100vh-4rem)]",
3099
3415
  ]);
3100
3416
  }
3101
3417
  // New size options
3102
3418
  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]'
3419
+ sm: "sm:max-w-[400px]",
3420
+ md: "sm:max-w-[500px]",
3421
+ lg: "sm:max-w-[640px]",
3422
+ xl: "sm:max-w-[800px]",
3107
3423
  };
3108
3424
  const maxWidth = sizeMap[this.size] || sizeMap.lg;
3109
- return this.buildClasses([
3425
+ return this.buildPanelClasses([
3110
3426
  // Mobile: fullscreen
3111
- 'w-full',
3112
- 'h-full',
3113
- 'max-h-[100dvh]',
3114
- 'rounded-t-[10px]',
3427
+ "w-full",
3428
+ "h-full",
3429
+ "max-h-[100dvh]",
3430
+ "rounded-t-[10px]",
3115
3431
  // Desktop: modal
3116
- 'sm:rounded-[10px]',
3117
- 'sm:w-auto',
3118
- 'sm:h-auto',
3432
+ "sm:rounded-[10px]",
3433
+ "sm:w-auto",
3434
+ "sm:h-auto",
3119
3435
  maxWidth,
3120
- 'sm:max-h-[calc(100vh-4rem)]'
3436
+ "sm:max-h-[calc(100vh-4rem)]",
3121
3437
  ]);
3122
3438
  }
3123
- buildClasses(sizeClasses) {
3439
+ buildPanelClasses(sizeClasses) {
3124
3440
  const base = [
3125
- 'relative',
3441
+ "relative",
3126
3442
  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',
3443
+ "flex",
3444
+ "flex-col",
3445
+ "border",
3446
+ "border-border",
3447
+ "bg-background",
3448
+ "text-foreground",
3449
+ "shadow-lg",
3450
+ "overflow-hidden",
3135
3451
  ...sizeClasses,
3136
- this.className
3452
+ this.className,
3137
3453
  ];
3138
- return base.filter(Boolean).join(' ');
3454
+ return base.filter(Boolean).join(" ");
3139
3455
  }
3140
3456
  get bodyWrapperClassName() {
3457
+ // min-h-0 is CRITICAL for flex child to shrink and allow internal scroll
3141
3458
  const base = [
3142
- 'flex-1',
3143
- 'overflow-y-auto',
3144
- 'px-4',
3145
- 'py-6',
3146
- 'sm:px-6',
3147
- this.bodyClassName
3459
+ "flex-1",
3460
+ "min-h-0",
3461
+ "overflow-y-auto",
3462
+ "px-4",
3463
+ "py-6",
3464
+ "sm:px-6",
3465
+ this.bodyClassName,
3148
3466
  ];
3149
- return base.filter(Boolean).join(' ');
3467
+ return base.filter(Boolean).join(" ");
3150
3468
  }
3151
3469
  get headerWrapperClassName() {
3152
3470
  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
3471
+ "flex",
3472
+ "items-start",
3473
+ "justify-between",
3474
+ "gap-3",
3475
+ "p-4",
3476
+ "sm:p-6",
3477
+ "border-b",
3478
+ "border-border",
3479
+ this.headerClassName,
3162
3480
  ];
3163
- return base.filter(Boolean).join(' ');
3481
+ return base.filter(Boolean).join(" ");
3164
3482
  }
3165
3483
  get footerWrapperClassName() {
3166
- const effectiveAlign = this.alignFooter === 'right' && this.variant === 'custom-close' ? 'left' : this.alignFooter;
3484
+ const effectiveAlign = this.alignFooter === "right" && this.variant === "custom-close"
3485
+ ? "left"
3486
+ : this.alignFooter;
3167
3487
  const base = [
3168
- 'p-4',
3169
- 'sm:p-6',
3170
- 'border-t',
3171
- 'border-border',
3488
+ "p-4",
3489
+ "sm:p-6",
3490
+ "border-t",
3491
+ "border-border",
3172
3492
  // Mobile: siempre full-width
3173
- 'flex',
3174
- 'flex-col',
3175
- 'gap-2',
3493
+ "flex",
3494
+ "flex-col",
3495
+ "gap-2",
3176
3496
  // 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
3497
+ effectiveAlign === "full-width"
3498
+ ? "sm:flex-col"
3499
+ : "sm:flex-row sm:items-center",
3500
+ effectiveAlign === "left" ? "sm:justify-start" : "",
3501
+ effectiveAlign === "right" ? "sm:justify-end" : "",
3502
+ this.footerClassName,
3183
3503
  ];
3184
- return base.filter(Boolean).join(' ');
3504
+ return base.filter(Boolean).join(" ");
3185
3505
  }
3186
3506
  get containerClassName() {
3187
- // Container con backdrop z-50
3507
+ // Container con backdrop z-40
3188
3508
  // Mobile: fullscreen desde el bottom
3189
3509
  // Desktop: centrado
3190
3510
  return responsive({
3191
3511
  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`
3512
+ sm: `fixed inset-0 ${Z_INDEX.modalBackdrop} flex items-center justify-center p-4`,
3193
3513
  });
3194
3514
  }
3195
3515
  }
3196
3516
  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 });
3517
+ 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
3518
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDialogComponent, decorators: [{
3199
3519
  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" }]
3520
+ 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
3521
  }], propDecorators: { open: [{
3202
3522
  type: Input
3203
3523
  }], variant: [{
@@ -3240,7 +3560,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
3240
3560
  type: Output
3241
3561
  }], onEsc: [{
3242
3562
  type: HostListener,
3243
- args: ['document:keydown.escape']
3563
+ args: ["document:keydown.escape"]
3244
3564
  }] } });
3245
3565
 
3246
3566
  /**
@@ -3686,12 +4006,12 @@ class PdmDropdownMenuComponent {
3686
4006
  }
3687
4007
  }
3688
4008
  }
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 });
4009
+ 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
4010
  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
4011
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDropdownMenuComponent, decorators: [{
3692
4012
  type: Component,
3693
4013
  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: [{
4014
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i1$1.Overlay }, { type: i0.ViewContainerRef }]; }, propDecorators: { triggerText: [{
3695
4015
  type: Input
3696
4016
  }], variant: [{
3697
4017
  type: Input
@@ -4048,35 +4368,178 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
4048
4368
  }] } });
4049
4369
 
4050
4370
  class PdmHoverCardComponent {
4051
- constructor() {
4052
- this.className = '';
4053
- this.panelClassName = '';
4054
- this.side = 'bottom';
4055
- this.align = 'start';
4371
+ constructor(overlay, viewContainerRef, elementRef, cdr) {
4372
+ this.overlay = overlay;
4373
+ this.viewContainerRef = viewContainerRef;
4374
+ this.elementRef = elementRef;
4375
+ this.cdr = cdr;
4376
+ this.className = "";
4377
+ this.panelClassName = "";
4378
+ this.side = "bottom";
4379
+ this.align = "start";
4056
4380
  this.panelWidth = 304;
4057
4381
  this.open = false;
4382
+ this.overlayRef = null;
4383
+ this.showTimeout = null;
4384
+ this.hideTimeout = null;
4058
4385
  }
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'
4386
+ ngOnDestroy() {
4387
+ this.clearTimeouts();
4388
+ this.destroyOverlay();
4389
+ }
4390
+ onMouseEnter() {
4391
+ this.clearTimeouts();
4392
+ this.showTimeout = setTimeout(() => this.show(), 150);
4393
+ }
4394
+ onMouseLeave() {
4395
+ this.clearTimeouts();
4396
+ this.hideTimeout = setTimeout(() => this.hide(), 150);
4397
+ }
4398
+ onFocusIn() {
4399
+ this.clearTimeouts();
4400
+ this.show();
4401
+ }
4402
+ onFocusOut() {
4403
+ this.clearTimeouts();
4404
+ this.hide();
4405
+ }
4406
+ clearTimeouts() {
4407
+ if (this.showTimeout) {
4408
+ clearTimeout(this.showTimeout);
4409
+ this.showTimeout = null;
4410
+ }
4411
+ if (this.hideTimeout) {
4412
+ clearTimeout(this.hideTimeout);
4413
+ this.hideTimeout = null;
4414
+ }
4415
+ }
4416
+ show() {
4417
+ if (this.open)
4418
+ return;
4419
+ this.open = true;
4420
+ this.cdr.markForCheck();
4421
+ this.createOverlay();
4422
+ }
4423
+ hide() {
4424
+ if (!this.open)
4425
+ return;
4426
+ this.open = false;
4427
+ this.cdr.markForCheck();
4428
+ this.destroyOverlay();
4429
+ }
4430
+ createOverlay() {
4431
+ if (this.overlayRef)
4432
+ return;
4433
+ const triggerEl = this.elementRef.nativeElement.querySelector("[pdmHoverTrigger]") ||
4434
+ this.elementRef.nativeElement;
4435
+ const positionStrategy = this.overlay
4436
+ .position()
4437
+ .flexibleConnectedTo(triggerEl)
4438
+ .withPositions(this.getPositionConfigs())
4439
+ .withFlexibleDimensions(false)
4440
+ .withPush(true);
4441
+ const panelClass = mergeOverlayPanelClass(OVERLAY_BASE_Z_INDEX, this.panelClassName);
4442
+ this.overlayRef = this.overlay.create({
4443
+ positionStrategy,
4444
+ panelClass,
4445
+ });
4446
+ const portal = new TemplatePortal(this.panelTemplateRef, this.viewContainerRef);
4447
+ this.overlayRef.attach(portal);
4448
+ }
4449
+ destroyOverlay() {
4450
+ if (this.overlayRef) {
4451
+ this.overlayRef.detach();
4452
+ this.overlayRef.dispose();
4453
+ this.overlayRef = null;
4454
+ }
4455
+ }
4456
+ getPositionConfigs() {
4457
+ // Map our side/align to CDK positions
4458
+ const configs = [];
4459
+ // Primary position based on side
4460
+ switch (this.side) {
4461
+ case "top":
4462
+ configs.push({
4463
+ originX: this.getAlignX(),
4464
+ originY: "top",
4465
+ overlayX: this.getAlignX(),
4466
+ overlayY: "bottom",
4467
+ offsetY: -8,
4468
+ });
4469
+ break;
4470
+ case "right":
4471
+ configs.push({
4472
+ originX: "end",
4473
+ originY: this.getAlignY(),
4474
+ overlayX: "start",
4475
+ overlayY: this.getAlignY(),
4476
+ offsetX: 8,
4477
+ });
4478
+ break;
4479
+ case "bottom":
4480
+ default:
4481
+ configs.push({
4482
+ originX: this.getAlignX(),
4483
+ originY: "bottom",
4484
+ overlayX: this.getAlignX(),
4485
+ overlayY: "top",
4486
+ offsetY: 8,
4487
+ });
4488
+ break;
4489
+ case "left":
4490
+ configs.push({
4491
+ originX: "start",
4492
+ originY: this.getAlignY(),
4493
+ overlayX: "end",
4494
+ overlayY: this.getAlignY(),
4495
+ offsetX: -8,
4496
+ });
4497
+ break;
4498
+ }
4499
+ // Add fallback positions
4500
+ switch (this.side) {
4501
+ case "top":
4502
+ case "bottom":
4503
+ configs.push({
4504
+ originX: "center",
4505
+ originY: this.side === "top" ? "top" : "bottom",
4506
+ overlayX: "center",
4507
+ overlayY: this.side === "top" ? "bottom" : "top",
4508
+ offsetY: this.side === "top" ? -8 : 8,
4509
+ });
4510
+ break;
4511
+ case "left":
4512
+ case "right":
4513
+ configs.push({
4514
+ originX: this.side === "left" ? "start" : "end",
4515
+ originY: "center",
4516
+ overlayX: this.side === "left" ? "end" : "start",
4517
+ overlayY: "center",
4518
+ offsetX: this.side === "left" ? -8 : 8,
4519
+ });
4520
+ break;
4521
+ }
4522
+ return configs;
4523
+ }
4524
+ getAlignX() {
4525
+ return this.align;
4526
+ }
4527
+ getAlignY() {
4528
+ // Map 'start'/'end' to 'top'/'bottom' for Y axis
4529
+ const alignMap = {
4530
+ start: "top",
4531
+ center: "center",
4532
+ end: "bottom",
4070
4533
  };
4071
- return `${sideClassMap[this.side]} ${alignClassMap[this.align]}`;
4534
+ return alignMap[this.align];
4072
4535
  }
4073
4536
  }
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 });
4537
+ 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 });
4538
+ 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
4539
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmHoverCardComponent, decorators: [{
4077
4540
  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: [{
4541
+ 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"] }]
4542
+ }], ctorParameters: function () { return [{ type: i1$1.Overlay }, { type: i0.ViewContainerRef }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { className: [{
4080
4543
  type: Input
4081
4544
  }], panelClassName: [{
4082
4545
  type: Input
@@ -4086,6 +4549,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
4086
4549
  type: Input
4087
4550
  }], panelWidth: [{
4088
4551
  type: Input
4552
+ }], panelTemplateRef: [{
4553
+ type: ViewChild,
4554
+ args: ["panelTemplate"]
4555
+ }], onMouseEnter: [{
4556
+ type: HostListener,
4557
+ args: ["mouseenter"]
4558
+ }], onMouseLeave: [{
4559
+ type: HostListener,
4560
+ args: ["mouseleave"]
4561
+ }], onFocusIn: [{
4562
+ type: HostListener,
4563
+ args: ["focusin"]
4564
+ }], onFocusOut: [{
4565
+ type: HostListener,
4566
+ args: ["focusout"]
4089
4567
  }] } });
4090
4568
 
4091
4569
  class PdmItemComponent {
@@ -4110,21 +4588,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
4110
4588
 
4111
4589
  class PdmInputComponent {
4112
4590
  constructor() {
4113
- this.id = '';
4114
- this.type = 'text';
4115
- this.value = '';
4116
- this.placeholder = '';
4591
+ this.id = "";
4592
+ this.type = "text";
4593
+ this.value = "";
4594
+ this.placeholder = "";
4117
4595
  this.disabled = false;
4118
4596
  this.readonly = false;
4119
4597
  this.required = false;
4120
4598
  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 = '';
4599
+ this.size = "regular";
4600
+ this.roundness = "default";
4601
+ this.className = "";
4602
+ this.inputClassName = "";
4603
+ this.label = "";
4604
+ this.helperText = "";
4605
+ this.errorText = "";
4128
4606
  this.valueChange = new EventEmitter();
4129
4607
  this.blurred = new EventEmitter();
4130
4608
  }
@@ -4136,10 +4614,10 @@ class PdmInputComponent {
4136
4614
  }
4137
4615
  }
4138
4616
  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 });
4617
+ 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
4618
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmInputComponent, decorators: [{
4141
4619
  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" }]
4620
+ 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
4621
  }], propDecorators: { id: [{
4144
4622
  type: Input
4145
4623
  }], type: [{
@@ -4253,18 +4731,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
4253
4731
 
4254
4732
  class PdmInputGroupComponent {
4255
4733
  constructor() {
4256
- this.id = '';
4257
- this.type = 'text';
4258
- this.value = '';
4259
- this.placeholder = '';
4734
+ this.id = "";
4735
+ this.type = "text";
4736
+ this.value = "";
4737
+ this.placeholder = "";
4260
4738
  this.disabled = false;
4261
4739
  this.invalid = false;
4262
- this.prefixText = '';
4263
- this.suffixText = '';
4264
- this.prefixIcon = '';
4265
- this.suffixIcon = '';
4266
- this.buttonText = '';
4267
- this.className = '';
4740
+ this.prefixText = "";
4741
+ this.suffixText = "";
4742
+ this.prefixIcon = "";
4743
+ this.suffixIcon = "";
4744
+ this.buttonText = "";
4745
+ this.className = "";
4268
4746
  this.valueChange = new EventEmitter();
4269
4747
  this.buttonClick = new EventEmitter();
4270
4748
  }
@@ -4276,10 +4754,10 @@ class PdmInputGroupComponent {
4276
4754
  }
4277
4755
  }
4278
4756
  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 });
4757
+ 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
4758
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmInputGroupComponent, decorators: [{
4281
4759
  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" }]
4760
+ 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
4761
  }], propDecorators: { id: [{
4284
4762
  type: Input
4285
4763
  }], type: [{
@@ -4464,35 +4942,57 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
4464
4942
  }] } });
4465
4943
 
4466
4944
  class PdmMenubarComponent {
4467
- constructor(elementRef, cdr) {
4945
+ constructor(overlay, viewContainerRef, elementRef, cdr) {
4946
+ this.overlay = overlay;
4947
+ this.viewContainerRef = viewContainerRef;
4468
4948
  this.elementRef = elementRef;
4469
4949
  this.cdr = cdr;
4470
4950
  this.menus = [];
4471
- this.className = '';
4951
+ this.className = "";
4952
+ this.panelClassName = "";
4472
4953
  this.itemSelect = new EventEmitter();
4473
4954
  this.openIndex = -1;
4955
+ this.overlayRef = null;
4956
+ this.outsideClickSub = null;
4474
4957
  }
4475
- ngOnInit() {
4476
- this.boundPointerDown = (event) => this.onDocumentPointerDown(event);
4477
- document.addEventListener('pointerdown', this.boundPointerDown, { capture: true });
4478
- }
4958
+ ngOnInit() { }
4479
4959
  ngOnDestroy() {
4480
- if (this.boundPointerDown) {
4481
- document.removeEventListener('pointerdown', this.boundPointerDown, { capture: true });
4482
- }
4960
+ this.destroyOverlay();
4483
4961
  }
4484
- onEsc() {
4962
+ onDocumentClickOrEsc(event) {
4963
+ // Close on escape
4964
+ if (event.type === "keydown") {
4965
+ if (this.openIndex >= 0) {
4966
+ this.openIndex = -1;
4967
+ this.cdr.markForCheck();
4968
+ }
4969
+ return;
4970
+ }
4971
+ // Close on click outside
4485
4972
  if (this.openIndex >= 0) {
4486
- this.openIndex = -1;
4487
- this.cdr.markForCheck();
4973
+ const target = event.target;
4974
+ if (!this.elementRef.nativeElement.contains(target)) {
4975
+ this.openIndex = -1;
4976
+ this.cdr.markForCheck();
4977
+ }
4488
4978
  }
4489
4979
  }
4490
- toggle(index) {
4980
+ toggle(index, event) {
4981
+ event.stopPropagation();
4491
4982
  this.openIndex = this.openIndex === index ? -1 : index;
4983
+ this.cdr.markForCheck();
4984
+ if (this.openIndex >= 0) {
4985
+ this.createOverlay(event);
4986
+ }
4987
+ else {
4988
+ this.destroyOverlay();
4989
+ }
4492
4990
  }
4493
4991
  select(value) {
4494
4992
  this.itemSelect.emit(value);
4495
4993
  this.openIndex = -1;
4994
+ this.cdr.markForCheck();
4995
+ this.destroyOverlay();
4496
4996
  }
4497
4997
  selectItem(item) {
4498
4998
  if (item.disabled || !item.value) {
@@ -4500,32 +5000,83 @@ class PdmMenubarComponent {
4500
5000
  }
4501
5001
  this.select(item.value);
4502
5002
  }
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)) {
5003
+ createOverlay(event) {
5004
+ this.destroyOverlay();
5005
+ const triggerEl = event.currentTarget;
5006
+ const positionStrategy = this.overlay
5007
+ .position()
5008
+ .flexibleConnectedTo(triggerEl)
5009
+ .withPositions(this.getPositionConfigs())
5010
+ .withFlexibleDimensions(false)
5011
+ .withPush(true);
5012
+ const panelClass = mergeOverlayPanelClass(OVERLAY_BASE_Z_INDEX, this.panelClassName);
5013
+ this.overlayRef = this.overlay.create({
5014
+ positionStrategy,
5015
+ panelClass,
5016
+ });
5017
+ const portal = new TemplatePortal(this.menuTemplateRef, this.viewContainerRef);
5018
+ this.overlayRef.attach(portal);
5019
+ // Close on click outside
5020
+ this.outsideClickSub = this.overlayRef
5021
+ .outsidePointerEvents()
5022
+ .subscribe(() => {
4510
5023
  this.openIndex = -1;
4511
5024
  this.cdr.markForCheck();
5025
+ this.destroyOverlay();
5026
+ });
5027
+ }
5028
+ destroyOverlay() {
5029
+ if (this.outsideClickSub) {
5030
+ this.outsideClickSub.unsubscribe();
5031
+ this.outsideClickSub = null;
5032
+ }
5033
+ if (this.overlayRef) {
5034
+ this.overlayRef.detach();
5035
+ this.overlayRef.dispose();
5036
+ this.overlayRef = null;
4512
5037
  }
4513
5038
  }
5039
+ getPositionConfigs() {
5040
+ return [
5041
+ {
5042
+ originX: "start",
5043
+ originY: "bottom",
5044
+ overlayX: "start",
5045
+ overlayY: "top",
5046
+ offsetY: 4,
5047
+ },
5048
+ {
5049
+ originX: "start",
5050
+ originY: "top",
5051
+ overlayX: "start",
5052
+ overlayY: "bottom",
5053
+ offsetY: -4,
5054
+ },
5055
+ ];
5056
+ }
4514
5057
  }
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 });
5058
+ 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 });
5059
+ 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
5060
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmMenubarComponent, decorators: [{
4518
5061
  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: [{
5062
+ 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"] }]
5063
+ }], ctorParameters: function () { return [{ type: i1$1.Overlay }, { type: i0.ViewContainerRef }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { menus: [{
4521
5064
  type: Input
4522
5065
  }], className: [{
4523
5066
  type: Input
5067
+ }], panelClassName: [{
5068
+ type: Input
4524
5069
  }], itemSelect: [{
4525
5070
  type: Output
4526
- }], onEsc: [{
5071
+ }], menuTemplateRef: [{
5072
+ type: ViewChild,
5073
+ args: ["menuTemplate"]
5074
+ }], onDocumentClickOrEsc: [{
4527
5075
  type: HostListener,
4528
- args: ['document:keydown.escape']
5076
+ args: ["document:click"]
5077
+ }, {
5078
+ type: HostListener,
5079
+ args: ["document:keydown.escape"]
4529
5080
  }] } });
4530
5081
 
4531
5082
  class PdmNativeSelectComponent {
@@ -4744,18 +5295,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
4744
5295
  }] } });
4745
5296
 
4746
5297
  class PdmSelectComponent {
4747
- constructor(elementRef, cdr, overlay, viewContainerRef) {
4748
- this.elementRef = elementRef;
5298
+ constructor(cdr, overlay, viewContainerRef) {
4749
5299
  this.cdr = cdr;
4750
5300
  this.overlay = overlay;
4751
5301
  this.viewContainerRef = viewContainerRef;
4752
- this.id = '';
4753
- this.value = '';
5302
+ this.id = "";
5303
+ this.value = "";
4754
5304
  this.options = [];
4755
5305
  this.disabled = false;
4756
5306
  this.invalid = false;
4757
- this.className = '';
4758
- this.placeholder = 'Select an option';
5307
+ this.className = "";
5308
+ this.placeholder = "Select an option";
4759
5309
  this.open = false;
4760
5310
  this.valueChange = new EventEmitter();
4761
5311
  this.overlayRef = null;
@@ -4778,7 +5328,7 @@ class PdmSelectComponent {
4778
5328
  return this.projectedOptions.map((d) => ({
4779
5329
  label: d.resolvedLabel,
4780
5330
  value: d.value,
4781
- disabled: d.disabled
5331
+ disabled: d.disabled,
4782
5332
  }));
4783
5333
  }
4784
5334
  return this.options;
@@ -4830,7 +5380,9 @@ class PdmSelectComponent {
4830
5380
  panelClass: [Z_INDEX.popover], positionStrategy, scrollStrategy: this.overlay.scrollStrategies.reposition(), width: triggerEl.offsetWidth }, this.overlayOptions));
4831
5381
  const portal = new TemplatePortal(this.panelTemplateRef, this.viewContainerRef);
4832
5382
  this.overlayRef.attach(portal);
4833
- this.backdropSub = this.overlayRef.outsidePointerEvents().subscribe((event) => {
5383
+ this.backdropSub = this.overlayRef
5384
+ .outsidePointerEvents()
5385
+ .subscribe((event) => {
4834
5386
  const target = event.target;
4835
5387
  if (!triggerEl.contains(target)) {
4836
5388
  this.closePanel();
@@ -4856,12 +5408,12 @@ class PdmSelectComponent {
4856
5408
  }
4857
5409
  }
4858
5410
  }
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 });
5411
+ 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 });
5412
+ 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", 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
5413
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmSelectComponent, decorators: [{
4862
5414
  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: [{
5415
+ 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", styles: [":host{display:block}\n"] }]
5416
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i1$1.Overlay }, { type: i0.ViewContainerRef }]; }, propDecorators: { id: [{
4865
5417
  type: Input
4866
5418
  }], value: [{
4867
5419
  type: Input
@@ -4881,16 +5433,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
4881
5433
  type: Output
4882
5434
  }], triggerRef: [{
4883
5435
  type: ViewChild,
4884
- args: ['triggerEl']
5436
+ args: ["triggerEl"]
4885
5437
  }], panelTemplateRef: [{
4886
5438
  type: ViewChild,
4887
- args: ['panelTemplate']
5439
+ args: ["panelTemplate"]
4888
5440
  }], projectedOptions: [{
4889
5441
  type: ContentChildren,
4890
5442
  args: [PdmSelectOptionDirective]
4891
5443
  }], onEscape: [{
4892
5444
  type: HostListener,
4893
- args: ['document:keydown.escape']
5445
+ args: ["document:keydown.escape"]
4894
5446
  }] } });
4895
5447
 
4896
5448
  class PdmPaginationComponent {
@@ -4961,51 +5513,39 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
4961
5513
  }] } });
4962
5514
 
4963
5515
  class PdmPopoverComponent {
4964
- constructor(elementRef, cdr) {
5516
+ constructor(overlay, viewContainerRef, elementRef, cdr) {
5517
+ this.overlay = overlay;
5518
+ this.viewContainerRef = viewContainerRef;
4965
5519
  this.elementRef = elementRef;
4966
5520
  this.cdr = cdr;
4967
5521
  this._open = false;
4968
- this.triggerText = 'Open';
4969
- this.className = '';
4970
- this.panelClassName = '';
5522
+ this.triggerText = "Open";
5523
+ this.className = "";
5524
+ this.panelClassName = "";
4971
5525
  this.showTrigger = true;
4972
5526
  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 });
5527
+ this.overlayRef = null;
5528
+ this.outsideClickSub = null;
4978
5529
  }
5530
+ ngOnInit() { }
4979
5531
  ngOnDestroy() {
4980
- if (this.boundPointerDown) {
4981
- document.removeEventListener('pointerdown', this.boundPointerDown, { capture: true });
4982
- }
5532
+ this.destroyOverlay();
4983
5533
  }
4984
5534
  set open(value) {
4985
- this._open = !!value;
4986
- if (this._open) {
4987
- this.schedulePanelPlacementUpdate();
5535
+ if (this._open === !!value)
5536
+ return;
5537
+ if (value) {
5538
+ this.openPanel();
4988
5539
  }
4989
5540
  else {
4990
- this.panelPlacement = 'bottom';
5541
+ this.closePanel();
4991
5542
  }
4992
- this.cdr.markForCheck();
4993
5543
  }
4994
5544
  get open() {
4995
5545
  return this._open;
4996
5546
  }
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
5547
  toggle() {
5007
5548
  this.open = !this.open;
5008
- this.openChange.emit(this.open);
5009
5549
  }
5010
5550
  onEsc() {
5011
5551
  if (this.open) {
@@ -5013,49 +5553,100 @@ class PdmPopoverComponent {
5013
5553
  this.openChange.emit(false);
5014
5554
  }
5015
5555
  }
5016
- onViewportChange() {
5017
- this.updatePanelPlacement();
5018
- }
5019
- onDocumentPointerDown(event) {
5020
- if (!this.open)
5556
+ openPanel() {
5557
+ var _a;
5558
+ if (this.overlayRef)
5021
5559
  return;
5022
- const target = event.target;
5023
- if (target && !this.elementRef.nativeElement.contains(target)) {
5560
+ const triggerEl = (_a = this.triggerRef) === null || _a === void 0 ? void 0 : _a.nativeElement;
5561
+ if (!triggerEl)
5562
+ return;
5563
+ this._open = true;
5564
+ this.openChange.emit(true);
5565
+ this.cdr.markForCheck();
5566
+ const positionStrategy = this.overlay
5567
+ .position()
5568
+ .flexibleConnectedTo(triggerEl)
5569
+ .withPositions(this.getPositionConfigs())
5570
+ .withFlexibleDimensions(false)
5571
+ .withPush(true);
5572
+ const panelClass = mergeOverlayPanelClass(OVERLAY_BASE_Z_INDEX, this.panelClassName);
5573
+ this.overlayRef = this.overlay.create({
5574
+ positionStrategy,
5575
+ panelClass,
5576
+ });
5577
+ const portal = new TemplatePortal(this.panelTemplateRef, this.viewContainerRef);
5578
+ this.overlayRef.attach(portal);
5579
+ // Close on click outside
5580
+ this.outsideClickSub = this.overlayRef
5581
+ .outsidePointerEvents()
5582
+ .subscribe(() => {
5024
5583
  this.open = false;
5025
5584
  this.openChange.emit(false);
5026
- }
5027
- }
5028
- schedulePanelPlacementUpdate() {
5029
- setTimeout(() => this.updatePanelPlacement());
5585
+ });
5586
+ this.cdr.markForCheck();
5030
5587
  }
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') {
5588
+ closePanel() {
5589
+ if (!this.overlayRef)
5038
5590
  return;
5591
+ this._open = false;
5592
+ this.openChange.emit(false);
5593
+ this.cdr.markForCheck();
5594
+ this.destroyOverlay();
5595
+ }
5596
+ destroyOverlay() {
5597
+ if (this.outsideClickSub) {
5598
+ this.outsideClickSub.unsubscribe();
5599
+ this.outsideClickSub = null;
5039
5600
  }
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();
5601
+ if (this.overlayRef) {
5602
+ this.overlayRef.detach();
5603
+ this.overlayRef.dispose();
5604
+ this.overlayRef = null;
5050
5605
  }
5051
5606
  }
5607
+ getPositionConfigs() {
5608
+ return [
5609
+ // Bottom (default)
5610
+ {
5611
+ originX: "start",
5612
+ originY: "bottom",
5613
+ overlayX: "start",
5614
+ overlayY: "top",
5615
+ offsetY: 8,
5616
+ },
5617
+ // Top (fallback)
5618
+ {
5619
+ originX: "start",
5620
+ originY: "top",
5621
+ overlayX: "start",
5622
+ overlayY: "bottom",
5623
+ offsetY: -8,
5624
+ },
5625
+ // Right
5626
+ {
5627
+ originX: "end",
5628
+ originY: "bottom",
5629
+ overlayX: "start",
5630
+ overlayY: "top",
5631
+ offsetY: 8,
5632
+ },
5633
+ // Left
5634
+ {
5635
+ originX: "start",
5636
+ originY: "bottom",
5637
+ overlayX: "end",
5638
+ overlayY: "top",
5639
+ offsetY: 8,
5640
+ },
5641
+ ];
5642
+ }
5052
5643
  }
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 });
5644
+ 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 });
5645
+ 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
5646
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmPopoverComponent, decorators: [{
5056
5647
  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: [{
5648
+ 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"] }]
5649
+ }], ctorParameters: function () { return [{ type: i1$1.Overlay }, { type: i0.ViewContainerRef }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { triggerText: [{
5059
5650
  type: Input
5060
5651
  }], className: [{
5061
5652
  type: Input
@@ -5065,26 +5656,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
5065
5656
  type: Input
5066
5657
  }], openChange: [{
5067
5658
  type: Output
5068
- }], anchorRef: [{
5069
- type: ViewChild,
5070
- args: ['anchorEl']
5071
5659
  }], triggerRef: [{
5072
5660
  type: ViewChild,
5073
- args: ['triggerEl']
5074
- }], panelRef: [{
5661
+ args: ["triggerEl"]
5662
+ }], panelTemplateRef: [{
5075
5663
  type: ViewChild,
5076
- args: ['panelEl']
5664
+ args: ["panelTemplate"]
5077
5665
  }], open: [{
5078
5666
  type: Input
5079
5667
  }], onEsc: [{
5080
5668
  type: HostListener,
5081
- args: ['document:keydown.escape']
5082
- }], onViewportChange: [{
5083
- type: HostListener,
5084
- args: ['window:resize']
5085
- }, {
5086
- type: HostListener,
5087
- args: ['window:scroll']
5669
+ args: ["document:keydown.escape"]
5088
5670
  }] } });
5089
5671
 
5090
5672
  class PdmProgressComponent {
@@ -5536,8 +6118,8 @@ class PdmTabsComponent {
5536
6118
  constructor(cdr) {
5537
6119
  this.cdr = cdr;
5538
6120
  this.items = [];
5539
- this.value = '';
5540
- this.className = '';
6121
+ this.value = "";
6122
+ this.className = "";
5541
6123
  this.valueChange = new EventEmitter();
5542
6124
  }
5543
6125
  select(item) {
@@ -5549,10 +6131,10 @@ class PdmTabsComponent {
5549
6131
  }
5550
6132
  }
5551
6133
  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 });
6134
+ 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
6135
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTabsComponent, decorators: [{
5554
6136
  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" }]
6137
+ 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
6138
  }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { items: [{
5557
6139
  type: Input
5558
6140
  }], value: [{
@@ -5660,8 +6242,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
5660
6242
  class PdmToggleGroupComponent {
5661
6243
  constructor() {
5662
6244
  this.items = [];
5663
- this.value = '';
5664
- this.className = '';
6245
+ this.value = "";
6246
+ this.className = "";
5665
6247
  this.valueChange = new EventEmitter();
5666
6248
  }
5667
6249
  onSelect(next, disabled) {
@@ -5671,10 +6253,10 @@ class PdmToggleGroupComponent {
5671
6253
  }
5672
6254
  }
5673
6255
  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 });
6256
+ 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
6257
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmToggleGroupComponent, decorators: [{
5676
6258
  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" }]
6259
+ 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
6260
  }], propDecorators: { items: [{
5679
6261
  type: Input
5680
6262
  }], value: [{
@@ -5686,33 +6268,173 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
5686
6268
  }] } });
5687
6269
 
5688
6270
  class PdmTooltipComponent {
5689
- constructor() {
5690
- this.text = '';
5691
- this.side = 'top';
5692
- this.className = '';
6271
+ constructor(overlay, viewContainerRef, elementRef, cdr) {
6272
+ this.overlay = overlay;
6273
+ this.viewContainerRef = viewContainerRef;
6274
+ this.elementRef = elementRef;
6275
+ this.cdr = cdr;
6276
+ this.text = "";
6277
+ this.side = "top";
6278
+ this.className = "";
5693
6279
  this.open = false;
6280
+ this.overlayRef = null;
6281
+ }
6282
+ ngOnDestroy() {
6283
+ this.destroyOverlay();
6284
+ }
6285
+ onMouseEnter() {
6286
+ this.show();
6287
+ }
6288
+ onMouseLeave() {
6289
+ this.hide();
5694
6290
  }
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';
6291
+ onFocusIn() {
6292
+ this.show();
6293
+ }
6294
+ onFocusOut() {
6295
+ this.hide();
6296
+ }
6297
+ show() {
6298
+ if (this.open || !this.text)
6299
+ return;
6300
+ this.open = true;
6301
+ this.cdr.markForCheck();
6302
+ this.createOverlay();
6303
+ }
6304
+ hide() {
6305
+ if (!this.open)
6306
+ return;
6307
+ this.open = false;
6308
+ this.cdr.markForCheck();
6309
+ this.destroyOverlay();
6310
+ }
6311
+ createOverlay() {
6312
+ if (this.overlayRef)
6313
+ return;
6314
+ const triggerEl = this.elementRef.nativeElement.querySelector(":scope > *") ||
6315
+ this.elementRef.nativeElement;
6316
+ const positionStrategy = this.overlay
6317
+ .position()
6318
+ .flexibleConnectedTo(triggerEl)
6319
+ .withPositions(this.getPositionConfigs())
6320
+ .withFlexibleDimensions(false)
6321
+ .withPush(true);
6322
+ const panelClass = mergeOverlayPanelClass(OVERLAY_BASE_Z_INDEX);
6323
+ this.overlayRef = this.overlay.create({
6324
+ positionStrategy,
6325
+ panelClass,
6326
+ });
6327
+ const portal = new TemplatePortal(this.tooltipTemplate, this.viewContainerRef);
6328
+ this.overlayRef.attach(portal);
6329
+ }
6330
+ destroyOverlay() {
6331
+ if (this.overlayRef) {
6332
+ this.overlayRef.detach();
6333
+ this.overlayRef.dispose();
6334
+ this.overlayRef = null;
6335
+ }
6336
+ }
6337
+ getPositionConfigs() {
6338
+ const offset = 4;
6339
+ switch (this.side) {
6340
+ case "bottom":
6341
+ return [
6342
+ {
6343
+ originX: "center",
6344
+ originY: "bottom",
6345
+ overlayX: "center",
6346
+ overlayY: "top",
6347
+ offsetY: offset,
6348
+ },
6349
+ {
6350
+ originX: "center",
6351
+ originY: "top",
6352
+ overlayX: "center",
6353
+ overlayY: "bottom",
6354
+ offsetY: -offset,
6355
+ },
6356
+ ];
6357
+ case "left":
6358
+ return [
6359
+ {
6360
+ originX: "start",
6361
+ originY: "center",
6362
+ overlayX: "end",
6363
+ overlayY: "center",
6364
+ offsetX: -offset,
6365
+ },
6366
+ {
6367
+ originX: "end",
6368
+ originY: "center",
6369
+ overlayX: "start",
6370
+ overlayY: "center",
6371
+ offsetX: offset,
6372
+ },
6373
+ ];
6374
+ case "right":
6375
+ return [
6376
+ {
6377
+ originX: "end",
6378
+ originY: "center",
6379
+ overlayX: "start",
6380
+ overlayY: "center",
6381
+ offsetX: offset,
6382
+ },
6383
+ {
6384
+ originX: "start",
6385
+ originY: "center",
6386
+ overlayX: "end",
6387
+ overlayY: "center",
6388
+ offsetX: -offset,
6389
+ },
6390
+ ];
6391
+ case "top":
6392
+ default:
6393
+ return [
6394
+ {
6395
+ originX: "center",
6396
+ originY: "top",
6397
+ overlayX: "center",
6398
+ overlayY: "bottom",
6399
+ offsetY: -offset,
6400
+ },
6401
+ {
6402
+ originX: "center",
6403
+ originY: "bottom",
6404
+ overlayX: "center",
6405
+ overlayY: "top",
6406
+ offsetY: offset,
6407
+ },
6408
+ ];
6409
+ }
5703
6410
  }
5704
6411
  }
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 });
6412
+ 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 });
6413
+ 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
6414
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTooltipComponent, decorators: [{
5708
6415
  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: [{
6416
+ 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"] }]
6417
+ }], ctorParameters: function () { return [{ type: i1$1.Overlay }, { type: i0.ViewContainerRef }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { text: [{
5711
6418
  type: Input
5712
6419
  }], side: [{
5713
6420
  type: Input
5714
6421
  }], className: [{
5715
6422
  type: Input
6423
+ }], tooltipTemplate: [{
6424
+ type: ViewChild,
6425
+ args: ["tooltipTemplate"]
6426
+ }], onMouseEnter: [{
6427
+ type: HostListener,
6428
+ args: ["mouseenter"]
6429
+ }], onMouseLeave: [{
6430
+ type: HostListener,
6431
+ args: ["mouseleave"]
6432
+ }], onFocusIn: [{
6433
+ type: HostListener,
6434
+ args: ["focusin"]
6435
+ }], onFocusOut: [{
6436
+ type: HostListener,
6437
+ args: ["focusout"]
5716
6438
  }] } });
5717
6439
 
5718
6440
  const COMPONENTS = [
@@ -5913,5 +6635,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
5913
6635
  * Generated bundle index. Do not edit.
5914
6636
  */
5915
6637
 
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 };
6638
+ 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
6639
  //# sourceMappingURL=pdm-ui-kit.mjs.map