ps-helix 4.0.0 → 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, output, computed, ChangeDetectionStrategy, Component, model, inject, ElementRef, signal, PLATFORM_ID, ViewEncapsulation, InjectionToken, viewChild, effect, ChangeDetectorRef, DestroyRef, forwardRef, Injectable, Renderer2, contentChild, EventEmitter, Output, Input, contentChildren, afterNextRender } from '@angular/core';
2
+ import { input, output, computed, ChangeDetectionStrategy, Component, model, inject, ElementRef, signal, PLATFORM_ID, ViewEncapsulation, InjectionToken, viewChild, effect, ChangeDetectorRef, DestroyRef, Injectable, Renderer2, contentChild, EventEmitter, Output, Input, contentChildren, afterNextRender } from '@angular/core';
3
3
  import * as i1 from '@angular/common';
4
4
  import { CommonModule, isPlatformBrowser, NgTemplateOutlet } from '@angular/common';
5
5
  import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
@@ -341,6 +341,8 @@ class PshCardComponent {
341
341
  this.showActionsDivider = input(true, ...(ngDevMode ? [{ debugName: "showActionsDivider" }] : []));
342
342
  /** Alignement des actions dans la zone card-actions */
343
343
  this.actionsAlignment = input('right', ...(ngDevMode ? [{ debugName: "actionsAlignment" }] : []));
344
+ /** Activer/désactiver le padding du body */
345
+ this.bodyPadding = input(true, ...(ngDevMode ? [{ debugName: "bodyPadding" }] : []));
344
346
  /** Classes CSS additionnelles */
345
347
  this.cssClass = input('', ...(ngDevMode ? [{ debugName: "cssClass" }] : []));
346
348
  /** Styles inline personnalisés */
@@ -433,12 +435,14 @@ class PshCardComponent {
433
435
  }
434
436
  }
435
437
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: PshCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
436
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: PshCardComponent, isStandalone: true, selector: "psh-card", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, hoverable: { classPropertyName: "hoverable", publicName: "hoverable", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, colorVariant: { classPropertyName: "colorVariant", publicName: "colorVariant", isSignal: true, isRequired: false, transformFunction: null }, density: { classPropertyName: "density", publicName: "density", isSignal: true, isRequired: false, transformFunction: null }, showHeaderDivider: { classPropertyName: "showHeaderDivider", publicName: "showHeaderDivider", isSignal: true, isRequired: false, transformFunction: null }, showFooterDivider: { classPropertyName: "showFooterDivider", publicName: "showFooterDivider", isSignal: true, isRequired: false, transformFunction: null }, showActionsDivider: { classPropertyName: "showActionsDivider", publicName: "showActionsDivider", isSignal: true, isRequired: false, transformFunction: null }, actionsAlignment: { classPropertyName: "actionsAlignment", publicName: "actionsAlignment", isSignal: true, isRequired: false, transformFunction: null }, cssClass: { classPropertyName: "cssClass", publicName: "cssClass", isSignal: true, isRequired: false, transformFunction: null }, customStyle: { classPropertyName: "customStyle", publicName: "customStyle", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { variant: "variantChange", hoverable: "hoverableChange", interactive: "interactiveChange", clicked: "clicked" }, ngImport: i0, template: "<div\n [class]=\"computedClasses()\"\n [style]=\"computedStyles()\"\n (click)=\"handleClick($event)\"\n (keydown)=\"handleKeydown($event)\"\n role=\"article\"\n [attr.tabindex]=\"interactive() && !disabled() ? 0 : null\"\n [attr.aria-disabled]=\"disabled() ? 'true' : null\"\n [attr.aria-busy]=\"loading() ? 'true' : null\"\n>\n <!-- Header avec titre et description int\u00E9gr\u00E9s -->\n @if (hasHeader()) {\n <div class=\"card-header\" [class.has-divider]=\"showHeaderDivider()\">\n <!-- Slot pour ic\u00F4ne/avatar avant le titre -->\n <ng-content select=\"[card-header-icon]\"></ng-content>\n\n <!-- Zone de titre et description -->\n @if (title() || description()) {\n <div class=\"card-header-content\">\n @if (title()) {\n <h3 class=\"card-title\">{{ title() }}</h3>\n }\n @if (description()) {\n <p class=\"card-description\">{{ description() }}</p>\n }\n </div>\n }\n\n <!-- Slot pour contenu personnalis\u00E9 du header -->\n <ng-content select=\"[card-header-content]\"></ng-content>\n\n <!-- Slot pour badge/tag ou actions secondaires -->\n <ng-content select=\"[card-header-extra]\"></ng-content>\n </div>\n }\n\n <!-- Body avec contenu principal -->\n <div class=\"card-body\">\n <!-- \u00C9tat de chargement -->\n @if (loading()) {\n <div class=\"card-loading\">\n <div class=\"skeleton-line\"></div>\n <div class=\"skeleton-line\"></div>\n <div class=\"skeleton-line short\"></div>\n </div>\n } @else {\n <!-- Contenu principal (slot par d\u00E9faut) -->\n <ng-content></ng-content>\n }\n </div>\n\n <!-- Footer optionnel pour m\u00E9tadonn\u00E9es -->\n <div class=\"card-footer\" [class.has-divider]=\"showFooterDivider()\">\n <ng-content select=\"[card-footer]\"></ng-content>\n </div>\n\n <!-- Actions -->\n <div class=\"card-actions\" [class]=\"actionsClasses()\" [class.has-divider]=\"showActionsDivider()\">\n <ng-content select=\"[card-actions]\"></ng-content>\n </div>\n</div>\n", styles: [".card{background:var(--surface-card);border-radius:var(--border-radius-lg, .75rem);overflow:hidden;transition:all .2s ease;width:100%;display:flex;flex-direction:column;position:relative}.card.variant-elevated{box-shadow:0 1px 3px #0000001a,0 1px 2px #0000000f}.card.variant-elevated.hoverable:hover{box-shadow:0 4px 6px #0000001a,0 2px 4px #0000000f}.card.variant-outlined{border:1px solid var(--surface-border)}.card.variant-default{background:var(--surface-section)}.card.color-info{border-left:4px solid var(--blue-500)}.card.color-info .card-header{background:rgba(var(--blue-500-rgb, 59, 130, 246),.05)}.card.color-success{border-left:4px solid var(--green-500)}.card.color-success .card-header{background:rgba(var(--green-500-rgb, 34, 197, 94),.05)}.card.color-warning{border-left:4px solid var(--orange-500)}.card.color-warning .card-header{background:rgba(var(--orange-500-rgb, 249, 115, 22),.05)}.card.color-danger{border-left:4px solid var(--red-500)}.card.color-danger .card-header{background:rgba(var(--red-500-rgb, 239, 68, 68),.05)}.card.density-compact{--card-header-padding: var(--size-3) var(--size-4);--card-body-padding: var(--size-4);--card-footer-padding: var(--size-3) var(--size-4);--card-actions-padding: var(--size-3) var(--size-4);--card-header-gap: var(--spacing-sm);--card-body-gap: var(--size-3)}.card.density-normal{--card-header-padding: var(--size-4) var(--size-5);--card-body-padding: var(--size-6);--card-footer-padding: var(--size-4) var(--size-5);--card-actions-padding: var(--size-4) var(--size-5);--card-header-gap: var(--size-3);--card-body-gap: var(--size-4)}.card.density-spacious{--card-header-padding: var(--size-6) var(--size-7);--card-body-padding: var(--size-8);--card-footer-padding: var(--size-5) var(--size-7);--card-actions-padding: var(--size-5) var(--size-7);--card-header-gap: var(--size-4);--card-body-gap: var(--size-5)}.card-header{padding:var(--card-header-padding);display:flex;align-items:flex-start;gap:var(--card-header-gap);background:var(--surface-ground);position:relative}.card-header.has-divider{border-bottom:1px solid var(--surface-border)}.card-header-content{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--spacing-xs)}.card-title{font-size:var(--font-size-lg, 1.125rem);font-weight:600;line-height:1.4;color:var(--text-color);margin:0;overflow:hidden;text-overflow:ellipsis}.card-description{font-size:var(--font-size-sm, .875rem);line-height:1.5;color:var(--text-color-secondary);margin:0}[card-header-icon]{flex-shrink:0;display:flex;align-items:center;justify-content:center}[card-header-content]{flex:1;min-width:0}[card-header-extra]{flex-shrink:0;display:flex;align-items:center;gap:var(--spacing-sm)}.card-body{padding:var(--card-body-padding);flex:1;display:flex;flex-direction:column;gap:var(--card-body-gap);color:var(--text-color);line-height:1.6;overflow:hidden}.card-body>*{margin:0}.card-body img{max-width:100%;height:auto;border-radius:var(--border-radius)}.card-body table{width:100%;max-width:100%;overflow-x:auto;display:block}.card-body pre{max-width:100%;overflow-x:auto;padding:var(--spacing-sm);background:var(--surface-ground);border-radius:var(--border-radius);font-size:var(--font-size-sm)}.card-body video,.card-body iframe{max-width:100%;height:auto}.card-footer{padding:var(--card-footer-padding);background:var(--surface-ground);display:flex;align-items:center;gap:var(--size-4);flex-wrap:wrap;font-size:var(--font-size-sm, .875rem);color:var(--text-color-secondary)}.card-footer:empty{display:none}.card-footer.has-divider{border-top:1px solid var(--surface-border)}.card-actions{padding:var(--card-actions-padding);background:var(--surface-ground);display:flex;align-items:center;gap:var(--spacing-md);justify-content:flex-end}.card-actions>*{flex-shrink:0;display:flex;gap:var(--spacing-sm)}.card-actions:empty{display:none}.card-actions.has-divider{border-top:1px solid var(--surface-border)}.card-actions.actions-align-left{justify-content:flex-start}.card-actions.actions-align-center{justify-content:center}.card-actions.actions-align-right{justify-content:flex-end}.card-actions.actions-align-space-between{justify-content:space-between}.card-actions.mobile-full-width-buttons{flex-direction:column;gap:var(--spacing-sm)}.card-actions.mobile-full-width-buttons>*{display:flex;flex-direction:column;width:100%;gap:var(--spacing-sm)}.card.hoverable:hover{transform:translateY(-2px)}.card.interactive{cursor:pointer;-webkit-user-select:none;user-select:none}.card.interactive:focus{outline:none;box-shadow:0 0 0 3px rgba(var(--primary-500-rgb, 59, 130, 246),.2)}.card.interactive:focus:not(:focus-visible){box-shadow:none}.card.interactive:active{transform:translateY(0)}.card.disabled{opacity:.6;pointer-events:none;cursor:not-allowed}.card.loading{pointer-events:none}.card-loading{display:flex;flex-direction:column;gap:var(--size-3);animation:pulse 1.5s ease-in-out infinite}.skeleton-line{height:var(--size-4);background:linear-gradient(90deg,var(--surface-border) 25%,var(--surface-hover) 50%,var(--surface-border) 75%);background-size:200% 100%;animation:shimmer 1.5s ease-in-out infinite;border-radius:var(--spacing-xs)}.skeleton-line.short{width:60%}@keyframes shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}@keyframes pulse{0%,to{opacity:1}50%{opacity:.7}}@media(max-width:1024px){.card.density-spacious{--card-header-padding: var(--size-5) var(--size-6);--card-body-padding: var(--size-7);--card-footer-padding: var(--size-4-5) var(--size-6);--card-actions-padding: var(--size-4-5) var(--size-6)}}@media(max-width:768px){.card.density-compact{--card-header-padding: var(--size-2-5) var(--size-3);--card-body-padding: var(--size-3);--card-footer-padding: var(--size-2-5) var(--size-3);--card-actions-padding: var(--size-2-5) var(--size-3)}.card.density-normal{--card-header-padding: var(--size-3) var(--size-4);--card-body-padding: var(--size-4);--card-footer-padding: var(--size-3) var(--size-4);--card-actions-padding: var(--size-3) var(--size-4)}.card.density-spacious{--card-header-padding: var(--size-4) var(--size-5);--card-body-padding: var(--size-5);--card-footer-padding: var(--size-4) var(--size-5);--card-actions-padding: var(--size-4) var(--size-5)}.card-title{font-size:clamp(.9375rem,2vw,1rem)}.card-description{font-size:var(--font-size-xs)}.card-footer{font-size:var(--font-size-xs);gap:var(--size-3)}}@media(max-width:640px){.card-actions{flex-direction:column;gap:var(--spacing-md)}.card-actions>*{flex-direction:column;width:100%}}@media(max-width:480px){.card.density-compact{--card-header-padding: var(--spacing-sm) var(--size-3);--card-body-padding: var(--size-3);--card-footer-padding: var(--spacing-sm) var(--size-3);--card-actions-padding: var(--spacing-sm) var(--size-3)}.card.density-normal{--card-header-padding: var(--size-2-5) var(--size-3);--card-body-padding: var(--size-3);--card-footer-padding: var(--size-2-5) var(--size-3);--card-actions-padding: var(--size-2-5) var(--size-3)}.card.density-spacious{--card-header-padding: var(--size-3) var(--size-4);--card-body-padding: var(--size-4);--card-footer-padding: var(--size-3) var(--size-4);--card-actions-padding: var(--size-3) var(--size-4)}.card-header{flex-wrap:wrap;gap:var(--spacing-xs)}.card-title{font-size:clamp(.875rem,3vw,.9375rem);line-height:1.3}.card-description{font-size:var(--font-size-xs);line-height:1.4}[card-header-icon],[card-header-extra]{width:100%;justify-content:flex-start}.card-footer{flex-direction:column;align-items:flex-start;gap:var(--spacing-sm)}.card-actions{flex-direction:column;gap:var(--spacing-sm)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
438
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: PshCardComponent, isStandalone: true, selector: "psh-card", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, hoverable: { classPropertyName: "hoverable", publicName: "hoverable", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, colorVariant: { classPropertyName: "colorVariant", publicName: "colorVariant", isSignal: true, isRequired: false, transformFunction: null }, density: { classPropertyName: "density", publicName: "density", isSignal: true, isRequired: false, transformFunction: null }, showHeaderDivider: { classPropertyName: "showHeaderDivider", publicName: "showHeaderDivider", isSignal: true, isRequired: false, transformFunction: null }, showFooterDivider: { classPropertyName: "showFooterDivider", publicName: "showFooterDivider", isSignal: true, isRequired: false, transformFunction: null }, showActionsDivider: { classPropertyName: "showActionsDivider", publicName: "showActionsDivider", isSignal: true, isRequired: false, transformFunction: null }, actionsAlignment: { classPropertyName: "actionsAlignment", publicName: "actionsAlignment", isSignal: true, isRequired: false, transformFunction: null }, bodyPadding: { classPropertyName: "bodyPadding", publicName: "bodyPadding", isSignal: true, isRequired: false, transformFunction: null }, cssClass: { classPropertyName: "cssClass", publicName: "cssClass", isSignal: true, isRequired: false, transformFunction: null }, customStyle: { classPropertyName: "customStyle", publicName: "customStyle", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { variant: "variantChange", hoverable: "hoverableChange", interactive: "interactiveChange", clicked: "clicked" }, host: { styleAttribute: "display: block;" }, ngImport: i0, template: "<div\n [class]=\"computedClasses()\"\n [style]=\"computedStyles()\"\n (click)=\"handleClick($event)\"\n (keydown)=\"handleKeydown($event)\"\n role=\"article\"\n [attr.tabindex]=\"interactive() && !disabled() ? 0 : null\"\n [attr.aria-disabled]=\"disabled() ? 'true' : null\"\n [attr.aria-busy]=\"loading() ? 'true' : null\"\n>\n <!-- Header avec titre et description int\u00E9gr\u00E9s -->\n @if (hasHeader()) {\n <div class=\"card-header\" [class.has-divider]=\"showHeaderDivider()\">\n <!-- Slot pour ic\u00F4ne/avatar avant le titre -->\n <ng-content select=\"[card-header-icon]\"></ng-content>\n\n <!-- Zone de titre et description -->\n @if (title() || description()) {\n <div class=\"card-header-content\">\n @if (title()) {\n <h3 class=\"card-title\">{{ title() }}</h3>\n }\n @if (description()) {\n <p class=\"card-description\">{{ description() }}</p>\n }\n </div>\n }\n\n <!-- Slot pour contenu personnalis\u00E9 du header -->\n <ng-content select=\"[card-header-content]\"></ng-content>\n\n <!-- Slot pour badge/tag ou actions secondaires -->\n <ng-content select=\"[card-header-extra]\"></ng-content>\n </div>\n }\n\n <!-- Body avec contenu principal -->\n <div class=\"card-body\" [class.no-padding]=\"!bodyPadding()\">\n <!-- \u00C9tat de chargement -->\n @if (loading()) {\n <div class=\"card-loading\">\n <div class=\"skeleton-line\"></div>\n <div class=\"skeleton-line\"></div>\n <div class=\"skeleton-line short\"></div>\n </div>\n } @else {\n <!-- Contenu principal (slot par d\u00E9faut) -->\n <ng-content></ng-content>\n }\n </div>\n\n <!-- Footer optionnel pour m\u00E9tadonn\u00E9es -->\n <div class=\"card-footer\" [class.has-divider]=\"showFooterDivider()\">\n <ng-content select=\"[card-footer]\"></ng-content>\n </div>\n\n <!-- Actions -->\n <div class=\"card-actions\" [class]=\"actionsClasses()\" [class.has-divider]=\"showActionsDivider()\">\n <ng-content select=\"[card-actions]\"></ng-content>\n </div>\n</div>\n", styles: [".card{background:var(--surface-card);border-radius:var(--border-radius-lg, .75rem);overflow:hidden;transition:all .2s ease;width:100%;display:flex;flex-direction:column;position:relative}.card.variant-elevated{box-shadow:0 1px 3px #0000001a,0 1px 2px #0000000f}.card.variant-elevated.hoverable:hover{box-shadow:0 4px 6px #0000001a,0 2px 4px #0000000f}.card.variant-outlined{border:1px solid var(--surface-border)}.card.variant-default{background:var(--surface-section)}.card.color-info{border-left:4px solid var(--blue-500)}.card.color-info .card-header{background:rgba(var(--blue-500-rgb, 59, 130, 246),.05)}.card.color-success{border-left:4px solid var(--green-500)}.card.color-success .card-header{background:rgba(var(--green-500-rgb, 34, 197, 94),.05)}.card.color-warning{border-left:4px solid var(--orange-500)}.card.color-warning .card-header{background:rgba(var(--orange-500-rgb, 249, 115, 22),.05)}.card.color-danger{border-left:4px solid var(--red-500)}.card.color-danger .card-header{background:rgba(var(--red-500-rgb, 239, 68, 68),.05)}.card.density-compact{--card-header-padding: var(--size-3) var(--size-4);--card-body-padding: var(--size-4);--card-footer-padding: var(--size-3) var(--size-4);--card-actions-padding: var(--size-3) var(--size-4);--card-header-gap: var(--spacing-sm);--card-body-gap: var(--size-3)}.card.density-normal{--card-header-padding: var(--size-4) var(--size-5);--card-body-padding: var(--size-6);--card-footer-padding: var(--size-4) var(--size-5);--card-actions-padding: var(--size-4) var(--size-5);--card-header-gap: var(--size-3);--card-body-gap: var(--size-4)}.card.density-spacious{--card-header-padding: var(--size-6) var(--size-7);--card-body-padding: var(--size-8);--card-footer-padding: var(--size-5) var(--size-7);--card-actions-padding: var(--size-5) var(--size-7);--card-header-gap: var(--size-4);--card-body-gap: var(--size-5)}.card-header{padding:var(--card-header-padding);display:flex;align-items:flex-start;gap:var(--card-header-gap);background:var(--surface-ground);position:relative}.card-header.has-divider{border-bottom:1px solid var(--surface-border)}.card-header-content{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--spacing-xs)}.card-title{font-size:var(--font-size-lg, 1.125rem);font-weight:600;line-height:1.4;color:var(--text-color);margin:0;overflow:hidden;text-overflow:ellipsis}.card-description{font-size:var(--font-size-sm, .875rem);line-height:1.5;color:var(--text-color-secondary);margin:0}[card-header-icon]{flex-shrink:0;display:flex;align-items:center;justify-content:center}[card-header-content]{flex:1;min-width:0}[card-header-extra]{flex-shrink:0;display:flex;align-items:center;gap:var(--spacing-sm)}.card-body{padding:var(--card-body-padding);flex:1;display:flex;flex-direction:column;gap:var(--card-body-gap);color:var(--text-color);line-height:1.6;overflow:hidden}.card-body.no-padding{padding:0}.card-body>*{margin:0}.card-body img{max-width:100%;height:auto;border-radius:var(--border-radius)}.card-body table{width:100%;max-width:100%;overflow-x:auto;display:block}.card-body pre{max-width:100%;overflow-x:auto;padding:var(--spacing-sm);background:var(--surface-ground);border-radius:var(--border-radius);font-size:var(--font-size-sm)}.card-body video,.card-body iframe{max-width:100%;height:auto}.card-footer{padding:var(--card-footer-padding);background:var(--surface-ground);display:flex;align-items:center;gap:var(--size-4);flex-wrap:wrap;font-size:var(--font-size-sm, .875rem);color:var(--text-color-secondary)}.card-footer:empty{display:none}.card-footer.has-divider{border-top:1px solid var(--surface-border)}.card-actions{padding:var(--card-actions-padding);background:var(--surface-ground);display:flex;align-items:center;gap:var(--spacing-md);justify-content:flex-end}.card-actions>*{flex-shrink:0;display:flex;gap:var(--spacing-sm)}.card-actions:empty{display:none}.card-actions.has-divider{border-top:1px solid var(--surface-border)}.card-actions.actions-align-left{justify-content:flex-start}.card-actions.actions-align-center{justify-content:center}.card-actions.actions-align-right{justify-content:flex-end}.card-actions.actions-align-space-between{justify-content:space-between}.card-actions.mobile-full-width-buttons{flex-direction:column;gap:var(--spacing-sm)}.card-actions.mobile-full-width-buttons>*{display:flex;flex-direction:column;width:100%;gap:var(--spacing-sm)}.card.hoverable:hover{transform:translateY(-2px)}.card.interactive{cursor:pointer;-webkit-user-select:none;user-select:none}.card.interactive:focus{outline:none;box-shadow:0 0 0 3px rgba(var(--primary-500-rgb, 59, 130, 246),.2)}.card.interactive:focus:not(:focus-visible){box-shadow:none}.card.interactive:active{transform:translateY(0)}.card.disabled{opacity:.6;pointer-events:none;cursor:not-allowed}.card.loading{pointer-events:none}.card-loading{display:flex;flex-direction:column;gap:var(--size-3);animation:pulse 1.5s ease-in-out infinite}.skeleton-line{height:var(--size-4);background:linear-gradient(90deg,var(--surface-border) 25%,var(--surface-hover) 50%,var(--surface-border) 75%);background-size:200% 100%;animation:shimmer 1.5s ease-in-out infinite;border-radius:var(--spacing-xs)}.skeleton-line.short{width:60%}@keyframes shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}@keyframes pulse{0%,to{opacity:1}50%{opacity:.7}}@media(max-width:1024px){.card.density-spacious{--card-header-padding: var(--size-5) var(--size-6);--card-body-padding: var(--size-7);--card-footer-padding: var(--size-4-5) var(--size-6);--card-actions-padding: var(--size-4-5) var(--size-6)}}@media(max-width:768px){.card.density-compact{--card-header-padding: var(--size-2-5) var(--size-3);--card-body-padding: var(--size-3);--card-footer-padding: var(--size-2-5) var(--size-3);--card-actions-padding: var(--size-2-5) var(--size-3)}.card.density-normal{--card-header-padding: var(--size-3) var(--size-4);--card-body-padding: var(--size-4);--card-footer-padding: var(--size-3) var(--size-4);--card-actions-padding: var(--size-3) var(--size-4)}.card.density-spacious{--card-header-padding: var(--size-4) var(--size-5);--card-body-padding: var(--size-5);--card-footer-padding: var(--size-4) var(--size-5);--card-actions-padding: var(--size-4) var(--size-5)}.card-title{font-size:clamp(.9375rem,2vw,1rem)}.card-description{font-size:var(--font-size-xs)}.card-footer{font-size:var(--font-size-xs);gap:var(--size-3)}}@media(max-width:640px){.card-actions{flex-direction:column;gap:var(--spacing-md)}.card-actions>*{flex-direction:column;width:100%}}@media(max-width:480px){.card.density-compact{--card-header-padding: var(--spacing-sm) var(--size-3);--card-body-padding: var(--size-3);--card-footer-padding: var(--spacing-sm) var(--size-3);--card-actions-padding: var(--spacing-sm) var(--size-3)}.card.density-normal{--card-header-padding: var(--size-2-5) var(--size-3);--card-body-padding: var(--size-3);--card-footer-padding: var(--size-2-5) var(--size-3);--card-actions-padding: var(--size-2-5) var(--size-3)}.card.density-spacious{--card-header-padding: var(--size-3) var(--size-4);--card-body-padding: var(--size-4);--card-footer-padding: var(--size-3) var(--size-4);--card-actions-padding: var(--size-3) var(--size-4)}.card-header{flex-wrap:wrap;gap:var(--spacing-xs)}.card-title{font-size:clamp(.875rem,3vw,.9375rem);line-height:1.3}.card-description{font-size:var(--font-size-xs);line-height:1.4}[card-header-icon],[card-header-extra]{width:100%;justify-content:flex-start}.card-footer{flex-direction:column;align-items:flex-start;gap:var(--spacing-sm)}.card-actions{flex-direction:column;gap:var(--spacing-sm)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
437
439
  }
438
440
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: PshCardComponent, decorators: [{
439
441
  type: Component,
440
- args: [{ selector: 'psh-card', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div\n [class]=\"computedClasses()\"\n [style]=\"computedStyles()\"\n (click)=\"handleClick($event)\"\n (keydown)=\"handleKeydown($event)\"\n role=\"article\"\n [attr.tabindex]=\"interactive() && !disabled() ? 0 : null\"\n [attr.aria-disabled]=\"disabled() ? 'true' : null\"\n [attr.aria-busy]=\"loading() ? 'true' : null\"\n>\n <!-- Header avec titre et description int\u00E9gr\u00E9s -->\n @if (hasHeader()) {\n <div class=\"card-header\" [class.has-divider]=\"showHeaderDivider()\">\n <!-- Slot pour ic\u00F4ne/avatar avant le titre -->\n <ng-content select=\"[card-header-icon]\"></ng-content>\n\n <!-- Zone de titre et description -->\n @if (title() || description()) {\n <div class=\"card-header-content\">\n @if (title()) {\n <h3 class=\"card-title\">{{ title() }}</h3>\n }\n @if (description()) {\n <p class=\"card-description\">{{ description() }}</p>\n }\n </div>\n }\n\n <!-- Slot pour contenu personnalis\u00E9 du header -->\n <ng-content select=\"[card-header-content]\"></ng-content>\n\n <!-- Slot pour badge/tag ou actions secondaires -->\n <ng-content select=\"[card-header-extra]\"></ng-content>\n </div>\n }\n\n <!-- Body avec contenu principal -->\n <div class=\"card-body\">\n <!-- \u00C9tat de chargement -->\n @if (loading()) {\n <div class=\"card-loading\">\n <div class=\"skeleton-line\"></div>\n <div class=\"skeleton-line\"></div>\n <div class=\"skeleton-line short\"></div>\n </div>\n } @else {\n <!-- Contenu principal (slot par d\u00E9faut) -->\n <ng-content></ng-content>\n }\n </div>\n\n <!-- Footer optionnel pour m\u00E9tadonn\u00E9es -->\n <div class=\"card-footer\" [class.has-divider]=\"showFooterDivider()\">\n <ng-content select=\"[card-footer]\"></ng-content>\n </div>\n\n <!-- Actions -->\n <div class=\"card-actions\" [class]=\"actionsClasses()\" [class.has-divider]=\"showActionsDivider()\">\n <ng-content select=\"[card-actions]\"></ng-content>\n </div>\n</div>\n", styles: [".card{background:var(--surface-card);border-radius:var(--border-radius-lg, .75rem);overflow:hidden;transition:all .2s ease;width:100%;display:flex;flex-direction:column;position:relative}.card.variant-elevated{box-shadow:0 1px 3px #0000001a,0 1px 2px #0000000f}.card.variant-elevated.hoverable:hover{box-shadow:0 4px 6px #0000001a,0 2px 4px #0000000f}.card.variant-outlined{border:1px solid var(--surface-border)}.card.variant-default{background:var(--surface-section)}.card.color-info{border-left:4px solid var(--blue-500)}.card.color-info .card-header{background:rgba(var(--blue-500-rgb, 59, 130, 246),.05)}.card.color-success{border-left:4px solid var(--green-500)}.card.color-success .card-header{background:rgba(var(--green-500-rgb, 34, 197, 94),.05)}.card.color-warning{border-left:4px solid var(--orange-500)}.card.color-warning .card-header{background:rgba(var(--orange-500-rgb, 249, 115, 22),.05)}.card.color-danger{border-left:4px solid var(--red-500)}.card.color-danger .card-header{background:rgba(var(--red-500-rgb, 239, 68, 68),.05)}.card.density-compact{--card-header-padding: var(--size-3) var(--size-4);--card-body-padding: var(--size-4);--card-footer-padding: var(--size-3) var(--size-4);--card-actions-padding: var(--size-3) var(--size-4);--card-header-gap: var(--spacing-sm);--card-body-gap: var(--size-3)}.card.density-normal{--card-header-padding: var(--size-4) var(--size-5);--card-body-padding: var(--size-6);--card-footer-padding: var(--size-4) var(--size-5);--card-actions-padding: var(--size-4) var(--size-5);--card-header-gap: var(--size-3);--card-body-gap: var(--size-4)}.card.density-spacious{--card-header-padding: var(--size-6) var(--size-7);--card-body-padding: var(--size-8);--card-footer-padding: var(--size-5) var(--size-7);--card-actions-padding: var(--size-5) var(--size-7);--card-header-gap: var(--size-4);--card-body-gap: var(--size-5)}.card-header{padding:var(--card-header-padding);display:flex;align-items:flex-start;gap:var(--card-header-gap);background:var(--surface-ground);position:relative}.card-header.has-divider{border-bottom:1px solid var(--surface-border)}.card-header-content{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--spacing-xs)}.card-title{font-size:var(--font-size-lg, 1.125rem);font-weight:600;line-height:1.4;color:var(--text-color);margin:0;overflow:hidden;text-overflow:ellipsis}.card-description{font-size:var(--font-size-sm, .875rem);line-height:1.5;color:var(--text-color-secondary);margin:0}[card-header-icon]{flex-shrink:0;display:flex;align-items:center;justify-content:center}[card-header-content]{flex:1;min-width:0}[card-header-extra]{flex-shrink:0;display:flex;align-items:center;gap:var(--spacing-sm)}.card-body{padding:var(--card-body-padding);flex:1;display:flex;flex-direction:column;gap:var(--card-body-gap);color:var(--text-color);line-height:1.6;overflow:hidden}.card-body>*{margin:0}.card-body img{max-width:100%;height:auto;border-radius:var(--border-radius)}.card-body table{width:100%;max-width:100%;overflow-x:auto;display:block}.card-body pre{max-width:100%;overflow-x:auto;padding:var(--spacing-sm);background:var(--surface-ground);border-radius:var(--border-radius);font-size:var(--font-size-sm)}.card-body video,.card-body iframe{max-width:100%;height:auto}.card-footer{padding:var(--card-footer-padding);background:var(--surface-ground);display:flex;align-items:center;gap:var(--size-4);flex-wrap:wrap;font-size:var(--font-size-sm, .875rem);color:var(--text-color-secondary)}.card-footer:empty{display:none}.card-footer.has-divider{border-top:1px solid var(--surface-border)}.card-actions{padding:var(--card-actions-padding);background:var(--surface-ground);display:flex;align-items:center;gap:var(--spacing-md);justify-content:flex-end}.card-actions>*{flex-shrink:0;display:flex;gap:var(--spacing-sm)}.card-actions:empty{display:none}.card-actions.has-divider{border-top:1px solid var(--surface-border)}.card-actions.actions-align-left{justify-content:flex-start}.card-actions.actions-align-center{justify-content:center}.card-actions.actions-align-right{justify-content:flex-end}.card-actions.actions-align-space-between{justify-content:space-between}.card-actions.mobile-full-width-buttons{flex-direction:column;gap:var(--spacing-sm)}.card-actions.mobile-full-width-buttons>*{display:flex;flex-direction:column;width:100%;gap:var(--spacing-sm)}.card.hoverable:hover{transform:translateY(-2px)}.card.interactive{cursor:pointer;-webkit-user-select:none;user-select:none}.card.interactive:focus{outline:none;box-shadow:0 0 0 3px rgba(var(--primary-500-rgb, 59, 130, 246),.2)}.card.interactive:focus:not(:focus-visible){box-shadow:none}.card.interactive:active{transform:translateY(0)}.card.disabled{opacity:.6;pointer-events:none;cursor:not-allowed}.card.loading{pointer-events:none}.card-loading{display:flex;flex-direction:column;gap:var(--size-3);animation:pulse 1.5s ease-in-out infinite}.skeleton-line{height:var(--size-4);background:linear-gradient(90deg,var(--surface-border) 25%,var(--surface-hover) 50%,var(--surface-border) 75%);background-size:200% 100%;animation:shimmer 1.5s ease-in-out infinite;border-radius:var(--spacing-xs)}.skeleton-line.short{width:60%}@keyframes shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}@keyframes pulse{0%,to{opacity:1}50%{opacity:.7}}@media(max-width:1024px){.card.density-spacious{--card-header-padding: var(--size-5) var(--size-6);--card-body-padding: var(--size-7);--card-footer-padding: var(--size-4-5) var(--size-6);--card-actions-padding: var(--size-4-5) var(--size-6)}}@media(max-width:768px){.card.density-compact{--card-header-padding: var(--size-2-5) var(--size-3);--card-body-padding: var(--size-3);--card-footer-padding: var(--size-2-5) var(--size-3);--card-actions-padding: var(--size-2-5) var(--size-3)}.card.density-normal{--card-header-padding: var(--size-3) var(--size-4);--card-body-padding: var(--size-4);--card-footer-padding: var(--size-3) var(--size-4);--card-actions-padding: var(--size-3) var(--size-4)}.card.density-spacious{--card-header-padding: var(--size-4) var(--size-5);--card-body-padding: var(--size-5);--card-footer-padding: var(--size-4) var(--size-5);--card-actions-padding: var(--size-4) var(--size-5)}.card-title{font-size:clamp(.9375rem,2vw,1rem)}.card-description{font-size:var(--font-size-xs)}.card-footer{font-size:var(--font-size-xs);gap:var(--size-3)}}@media(max-width:640px){.card-actions{flex-direction:column;gap:var(--spacing-md)}.card-actions>*{flex-direction:column;width:100%}}@media(max-width:480px){.card.density-compact{--card-header-padding: var(--spacing-sm) var(--size-3);--card-body-padding: var(--size-3);--card-footer-padding: var(--spacing-sm) var(--size-3);--card-actions-padding: var(--spacing-sm) var(--size-3)}.card.density-normal{--card-header-padding: var(--size-2-5) var(--size-3);--card-body-padding: var(--size-3);--card-footer-padding: var(--size-2-5) var(--size-3);--card-actions-padding: var(--size-2-5) var(--size-3)}.card.density-spacious{--card-header-padding: var(--size-3) var(--size-4);--card-body-padding: var(--size-4);--card-footer-padding: var(--size-3) var(--size-4);--card-actions-padding: var(--size-3) var(--size-4)}.card-header{flex-wrap:wrap;gap:var(--spacing-xs)}.card-title{font-size:clamp(.875rem,3vw,.9375rem);line-height:1.3}.card-description{font-size:var(--font-size-xs);line-height:1.4}[card-header-icon],[card-header-extra]{width:100%;justify-content:flex-start}.card-footer{flex-direction:column;align-items:flex-start;gap:var(--spacing-sm)}.card-actions{flex-direction:column;gap:var(--spacing-sm)}}\n"] }]
441
- }], ctorParameters: () => [], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }, { type: i0.Output, args: ["variantChange"] }], hoverable: [{ type: i0.Input, args: [{ isSignal: true, alias: "hoverable", required: false }] }, { type: i0.Output, args: ["hoverableChange"] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }, { type: i0.Output, args: ["interactiveChange"] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], colorVariant: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorVariant", required: false }] }], density: [{ type: i0.Input, args: [{ isSignal: true, alias: "density", required: false }] }], showHeaderDivider: [{ type: i0.Input, args: [{ isSignal: true, alias: "showHeaderDivider", required: false }] }], showFooterDivider: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFooterDivider", required: false }] }], showActionsDivider: [{ type: i0.Input, args: [{ isSignal: true, alias: "showActionsDivider", required: false }] }], actionsAlignment: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionsAlignment", required: false }] }], cssClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "cssClass", required: false }] }], customStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "customStyle", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], clicked: [{ type: i0.Output, args: ["clicked"] }] } });
442
+ args: [{ selector: 'psh-card', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
443
+ style: 'display: block;',
444
+ }, template: "<div\n [class]=\"computedClasses()\"\n [style]=\"computedStyles()\"\n (click)=\"handleClick($event)\"\n (keydown)=\"handleKeydown($event)\"\n role=\"article\"\n [attr.tabindex]=\"interactive() && !disabled() ? 0 : null\"\n [attr.aria-disabled]=\"disabled() ? 'true' : null\"\n [attr.aria-busy]=\"loading() ? 'true' : null\"\n>\n <!-- Header avec titre et description int\u00E9gr\u00E9s -->\n @if (hasHeader()) {\n <div class=\"card-header\" [class.has-divider]=\"showHeaderDivider()\">\n <!-- Slot pour ic\u00F4ne/avatar avant le titre -->\n <ng-content select=\"[card-header-icon]\"></ng-content>\n\n <!-- Zone de titre et description -->\n @if (title() || description()) {\n <div class=\"card-header-content\">\n @if (title()) {\n <h3 class=\"card-title\">{{ title() }}</h3>\n }\n @if (description()) {\n <p class=\"card-description\">{{ description() }}</p>\n }\n </div>\n }\n\n <!-- Slot pour contenu personnalis\u00E9 du header -->\n <ng-content select=\"[card-header-content]\"></ng-content>\n\n <!-- Slot pour badge/tag ou actions secondaires -->\n <ng-content select=\"[card-header-extra]\"></ng-content>\n </div>\n }\n\n <!-- Body avec contenu principal -->\n <div class=\"card-body\" [class.no-padding]=\"!bodyPadding()\">\n <!-- \u00C9tat de chargement -->\n @if (loading()) {\n <div class=\"card-loading\">\n <div class=\"skeleton-line\"></div>\n <div class=\"skeleton-line\"></div>\n <div class=\"skeleton-line short\"></div>\n </div>\n } @else {\n <!-- Contenu principal (slot par d\u00E9faut) -->\n <ng-content></ng-content>\n }\n </div>\n\n <!-- Footer optionnel pour m\u00E9tadonn\u00E9es -->\n <div class=\"card-footer\" [class.has-divider]=\"showFooterDivider()\">\n <ng-content select=\"[card-footer]\"></ng-content>\n </div>\n\n <!-- Actions -->\n <div class=\"card-actions\" [class]=\"actionsClasses()\" [class.has-divider]=\"showActionsDivider()\">\n <ng-content select=\"[card-actions]\"></ng-content>\n </div>\n</div>\n", styles: [".card{background:var(--surface-card);border-radius:var(--border-radius-lg, .75rem);overflow:hidden;transition:all .2s ease;width:100%;display:flex;flex-direction:column;position:relative}.card.variant-elevated{box-shadow:0 1px 3px #0000001a,0 1px 2px #0000000f}.card.variant-elevated.hoverable:hover{box-shadow:0 4px 6px #0000001a,0 2px 4px #0000000f}.card.variant-outlined{border:1px solid var(--surface-border)}.card.variant-default{background:var(--surface-section)}.card.color-info{border-left:4px solid var(--blue-500)}.card.color-info .card-header{background:rgba(var(--blue-500-rgb, 59, 130, 246),.05)}.card.color-success{border-left:4px solid var(--green-500)}.card.color-success .card-header{background:rgba(var(--green-500-rgb, 34, 197, 94),.05)}.card.color-warning{border-left:4px solid var(--orange-500)}.card.color-warning .card-header{background:rgba(var(--orange-500-rgb, 249, 115, 22),.05)}.card.color-danger{border-left:4px solid var(--red-500)}.card.color-danger .card-header{background:rgba(var(--red-500-rgb, 239, 68, 68),.05)}.card.density-compact{--card-header-padding: var(--size-3) var(--size-4);--card-body-padding: var(--size-4);--card-footer-padding: var(--size-3) var(--size-4);--card-actions-padding: var(--size-3) var(--size-4);--card-header-gap: var(--spacing-sm);--card-body-gap: var(--size-3)}.card.density-normal{--card-header-padding: var(--size-4) var(--size-5);--card-body-padding: var(--size-6);--card-footer-padding: var(--size-4) var(--size-5);--card-actions-padding: var(--size-4) var(--size-5);--card-header-gap: var(--size-3);--card-body-gap: var(--size-4)}.card.density-spacious{--card-header-padding: var(--size-6) var(--size-7);--card-body-padding: var(--size-8);--card-footer-padding: var(--size-5) var(--size-7);--card-actions-padding: var(--size-5) var(--size-7);--card-header-gap: var(--size-4);--card-body-gap: var(--size-5)}.card-header{padding:var(--card-header-padding);display:flex;align-items:flex-start;gap:var(--card-header-gap);background:var(--surface-ground);position:relative}.card-header.has-divider{border-bottom:1px solid var(--surface-border)}.card-header-content{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--spacing-xs)}.card-title{font-size:var(--font-size-lg, 1.125rem);font-weight:600;line-height:1.4;color:var(--text-color);margin:0;overflow:hidden;text-overflow:ellipsis}.card-description{font-size:var(--font-size-sm, .875rem);line-height:1.5;color:var(--text-color-secondary);margin:0}[card-header-icon]{flex-shrink:0;display:flex;align-items:center;justify-content:center}[card-header-content]{flex:1;min-width:0}[card-header-extra]{flex-shrink:0;display:flex;align-items:center;gap:var(--spacing-sm)}.card-body{padding:var(--card-body-padding);flex:1;display:flex;flex-direction:column;gap:var(--card-body-gap);color:var(--text-color);line-height:1.6;overflow:hidden}.card-body.no-padding{padding:0}.card-body>*{margin:0}.card-body img{max-width:100%;height:auto;border-radius:var(--border-radius)}.card-body table{width:100%;max-width:100%;overflow-x:auto;display:block}.card-body pre{max-width:100%;overflow-x:auto;padding:var(--spacing-sm);background:var(--surface-ground);border-radius:var(--border-radius);font-size:var(--font-size-sm)}.card-body video,.card-body iframe{max-width:100%;height:auto}.card-footer{padding:var(--card-footer-padding);background:var(--surface-ground);display:flex;align-items:center;gap:var(--size-4);flex-wrap:wrap;font-size:var(--font-size-sm, .875rem);color:var(--text-color-secondary)}.card-footer:empty{display:none}.card-footer.has-divider{border-top:1px solid var(--surface-border)}.card-actions{padding:var(--card-actions-padding);background:var(--surface-ground);display:flex;align-items:center;gap:var(--spacing-md);justify-content:flex-end}.card-actions>*{flex-shrink:0;display:flex;gap:var(--spacing-sm)}.card-actions:empty{display:none}.card-actions.has-divider{border-top:1px solid var(--surface-border)}.card-actions.actions-align-left{justify-content:flex-start}.card-actions.actions-align-center{justify-content:center}.card-actions.actions-align-right{justify-content:flex-end}.card-actions.actions-align-space-between{justify-content:space-between}.card-actions.mobile-full-width-buttons{flex-direction:column;gap:var(--spacing-sm)}.card-actions.mobile-full-width-buttons>*{display:flex;flex-direction:column;width:100%;gap:var(--spacing-sm)}.card.hoverable:hover{transform:translateY(-2px)}.card.interactive{cursor:pointer;-webkit-user-select:none;user-select:none}.card.interactive:focus{outline:none;box-shadow:0 0 0 3px rgba(var(--primary-500-rgb, 59, 130, 246),.2)}.card.interactive:focus:not(:focus-visible){box-shadow:none}.card.interactive:active{transform:translateY(0)}.card.disabled{opacity:.6;pointer-events:none;cursor:not-allowed}.card.loading{pointer-events:none}.card-loading{display:flex;flex-direction:column;gap:var(--size-3);animation:pulse 1.5s ease-in-out infinite}.skeleton-line{height:var(--size-4);background:linear-gradient(90deg,var(--surface-border) 25%,var(--surface-hover) 50%,var(--surface-border) 75%);background-size:200% 100%;animation:shimmer 1.5s ease-in-out infinite;border-radius:var(--spacing-xs)}.skeleton-line.short{width:60%}@keyframes shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}@keyframes pulse{0%,to{opacity:1}50%{opacity:.7}}@media(max-width:1024px){.card.density-spacious{--card-header-padding: var(--size-5) var(--size-6);--card-body-padding: var(--size-7);--card-footer-padding: var(--size-4-5) var(--size-6);--card-actions-padding: var(--size-4-5) var(--size-6)}}@media(max-width:768px){.card.density-compact{--card-header-padding: var(--size-2-5) var(--size-3);--card-body-padding: var(--size-3);--card-footer-padding: var(--size-2-5) var(--size-3);--card-actions-padding: var(--size-2-5) var(--size-3)}.card.density-normal{--card-header-padding: var(--size-3) var(--size-4);--card-body-padding: var(--size-4);--card-footer-padding: var(--size-3) var(--size-4);--card-actions-padding: var(--size-3) var(--size-4)}.card.density-spacious{--card-header-padding: var(--size-4) var(--size-5);--card-body-padding: var(--size-5);--card-footer-padding: var(--size-4) var(--size-5);--card-actions-padding: var(--size-4) var(--size-5)}.card-title{font-size:clamp(.9375rem,2vw,1rem)}.card-description{font-size:var(--font-size-xs)}.card-footer{font-size:var(--font-size-xs);gap:var(--size-3)}}@media(max-width:640px){.card-actions{flex-direction:column;gap:var(--spacing-md)}.card-actions>*{flex-direction:column;width:100%}}@media(max-width:480px){.card.density-compact{--card-header-padding: var(--spacing-sm) var(--size-3);--card-body-padding: var(--size-3);--card-footer-padding: var(--spacing-sm) var(--size-3);--card-actions-padding: var(--spacing-sm) var(--size-3)}.card.density-normal{--card-header-padding: var(--size-2-5) var(--size-3);--card-body-padding: var(--size-3);--card-footer-padding: var(--size-2-5) var(--size-3);--card-actions-padding: var(--size-2-5) var(--size-3)}.card.density-spacious{--card-header-padding: var(--size-3) var(--size-4);--card-body-padding: var(--size-4);--card-footer-padding: var(--size-3) var(--size-4);--card-actions-padding: var(--size-3) var(--size-4)}.card-header{flex-wrap:wrap;gap:var(--spacing-xs)}.card-title{font-size:clamp(.875rem,3vw,.9375rem);line-height:1.3}.card-description{font-size:var(--font-size-xs);line-height:1.4}[card-header-icon],[card-header-extra]{width:100%;justify-content:flex-start}.card-footer{flex-direction:column;align-items:flex-start;gap:var(--spacing-sm)}.card-actions{flex-direction:column;gap:var(--spacing-sm)}}\n"] }]
445
+ }], ctorParameters: () => [], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }, { type: i0.Output, args: ["variantChange"] }], hoverable: [{ type: i0.Input, args: [{ isSignal: true, alias: "hoverable", required: false }] }, { type: i0.Output, args: ["hoverableChange"] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }, { type: i0.Output, args: ["interactiveChange"] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], colorVariant: [{ type: i0.Input, args: [{ isSignal: true, alias: "colorVariant", required: false }] }], density: [{ type: i0.Input, args: [{ isSignal: true, alias: "density", required: false }] }], showHeaderDivider: [{ type: i0.Input, args: [{ isSignal: true, alias: "showHeaderDivider", required: false }] }], showFooterDivider: [{ type: i0.Input, args: [{ isSignal: true, alias: "showFooterDivider", required: false }] }], showActionsDivider: [{ type: i0.Input, args: [{ isSignal: true, alias: "showActionsDivider", required: false }] }], actionsAlignment: [{ type: i0.Input, args: [{ isSignal: true, alias: "actionsAlignment", required: false }] }], bodyPadding: [{ type: i0.Input, args: [{ isSignal: true, alias: "bodyPadding", required: false }] }], cssClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "cssClass", required: false }] }], customStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "customStyle", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], clicked: [{ type: i0.Output, args: ["clicked"] }] } });
442
446
 
443
447
  const TAG_CONFIG = new InjectionToken('TAG_CONFIG', {
444
448
  factory: () => ({
@@ -955,9 +959,9 @@ let checkboxIdCounter = 0;
955
959
  class PshCheckboxComponent {
956
960
  constructor() {
957
961
  this.config = inject(CHECKBOX_CONFIG);
958
- this.uniqueId = `checkbox-${++checkboxIdCounter}`;
959
962
  this.checkboxInput = viewChild('checkboxInput', ...(ngDevMode ? [{ debugName: "checkboxInput" }] : []));
960
- this.onChange = (value) => { };
963
+ this.uniqueId = `psh-cb-${++checkboxIdCounter}`;
964
+ this.onChange = (_) => { };
961
965
  this.onTouched = () => { };
962
966
  this.checked = model(this.config.checked ?? false, ...(ngDevMode ? [{ debugName: "checked" }] : []));
963
967
  this.disabled = model(this.config.disabled ?? false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
@@ -965,46 +969,44 @@ class PshCheckboxComponent {
965
969
  this.touched = model(false, ...(ngDevMode ? [{ debugName: "touched" }] : []));
966
970
  this.required = input(this.config.required ?? false, ...(ngDevMode ? [{ debugName: "required" }] : []));
967
971
  this.label = input(this.config.label ?? '', ...(ngDevMode ? [{ debugName: "label" }] : []));
968
- this.error = input('', ...(ngDevMode ? [{ debugName: "error" }] : []));
969
- this.success = input('', ...(ngDevMode ? [{ debugName: "success" }] : []));
970
- this.ariaLabel = input(...(ngDevMode ? [undefined, { debugName: "ariaLabel" }] : []));
972
+ this.error = input(this.config.error, ...(ngDevMode ? [{ debugName: "error" }] : []));
973
+ this.success = input(this.config.success, ...(ngDevMode ? [{ debugName: "success" }] : []));
974
+ this.ariaLabel = input(this.config.ariaLabel, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
971
975
  this.size = input(this.config.size ?? 'medium', ...(ngDevMode ? [{ debugName: "size" }] : []));
972
976
  this.labelPosition = input(this.config.labelPosition ?? 'right', ...(ngDevMode ? [{ debugName: "labelPosition" }] : []));
973
977
  this.ariaChecked = computed(() => this.indeterminate() ? 'mixed' : (this.checked() ? 'true' : 'false'), ...(ngDevMode ? [{ debugName: "ariaChecked" }] : []));
974
- this.computedAriaLabel = computed(() => this.ariaLabel(), ...(ngDevMode ? [{ debugName: "computedAriaLabel" }] : []));
975
- this.errorMessageId = computed(() => this.error() ? `${this.uniqueId}-error` : undefined, ...(ngDevMode ? [{ debugName: "errorMessageId" }] : []));
976
- this.successMessageId = computed(() => this.success() ? `${this.uniqueId}-success` : undefined, ...(ngDevMode ? [{ debugName: "successMessageId" }] : []));
978
+ this.computedAriaLabel = computed(() => this.ariaLabel() || this.label() || undefined, ...(ngDevMode ? [{ debugName: "computedAriaLabel" }] : []));
977
979
  this.ariaDescribedBy = computed(() => {
978
980
  const ids = [];
979
- if (this.errorMessageId())
980
- ids.push(this.errorMessageId());
981
- if (this.successMessageId())
982
- ids.push(this.successMessageId());
981
+ if (this.error())
982
+ ids.push(`${this.uniqueId}-error`);
983
+ if (this.success())
984
+ ids.push(`${this.uniqueId}-success`);
983
985
  return ids.length > 0 ? ids.join(' ') : undefined;
984
986
  }, ...(ngDevMode ? [{ debugName: "ariaDescribedBy" }] : []));
985
- this.state = computed(() => this.getState(), ...(ngDevMode ? [{ debugName: "state" }] : []));
987
+ this.state = computed(() => {
988
+ if (this.disabled())
989
+ return 'disabled';
990
+ if (this.indeterminate())
991
+ return 'indeterminate';
992
+ if (this.error())
993
+ return 'error';
994
+ if (this.success())
995
+ return 'success';
996
+ return this.checked() ? 'checked' : 'unchecked';
997
+ }, ...(ngDevMode ? [{ debugName: "state" }] : []));
986
998
  effect(() => {
987
999
  if (!this.label() && !this.ariaLabel()) {
988
- console.warn('[psh-checkbox] No accessible label provided. Please use label input or ariaLabel input.');
1000
+ console.warn('[psh-checkbox] Label manquant pour l\'accessibilité.');
989
1001
  }
990
- }, { allowSignalWrites: false });
991
- }
992
- getState() {
993
- if (this.disabled())
994
- return 'disabled';
995
- if (this.indeterminate())
996
- return 'indeterminate';
997
- if (this.error())
998
- return 'error';
999
- if (this.success())
1000
- return 'success';
1001
- return this.checked() ? 'checked' : 'unchecked';
1002
+ });
1002
1003
  }
1003
1004
  toggle() {
1004
1005
  if (!this.disabled()) {
1005
- this.checked.update(v => !v);
1006
+ const newValue = !this.checked();
1007
+ this.checked.set(newValue);
1006
1008
  this.indeterminate.set(false);
1007
- this.onChange(this.checked());
1009
+ this.onChange(newValue);
1008
1010
  this.onTouched();
1009
1011
  this.touched.set(true);
1010
1012
  }
@@ -1012,49 +1014,26 @@ class PshCheckboxComponent {
1012
1014
  handleKeydown(event) {
1013
1015
  if (this.disabled())
1014
1016
  return;
1015
- if (event.key === ' ' || event.key === 'Spacebar') {
1016
- event.preventDefault();
1017
- this.toggle();
1018
- }
1019
- else if (event.key === 'Enter') {
1017
+ if (event.key === ' ' || event.key === 'Spacebar' || event.key === 'Enter') {
1020
1018
  event.preventDefault();
1021
1019
  this.toggle();
1022
1020
  }
1023
1021
  }
1024
- writeValue(value) {
1025
- this.checked.set(value ?? false);
1026
- }
1027
- registerOnChange(fn) {
1028
- this.onChange = fn;
1029
- }
1030
- registerOnTouched(fn) {
1031
- this.onTouched = fn;
1032
- }
1033
- setDisabledState(isDisabled) {
1034
- this.disabled.set(isDisabled);
1035
- }
1036
- focus() {
1037
- const el = this.checkboxInput();
1038
- if (el?.nativeElement) {
1039
- el.nativeElement.focus();
1040
- }
1041
- }
1042
- blur() {
1043
- const el = this.checkboxInput();
1044
- if (el?.nativeElement) {
1045
- el.nativeElement.blur();
1046
- }
1047
- }
1022
+ writeValue(value) { this.checked.set(!!value); }
1023
+ registerOnChange(fn) { this.onChange = fn; }
1024
+ registerOnTouched(fn) { this.onTouched = fn; }
1025
+ setDisabledState(isDisabled) { this.disabled.set(isDisabled); }
1026
+ focus() { this.checkboxInput()?.nativeElement.focus(); }
1048
1027
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: PshCheckboxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1049
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: PshCheckboxComponent, isStandalone: true, selector: "psh-checkbox", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, indeterminate: { classPropertyName: "indeterminate", publicName: "indeterminate", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, success: { classPropertyName: "success", publicName: "success", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, labelPosition: { classPropertyName: "labelPosition", publicName: "labelPosition", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange", disabled: "disabledChange", indeterminate: "indeterminateChange", touched: "touchedChange" }, host: { properties: { "class.checkbox-disabled": "disabled()", "class.checkbox-error": "!!error()", "class.checkbox-success": "!!success()", "class.checkbox-small": "size() === \"small\"", "class.checkbox-large": "size() === \"large\"", "attr.data-state": "state()" } }, providers: [{
1028
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: PshCheckboxComponent, isStandalone: true, selector: "psh-checkbox", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, indeterminate: { classPropertyName: "indeterminate", publicName: "indeterminate", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, success: { classPropertyName: "success", publicName: "success", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, labelPosition: { classPropertyName: "labelPosition", publicName: "labelPosition", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange", disabled: "disabledChange", indeterminate: "indeterminateChange", touched: "touchedChange" }, host: { properties: { "class.checkbox-disabled": "disabled()", "class.checkbox-error": "!!error()", "class.checkbox-success": "!!success()", "class.checkbox-small": "size() === \"small\"", "class.checkbox-large": "size() === \"large\"", "class.checkbox-checked": "checked() && !indeterminate()", "class.checkbox-indeterminate": "indeterminate()", "attr.data-state": "state()", "attr.aria-checked": "ariaChecked()" } }, providers: [{
1050
1029
  provide: NG_VALUE_ACCESSOR,
1051
1030
  useExisting: PshCheckboxComponent,
1052
1031
  multi: true
1053
- }], viewQueries: [{ propertyName: "checkboxInput", first: true, predicate: ["checkboxInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"checkbox-container\">\n <label class=\"checkbox-label\" [class.label-left]=\"labelPosition() === 'left'\">\n <input\n #checkboxInput\n type=\"checkbox\"\n class=\"checkbox-input\"\n [checked]=\"checked()\"\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n [attr.aria-label]=\"computedAriaLabel()\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"error() ? 'true' : null\"\n [attr.aria-checked]=\"ariaChecked()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n (change)=\"toggle()\"\n (keydown)=\"handleKeydown($event)\"\n />\n <span \n class=\"checkbox-control\"\n [class.error]=\"!!error()\"\n [class.success]=\"!!success()\"\n [class.indeterminate]=\"indeterminate()\"\n >\n @if (checked() && !indeterminate()) {\n <i class=\"ph ph-check\" aria-hidden=\"true\"></i>\n }\n @if (indeterminate()) {\n <i class=\"ph ph-minus\" aria-hidden=\"true\"></i>\n }\n </span>\n <span class=\"checkbox-text\">\n @if (label()) {\n {{ label() }}\n } @else {\n <ng-content></ng-content>\n }\n </span>\n </label>\n\n @if (error()) {\n <div [id]=\"errorMessageId()\" class=\"checkbox-error\" role=\"alert\">\n {{ error() }}\n </div>\n }\n\n @if (success()) {\n <div [id]=\"successMessageId()\" class=\"checkbox-success\" role=\"status\">\n {{ success() }}\n </div>\n }\n</div>", styles: [".checkbox-container{display:inline-flex;flex-direction:column;gap:var(--spacing-xs)}.checkbox-label{display:inline-flex;align-items:center;gap:var(--spacing-sm);cursor:pointer;-webkit-user-select:none;user-select:none;color:var(--text-color)}.checkbox-label.label-left{flex-direction:row-reverse;justify-content:space-between}.checkbox-input{position:absolute;opacity:0;width:0;height:0}.checkbox-control{display:flex;align-items:center;justify-content:center;width:var(--size-4-5);height:var(--size-4-5);min-width:var(--size-4-5);min-height:var(--size-4-5);border:var(--border-width-2) solid var(--surface-border);border-radius:var(--border-radius);background:var(--surface-card);transition:background-color var(--animation-duration-fast) var(--animation-easing-default),border-color var(--animation-duration-fast) var(--animation-easing-default);color:var(--primary-color-text);position:relative;flex-shrink:0}.checkbox-input:checked+.checkbox-control{background:var(--primary-color);border-color:var(--primary-color)}.checkbox-input:focus-visible+.checkbox-control{outline:var(--focus-outline-width) var(--focus-outline-style) var(--focus-outline-color);outline-offset:var(--focus-outline-offset)}.checkbox-control i{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%) scale(0);font-size:var(--font-size-xs);opacity:0;transition:opacity var(--animation-duration-fast) var(--animation-easing-default),transform var(--animation-duration-fast) var(--animation-easing-default)}.checkbox-input:checked+.checkbox-control i,.checkbox-control.indeterminate i{opacity:1;transform:translate(-50%,-50%) scale(1.1)}.checkbox-control.indeterminate{background:var(--primary-color);border-color:var(--primary-color)}:host(.checkbox-disabled) .checkbox-label{opacity:var(--opacity-disabled);cursor:not-allowed}:host(.checkbox-error) .checkbox-control{border-color:var(--danger-color)}:host(.checkbox-error) .checkbox-input:checked+.checkbox-control{background:var(--danger-color);border-color:var(--danger-color)}:host(.checkbox-success) .checkbox-control{border-color:var(--success-color)}:host(.checkbox-success) .checkbox-input:checked+.checkbox-control{background:var(--success-color);border-color:var(--success-color)}.checkbox-error{font-size:var(--font-size-sm);color:var(--danger-color)}.checkbox-success{font-size:var(--font-size-sm);color:var(--success-color)}:host(.checkbox-small) .checkbox-control{width:var(--size-4);height:var(--size-4);min-width:var(--size-4);min-height:var(--size-4)}:host(.checkbox-small) .checkbox-text{font-size:var(--font-size-sm)}:host(.checkbox-large) .checkbox-control{width:var(--size-5-5);height:var(--size-5-5);min-width:var(--size-5-5);min-height:var(--size-5-5)}:host(.checkbox-large) .checkbox-text{font-size:var(--font-size-lg)}.checkbox-text{color:var(--text-color)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1032
+ }], viewQueries: [{ propertyName: "checkboxInput", first: true, predicate: ["checkboxInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"checkbox-container\">\n <label class=\"checkbox-label\" [class.label-left]=\"labelPosition() === 'left'\">\n <input\n #checkboxInput\n type=\"checkbox\"\n class=\"checkbox-input\"\n [checked]=\"checked()\"\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n [attr.aria-label]=\"computedAriaLabel()\"\n [attr.aria-checked]=\"ariaChecked()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n (change)=\"toggle()\"\n (keydown)=\"handleKeydown($event)\"\n />\n \n <span class=\"checkbox-control\">\n @if (checked() && !indeterminate()) {\n <i class=\"ph ph-check\" aria-hidden=\"true\"></i>\n }\n @if (indeterminate()) {\n <i class=\"ph ph-minus\" aria-hidden=\"true\"></i>\n }\n </span>\n\n <span class=\"checkbox-text\">\n @if (label()) {\n {{ label() }}\n } @else {\n <ng-content></ng-content>\n }\n </span>\n </label>\n\n @if (error()) {\n <div [id]=\"uniqueId + '-error'\" class=\"checkbox-message error\" role=\"alert\">\n {{ error() }}\n </div>\n }\n @if (success()) {\n <div [id]=\"uniqueId + '-success'\" class=\"checkbox-message success\" role=\"status\">\n {{ success() }}\n </div>\n }\n</div>", styles: [":host{display:inline-flex;flex-direction:column;gap:.5rem}.checkbox-container{display:flex;flex-direction:column}.checkbox-label{display:inline-flex;align-items:center;gap:.75rem;cursor:pointer;-webkit-user-select:none;user-select:none;color:var(--text-color)}.checkbox-label.label-left{flex-direction:row-reverse;justify-content:space-between}.checkbox-input{position:absolute;opacity:0;width:0;height:0}.checkbox-control{display:flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;border:.125rem solid var(--surface-border);border-radius:var(--border-radius);background:var(--surface-card);transition:all var(--animation-duration-fast) var(--animation-easing-default);color:#fff;position:relative;flex-shrink:0}:host.checkbox-checked .checkbox-control,:host.checkbox-indeterminate .checkbox-control{background:var(--primary-color);border-color:var(--primary-color)}.checkbox-input:focus-visible+.checkbox-control{outline:.125rem solid var(--focus-outline-color);outline-offset:.125rem}.checkbox-control i{font-size:.875rem;line-height:1}:host.checkbox-small .checkbox-control{width:1rem;height:1rem}:host.checkbox-large .checkbox-control{width:1.5rem;height:1.5rem}:host.checkbox-error .checkbox-control{border-color:var(--danger-color)}:host.checkbox-error.checkbox-checked .checkbox-control{background:var(--danger-color)}:host.checkbox-success .checkbox-control{border-color:var(--success-color)}:host.checkbox-success.checkbox-checked .checkbox-control{background:var(--success-color)}:host.checkbox-disabled{opacity:var(--opacity-disabled);cursor:not-allowed}:host.checkbox-disabled .checkbox-label{cursor:not-allowed}.checkbox-message{font-size:.875rem;margin-top:.125rem}.checkbox-message.error{color:var(--danger-color)}.checkbox-message.success{color:var(--success-color)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1054
1033
  }
1055
1034
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: PshCheckboxComponent, decorators: [{
1056
1035
  type: Component,
1057
- args: [{ selector: 'psh-checkbox', imports: [], changeDetection: ChangeDetectionStrategy.OnPush, providers: [{
1036
+ args: [{ selector: 'psh-checkbox', standalone: true, imports: [], changeDetection: ChangeDetectionStrategy.OnPush, providers: [{
1058
1037
  provide: NG_VALUE_ACCESSOR,
1059
1038
  useExisting: PshCheckboxComponent,
1060
1039
  multi: true
@@ -1064,8 +1043,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
1064
1043
  '[class.checkbox-success]': '!!success()',
1065
1044
  '[class.checkbox-small]': 'size() === "small"',
1066
1045
  '[class.checkbox-large]': 'size() === "large"',
1067
- '[attr.data-state]': 'state()'
1068
- }, template: "<div class=\"checkbox-container\">\n <label class=\"checkbox-label\" [class.label-left]=\"labelPosition() === 'left'\">\n <input\n #checkboxInput\n type=\"checkbox\"\n class=\"checkbox-input\"\n [checked]=\"checked()\"\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n [attr.aria-label]=\"computedAriaLabel()\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"error() ? 'true' : null\"\n [attr.aria-checked]=\"ariaChecked()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n (change)=\"toggle()\"\n (keydown)=\"handleKeydown($event)\"\n />\n <span \n class=\"checkbox-control\"\n [class.error]=\"!!error()\"\n [class.success]=\"!!success()\"\n [class.indeterminate]=\"indeterminate()\"\n >\n @if (checked() && !indeterminate()) {\n <i class=\"ph ph-check\" aria-hidden=\"true\"></i>\n }\n @if (indeterminate()) {\n <i class=\"ph ph-minus\" aria-hidden=\"true\"></i>\n }\n </span>\n <span class=\"checkbox-text\">\n @if (label()) {\n {{ label() }}\n } @else {\n <ng-content></ng-content>\n }\n </span>\n </label>\n\n @if (error()) {\n <div [id]=\"errorMessageId()\" class=\"checkbox-error\" role=\"alert\">\n {{ error() }}\n </div>\n }\n\n @if (success()) {\n <div [id]=\"successMessageId()\" class=\"checkbox-success\" role=\"status\">\n {{ success() }}\n </div>\n }\n</div>", styles: [".checkbox-container{display:inline-flex;flex-direction:column;gap:var(--spacing-xs)}.checkbox-label{display:inline-flex;align-items:center;gap:var(--spacing-sm);cursor:pointer;-webkit-user-select:none;user-select:none;color:var(--text-color)}.checkbox-label.label-left{flex-direction:row-reverse;justify-content:space-between}.checkbox-input{position:absolute;opacity:0;width:0;height:0}.checkbox-control{display:flex;align-items:center;justify-content:center;width:var(--size-4-5);height:var(--size-4-5);min-width:var(--size-4-5);min-height:var(--size-4-5);border:var(--border-width-2) solid var(--surface-border);border-radius:var(--border-radius);background:var(--surface-card);transition:background-color var(--animation-duration-fast) var(--animation-easing-default),border-color var(--animation-duration-fast) var(--animation-easing-default);color:var(--primary-color-text);position:relative;flex-shrink:0}.checkbox-input:checked+.checkbox-control{background:var(--primary-color);border-color:var(--primary-color)}.checkbox-input:focus-visible+.checkbox-control{outline:var(--focus-outline-width) var(--focus-outline-style) var(--focus-outline-color);outline-offset:var(--focus-outline-offset)}.checkbox-control i{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%) scale(0);font-size:var(--font-size-xs);opacity:0;transition:opacity var(--animation-duration-fast) var(--animation-easing-default),transform var(--animation-duration-fast) var(--animation-easing-default)}.checkbox-input:checked+.checkbox-control i,.checkbox-control.indeterminate i{opacity:1;transform:translate(-50%,-50%) scale(1.1)}.checkbox-control.indeterminate{background:var(--primary-color);border-color:var(--primary-color)}:host(.checkbox-disabled) .checkbox-label{opacity:var(--opacity-disabled);cursor:not-allowed}:host(.checkbox-error) .checkbox-control{border-color:var(--danger-color)}:host(.checkbox-error) .checkbox-input:checked+.checkbox-control{background:var(--danger-color);border-color:var(--danger-color)}:host(.checkbox-success) .checkbox-control{border-color:var(--success-color)}:host(.checkbox-success) .checkbox-input:checked+.checkbox-control{background:var(--success-color);border-color:var(--success-color)}.checkbox-error{font-size:var(--font-size-sm);color:var(--danger-color)}.checkbox-success{font-size:var(--font-size-sm);color:var(--success-color)}:host(.checkbox-small) .checkbox-control{width:var(--size-4);height:var(--size-4);min-width:var(--size-4);min-height:var(--size-4)}:host(.checkbox-small) .checkbox-text{font-size:var(--font-size-sm)}:host(.checkbox-large) .checkbox-control{width:var(--size-5-5);height:var(--size-5-5);min-width:var(--size-5-5);min-height:var(--size-5-5)}:host(.checkbox-large) .checkbox-text{font-size:var(--font-size-lg)}.checkbox-text{color:var(--text-color)}\n"] }]
1046
+ '[class.checkbox-checked]': 'checked() && !indeterminate()',
1047
+ '[class.checkbox-indeterminate]': 'indeterminate()',
1048
+ '[attr.data-state]': 'state()',
1049
+ '[attr.aria-checked]': 'ariaChecked()'
1050
+ }, template: "<div class=\"checkbox-container\">\n <label class=\"checkbox-label\" [class.label-left]=\"labelPosition() === 'left'\">\n <input\n #checkboxInput\n type=\"checkbox\"\n class=\"checkbox-input\"\n [checked]=\"checked()\"\n [disabled]=\"disabled()\"\n [required]=\"required()\"\n [attr.aria-label]=\"computedAriaLabel()\"\n [attr.aria-checked]=\"ariaChecked()\"\n [attr.aria-describedby]=\"ariaDescribedBy()\"\n (change)=\"toggle()\"\n (keydown)=\"handleKeydown($event)\"\n />\n \n <span class=\"checkbox-control\">\n @if (checked() && !indeterminate()) {\n <i class=\"ph ph-check\" aria-hidden=\"true\"></i>\n }\n @if (indeterminate()) {\n <i class=\"ph ph-minus\" aria-hidden=\"true\"></i>\n }\n </span>\n\n <span class=\"checkbox-text\">\n @if (label()) {\n {{ label() }}\n } @else {\n <ng-content></ng-content>\n }\n </span>\n </label>\n\n @if (error()) {\n <div [id]=\"uniqueId + '-error'\" class=\"checkbox-message error\" role=\"alert\">\n {{ error() }}\n </div>\n }\n @if (success()) {\n <div [id]=\"uniqueId + '-success'\" class=\"checkbox-message success\" role=\"status\">\n {{ success() }}\n </div>\n }\n</div>", styles: [":host{display:inline-flex;flex-direction:column;gap:.5rem}.checkbox-container{display:flex;flex-direction:column}.checkbox-label{display:inline-flex;align-items:center;gap:.75rem;cursor:pointer;-webkit-user-select:none;user-select:none;color:var(--text-color)}.checkbox-label.label-left{flex-direction:row-reverse;justify-content:space-between}.checkbox-input{position:absolute;opacity:0;width:0;height:0}.checkbox-control{display:flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;border:.125rem solid var(--surface-border);border-radius:var(--border-radius);background:var(--surface-card);transition:all var(--animation-duration-fast) var(--animation-easing-default);color:#fff;position:relative;flex-shrink:0}:host.checkbox-checked .checkbox-control,:host.checkbox-indeterminate .checkbox-control{background:var(--primary-color);border-color:var(--primary-color)}.checkbox-input:focus-visible+.checkbox-control{outline:.125rem solid var(--focus-outline-color);outline-offset:.125rem}.checkbox-control i{font-size:.875rem;line-height:1}:host.checkbox-small .checkbox-control{width:1rem;height:1rem}:host.checkbox-large .checkbox-control{width:1.5rem;height:1.5rem}:host.checkbox-error .checkbox-control{border-color:var(--danger-color)}:host.checkbox-error.checkbox-checked .checkbox-control{background:var(--danger-color)}:host.checkbox-success .checkbox-control{border-color:var(--success-color)}:host.checkbox-success.checkbox-checked .checkbox-control{background:var(--success-color)}:host.checkbox-disabled{opacity:var(--opacity-disabled);cursor:not-allowed}:host.checkbox-disabled .checkbox-label{cursor:not-allowed}.checkbox-message{font-size:.875rem;margin-top:.125rem}.checkbox-message.error{color:var(--danger-color)}.checkbox-message.success{color:var(--success-color)}\n"] }]
1069
1051
  }], ctorParameters: () => [], propDecorators: { checkboxInput: [{ type: i0.ViewChild, args: ['checkboxInput', { isSignal: true }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }, { type: i0.Output, args: ["disabledChange"] }], indeterminate: [{ type: i0.Input, args: [{ isSignal: true, alias: "indeterminate", required: false }] }, { type: i0.Output, args: ["indeterminateChange"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], success: [{ type: i0.Input, args: [{ isSignal: true, alias: "success", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], labelPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelPosition", required: false }] }] } });
1070
1052
 
1071
1053
  class PshCollapseComponent {
@@ -1452,34 +1434,25 @@ class PshInputComponent {
1452
1434
  }
1453
1435
  return this.type();
1454
1436
  }, ...(ngDevMode ? [{ debugName: "effectiveType" }] : []));
1455
- this.computedAriaLabel = computed(() => {
1456
- return this.ariaLabel() || this.label() || this.placeholder();
1457
- }, ...(ngDevMode ? [{ debugName: "computedAriaLabel" }] : []));
1458
- this.passwordToggleLabel = computed(() => {
1459
- return this.passwordVisible() ? INPUT_LABELS.hidePassword : INPUT_LABELS.showPassword;
1460
- }, ...(ngDevMode ? [{ debugName: "passwordToggleLabel" }] : []));
1437
+ this.computedAriaLabel = computed(() => this.ariaLabel() || this.label() || this.placeholder(), ...(ngDevMode ? [{ debugName: "computedAriaLabel" }] : []));
1438
+ this.passwordToggleLabel = computed(() => this.passwordVisible() ? INPUT_LABELS.hidePassword : INPUT_LABELS.showPassword, ...(ngDevMode ? [{ debugName: "passwordToggleLabel" }] : []));
1461
1439
  this.state = computed(() => this.getState(), ...(ngDevMode ? [{ debugName: "state" }] : []));
1462
1440
  this.onChange = (_) => { };
1463
1441
  this.onTouched = () => { };
1464
1442
  this.destroyRef.onDestroy(() => {
1465
- if (this.blurTimeoutId !== null) {
1466
- clearTimeout(this.blurTimeoutId);
1467
- }
1468
- if (this.debounceTimeoutId !== null) {
1469
- clearTimeout(this.debounceTimeoutId);
1470
- }
1443
+ if (this.blurTimeoutId)
1444
+ window.clearTimeout(this.blurTimeoutId);
1445
+ if (this.debounceTimeoutId)
1446
+ window.clearTimeout(this.debounceTimeoutId);
1471
1447
  });
1472
1448
  }
1473
1449
  writeValue(value) {
1474
- this.value.set(value ?? '');
1450
+ const safeValue = typeof value === 'string' ? value : '';
1451
+ this.value.set(safeValue);
1475
1452
  this.cdr.markForCheck();
1476
1453
  }
1477
- registerOnChange(fn) {
1478
- this.onChange = fn;
1479
- }
1480
- registerOnTouched(fn) {
1481
- this.onTouched = fn;
1482
- }
1454
+ registerOnChange(fn) { this.onChange = fn; }
1455
+ registerOnTouched(fn) { this.onTouched = fn; }
1483
1456
  setDisabledState(isDisabled) {
1484
1457
  this.disabled.set(isDisabled);
1485
1458
  }
@@ -1494,8 +1467,9 @@ class PshInputComponent {
1494
1467
  handleFocus() {
1495
1468
  this.focusedSignal.set(true);
1496
1469
  this.inputFocus.emit();
1497
- if (this.suggestions() && this.value().length >= this.autocompleteConfig().minLength) {
1498
- this.updateSuggestions(this.value());
1470
+ const val = this.value();
1471
+ if (this.suggestions() && val.length >= this.autocompleteConfig().minLength) {
1472
+ this.updateSuggestions(val);
1499
1473
  }
1500
1474
  }
1501
1475
  handleBlur() {
@@ -1503,9 +1477,8 @@ class PshInputComponent {
1503
1477
  this.inputBlur.emit();
1504
1478
  this.onTouched();
1505
1479
  this.touched.set(true);
1506
- if (this.blurTimeoutId !== null) {
1507
- clearTimeout(this.blurTimeoutId);
1508
- }
1480
+ if (this.blurTimeoutId)
1481
+ window.clearTimeout(this.blurTimeoutId);
1509
1482
  this.blurTimeoutId = window.setTimeout(() => {
1510
1483
  this.suggestionsVisible.set(false);
1511
1484
  this.focusedSuggestionIndex.set(-1);
@@ -1520,18 +1493,18 @@ class PshInputComponent {
1520
1493
  switch (event.key) {
1521
1494
  case 'ArrowDown':
1522
1495
  event.preventDefault();
1523
- this.focusedSuggestionIndex.update(i => i < suggestions.length - 1 ? i + 1 : 0);
1496
+ this.focusedSuggestionIndex.update(i => (i < suggestions.length - 1 ? i + 1 : 0));
1524
1497
  break;
1525
1498
  case 'ArrowUp':
1526
1499
  event.preventDefault();
1527
- this.focusedSuggestionIndex.update(i => i > 0 ? i - 1 : suggestions.length - 1);
1500
+ this.focusedSuggestionIndex.update(i => (i > 0 ? i - 1 : suggestions.length - 1));
1528
1501
  break;
1529
1502
  case 'Enter':
1530
- event.preventDefault();
1531
1503
  if (currentIndex >= 0 && currentIndex < suggestions.length) {
1532
- const selectedSuggestion = suggestions[currentIndex];
1533
- if (selectedSuggestion) {
1534
- this.handleSuggestionClick(selectedSuggestion);
1504
+ event.preventDefault();
1505
+ const selected = suggestions[currentIndex];
1506
+ if (selected !== undefined) {
1507
+ this.handleSuggestionClick(selected);
1535
1508
  }
1536
1509
  }
1537
1510
  break;
@@ -1543,12 +1516,11 @@ class PshInputComponent {
1543
1516
  }
1544
1517
  }
1545
1518
  handleSuggestionClick(suggestion) {
1546
- if (suggestion) {
1547
- this.value.set(suggestion);
1548
- this.onChange(suggestion);
1549
- this.suggestionSelect.emit(suggestion);
1550
- this.suggestionsVisible.set(false);
1551
- }
1519
+ this.value.set(suggestion);
1520
+ this.onChange(suggestion);
1521
+ this.suggestionSelect.emit(suggestion);
1522
+ this.suggestionsVisible.set(false);
1523
+ this.focusedSuggestionIndex.set(-1);
1552
1524
  }
1553
1525
  togglePasswordVisibility() {
1554
1526
  this.passwordVisibleSignal.update(v => !v);
@@ -1558,62 +1530,68 @@ class PshInputComponent {
1558
1530
  }
1559
1531
  focus() {
1560
1532
  const inputEl = this.elementRef.nativeElement.querySelector('input');
1561
- if (inputEl) {
1562
- inputEl.focus();
1563
- }
1533
+ inputEl?.focus();
1564
1534
  }
1565
1535
  focusSelect() {
1566
1536
  this.focus();
1567
1537
  }
1568
1538
  debouncedUpdateSuggestions(value) {
1569
- if (this.debounceTimeoutId !== null) {
1570
- clearTimeout(this.debounceTimeoutId);
1571
- }
1572
- const debounceTime = this.autocompleteConfig().debounceTime;
1539
+ if (this.debounceTimeoutId)
1540
+ window.clearTimeout(this.debounceTimeoutId);
1573
1541
  this.debounceTimeoutId = window.setTimeout(() => {
1574
1542
  this.updateSuggestions(value);
1575
1543
  this.debounceTimeoutId = null;
1576
- }, debounceTime);
1544
+ }, this.autocompleteConfig().debounceTime);
1577
1545
  }
1578
1546
  async updateSuggestions(value) {
1579
- const suggestionsValue = this.suggestions();
1580
- if (typeof suggestionsValue === 'function') {
1581
- try {
1582
- const results = await suggestionsValue(value);
1583
- if (Array.isArray(results)) {
1584
- this.filteredSuggestionsSignal.set(results);
1585
- this.suggestionsVisible.set(true);
1586
- }
1547
+ const provider = this.suggestions();
1548
+ try {
1549
+ let results = [];
1550
+ if (typeof provider === 'function') {
1551
+ results = await provider(value);
1587
1552
  }
1588
- catch (error) {
1589
- console.error('Error fetching suggestions:', error);
1590
- this.filteredSuggestionsSignal.set([]);
1553
+ else if (Array.isArray(provider)) {
1554
+ results = provider.filter(s => s.toLowerCase().includes(value.toLowerCase()));
1591
1555
  }
1556
+ this.filteredSuggestionsSignal.set(results);
1557
+ this.suggestionsVisible.set(results.length > 0);
1592
1558
  }
1593
- else if (Array.isArray(suggestionsValue)) {
1594
- const filtered = suggestionsValue.filter(suggestion => suggestion.toLowerCase().includes(value.toLowerCase()));
1595
- this.filteredSuggestionsSignal.set(filtered);
1596
- this.suggestionsVisible.set(true);
1559
+ catch (error) {
1560
+ this.filteredSuggestionsSignal.set([]);
1597
1561
  }
1598
1562
  }
1599
1563
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: PshInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1600
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: PshInputComponent, isStandalone: true, selector: "psh-input", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, showLabel: { classPropertyName: "showLabel", publicName: "showLabel", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, iconStart: { classPropertyName: "iconStart", publicName: "iconStart", isSignal: true, isRequired: false, transformFunction: null }, iconEnd: { classPropertyName: "iconEnd", publicName: "iconEnd", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, success: { classPropertyName: "success", publicName: "success", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, suggestions: { classPropertyName: "suggestions", publicName: "suggestions", isSignal: true, isRequired: false, transformFunction: null }, autocompleteConfig: { classPropertyName: "autocompleteConfig", publicName: "autocompleteConfig", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", disabled: "disabledChange", readonly: "readonlyChange", loading: "loadingChange", touched: "touchedChange", inputFocus: "inputFocus", inputBlur: "inputBlur", suggestionSelect: "suggestionSelect" }, providers: [
1564
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: PshInputComponent, isStandalone: true, selector: "psh-input", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, showLabel: { classPropertyName: "showLabel", publicName: "showLabel", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, iconStart: { classPropertyName: "iconStart", publicName: "iconStart", isSignal: true, isRequired: false, transformFunction: null }, iconEnd: { classPropertyName: "iconEnd", publicName: "iconEnd", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, success: { classPropertyName: "success", publicName: "success", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, suggestions: { classPropertyName: "suggestions", publicName: "suggestions", isSignal: true, isRequired: false, transformFunction: null }, autocompleteConfig: { classPropertyName: "autocompleteConfig", publicName: "autocompleteConfig", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", disabled: "disabledChange", readonly: "readonlyChange", loading: "loadingChange", touched: "touchedChange", inputFocus: "inputFocus", inputBlur: "inputBlur", suggestionSelect: "suggestionSelect" }, host: { properties: { "class.full-width": "fullWidth()", "class.small": "size() === \"small\"", "class.large": "size() === \"large\"", "class.error": "!!error()", "class.success": "!!success()", "class.disabled": "disabled()", "class.readonly": "readonly()", "class.loading": "loading()", "class.focused": "focused()", "class.has-start-icon": "!!iconStart()", "class.has-end-icon": "!!iconEnd() || type() === \"password\"", "class.outlined": "variant() === \"outlined\"", "class.filled": "variant() === \"filled\"" } }, providers: [
1601
1565
  {
1602
1566
  provide: NG_VALUE_ACCESSOR,
1603
- useExisting: forwardRef(() => PshInputComponent),
1567
+ useExisting: PshInputComponent,
1604
1568
  multi: true
1605
1569
  }
1606
- ], ngImport: i0, template: "<div \n class=\"input-container\"\n [class.full-width]=\"fullWidth()\"\n [class.small]=\"size() === 'small'\"\n [class.large]=\"size() === 'large'\"\n [class.error]=\"!!error()\"\n [class.success]=\"!!success()\"\n [class.disabled]=\"disabled()\"\n [class.readonly]=\"readonly()\"\n [class.loading]=\"loading()\"\n [class.focused]=\"focused()\"\n [class.has-start-icon]=\"!!iconStart()\"\n [class.has-end-icon]=\"!!iconEnd() || type() === 'password'\"\n [class.outlined]=\"variant() === 'outlined'\"\n [class.filled]=\"variant() === 'filled'\"\n>\n <!-- Label slot -->\n @if (showLabel()) {\n <label class=\"input-label\" [for]=\"inputId\" (click)=\"focusSelect()\" [class.required]=\"required()\">\n <ng-content select=\"[input-label]\"></ng-content>\n @if (!hasLabelContent()) {\n {{ label() }}\n }\n </label>\n }\n\n <div class=\"input-wrapper\">\n @if (iconStart()) {\n <i class=\"ph ph-{{ iconStart() }}\" aria-hidden=\"true\"></i>\n }\n\n <input\n [id]=\"inputId\"\n [type]=\"effectiveType()\"\n [attr.placeholder]=\"placeholder()\"\n [attr.aria-label]=\"computedAriaLabel()\"\n [attr.aria-invalid]=\"!!error()\"\n [attr.aria-required]=\"required()\"\n [attr.aria-describedby]=\"error() ? 'error-message' : success() ? 'success-message' : hint() ? 'hint-message' : null\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [required]=\"required()\"\n [value]=\"value()\"\n (input)=\"handleInput($event)\"\n (keydown)=\"handleKeydown($event)\"\n (focus)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n [attr.data-state]=\"state()\"\n />\n\n @if (iconEnd()) {\n <i class=\"ph ph-{{ iconEnd() }}\" aria-hidden=\"true\"></i>\n }\n\n @if (type() === 'password') {\n <button\n type=\"button\"\n class=\"password-toggle\"\n (click)=\"togglePasswordVisibility()\"\n [attr.aria-label]=\"passwordToggleLabel()\"\n [disabled]=\"disabled() || readonly()\"\n >\n <i \n [class]=\"'ph ph-' + (passwordVisible() ? 'eye-slash' : 'eye')\"\n aria-hidden=\"true\"\n ></i>\n </button>\n }\n\n @if (loading()) {\n <div class=\"input-loader\" aria-hidden=\"true\">\n <div class=\"loader\"></div>\n </div>\n }\n\n @if (showSuggestions()) {\n <div class=\"suggestions-list\" role=\"listbox\">\n @for (suggestion of filteredSuggestions(); track suggestion; let i = $index) {\n <div \n class=\"suggestion-item\"\n [class.focused]=\"i === focusedSuggestionIndex()\"\n role=\"option\"\n [attr.aria-selected]=\"i === focusedSuggestionIndex()\"\n (click)=\"handleSuggestionClick(suggestion)\"\n (mouseenter)=\"focusedSuggestionIndex.set(i)\"\n >\n {{ suggestion }}\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Error message slot -->\n @if (error()) {\n <div id=\"error-message\" class=\"input-error\" role=\"alert\">\n <ng-content select=\"[input-error]\">\n {{ error() }}\n </ng-content>\n </div>\n }\n\n <!-- Success message slot -->\n @if (success()) {\n <div id=\"success-message\" class=\"input-success\" role=\"status\">\n <ng-content select=\"[input-success]\">\n {{ success() }}\n </ng-content>\n </div>\n }\n\n <!-- Hint message slot -->\n @if (hint()) {\n <div id=\"hint-message\" class=\"input-hint\">\n <ng-content select=\"[input-hint]\">\n {{ hint() }}\n </ng-content>\n </div>\n }\n</div>", styles: [".input-container{position:relative;width:100%;max-width:300px}.input-container.full-width{max-width:none}.input-label{display:block;color:var(--text-color);font-size:var(--font-size-sm);font-weight:500;margin-bottom:var(--spacing-xs);width:100%;cursor:pointer}.input-label.required:after{content:\"*\";color:var(--danger-color);margin-left:var(--spacing-xxs)}.input-wrapper{position:relative;display:flex;align-items:center;width:100%}input{width:100%;height:var(--height-input-md);padding:0 var(--spacing-md);font-family:inherit;font-size:var(--font-size-base);color:var(--text-color);background:var(--surface-0);border:var(--border-width-1) solid var(--surface-border);border-radius:var(--border-radius);transition:all var(--animation-duration-default) var(--animation-easing-default)}input:hover:not(:disabled):not(:focus){border-color:var(--primary-color)}input::placeholder{color:var(--text-color-tertiary);opacity:1}input:focus{outline:none;border-color:var(--primary-color);box-shadow:0 0 0 var(--focus-ring-width) var(--focus-ring-color)}.input-container.outlined input{background:transparent;border:var(--border-width-2) solid var(--surface-border)}.input-container.outlined input:hover:not(:disabled):not(:focus){border-color:var(--primary-color)}.input-container.outlined input:focus{border-color:var(--primary-color);box-shadow:0 0 0 var(--focus-ring-width) var(--focus-ring-color)}.input-container.filled input{background:var(--surface-ground);border:var(--border-width-1) solid transparent}.input-container.filled input:hover:not(:disabled):not(:focus){background:var(--surface-hover)}.input-container.filled input:focus{background:var(--surface-0);border-color:var(--primary-color);box-shadow:0 0 0 var(--focus-ring-width) var(--focus-ring-color)}.input-container.error input{border-color:var(--danger-color)}.input-container.error input:focus{box-shadow:0 0 0 var(--focus-ring-width) var(--focus-ring-error)}.input-container.success input{border-color:var(--success-color)}.input-container.success input:focus{box-shadow:0 0 0 var(--focus-ring-width) var(--focus-ring-success)}.input-container.disabled input{background:var(--surface-ground);cursor:not-allowed;opacity:var(--opacity-disabled)}.input-container.readonly input{background:var(--surface-ground);cursor:default}.input-container.has-start-icon input{padding-left:calc(var(--spacing-md) * 2 + 1rem)}.input-container.has-end-icon input{padding-right:calc(var(--spacing-md) * 2 + 1rem)}.input-wrapper i{position:absolute;font-size:var(--icon-size-md);color:var(--text-color-secondary);pointer-events:none}.input-wrapper i:first-child{left:var(--spacing-md)}.input-wrapper i:last-child{right:var(--spacing-md)}.password-toggle{position:absolute;right:var(--spacing-md);background:transparent;border:none;color:var(--text-color-secondary);cursor:pointer;padding:var(--spacing-xs);border-radius:var(--border-radius);display:flex;align-items:center;justify-content:center;transition:all .2s ease}.password-toggle:hover{background:var(--surface-hover);color:var(--text-color)}.password-toggle:focus{outline:none;box-shadow:0 0 0 var(--focus-ring-width) var(--focus-ring-color)}.password-toggle i{font-size:var(--icon-size-md);position:static;pointer-events:auto}.input-container.small input{height:var(--height-input-sm);padding:0 var(--spacing-md);font-size:var(--font-size-sm)}.input-container.large input{height:var(--height-input-lg);padding:0 var(--spacing-lg);font-size:var(--font-size-lg)}.input-error,.input-success,.input-hint{font-size:var(--font-size-sm);margin-top:var(--spacing-xs)}.input-error{color:var(--danger-color);display:flex;align-items:center;gap:var(--spacing-xs)}.input-error i{font-size:var(--icon-size-sm)}.input-success{color:var(--success-color)}.input-hint{color:var(--text-color-secondary)}.input-loader{position:absolute;right:var(--spacing-md);display:flex;align-items:center;justify-content:center}.loader{width:var(--icon-size-sm);height:var(--icon-size-sm);border:var(--border-width-2) solid var(--surface-border);border-top-color:var(--primary-color);border-radius:50%;animation:spin .8s linear infinite}.suggestions-list{position:absolute;top:100%;left:0;right:0;background:var(--surface-0);border:var(--border-width-1) solid var(--surface-border);border-radius:var(--border-radius);box-shadow:var(--shadow-lg);z-index:var(--z-index-dropdown);max-height:var(--size-48);overflow-y:auto;margin-top:var(--spacing-xs)}.suggestion-item{padding:var(--spacing-sm) var(--spacing-md);cursor:pointer;transition:all var(--animation-duration-default) var(--animation-easing-default);color:var(--text-color)}.suggestion-item:hover,.suggestion-item.focused{background:var(--surface-hover);color:var(--primary-color)}@keyframes spin{to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1570
+ ], ngImport: i0, template: "<div class=\"input-container\">\n @if (showLabel()) {\n <label \n class=\"input-label\" \n [for]=\"inputId\" \n (click)=\"focusSelect()\" \n [class.required]=\"required()\"\n >\n <ng-content select=\"[input-label]\"></ng-content>\n @if (!hasLabelContent()) {\n {{ label() }}\n }\n </label>\n }\n\n <div class=\"input-wrapper\">\n @if (iconStart()) {\n <i class=\"ph ph-{{ iconStart() }}\" aria-hidden=\"true\"></i>\n }\n\n <input\n [id]=\"inputId\"\n [type]=\"effectiveType()\"\n [attr.placeholder]=\"placeholder()\"\n [attr.aria-label]=\"computedAriaLabel()\"\n [attr.aria-invalid]=\"!!error()\"\n [attr.aria-required]=\"required()\"\n [attr.aria-describedby]=\"error() ? 'error-message' : success() ? 'success-message' : hint() ? 'hint-message' : null\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [required]=\"required()\"\n [value]=\"value()\"\n (input)=\"handleInput($event)\"\n (keydown)=\"handleKeydown($event)\"\n (focus)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n [attr.data-state]=\"state()\"\n />\n\n @if (iconEnd()) {\n <i class=\"ph ph-{{ iconEnd() }}\" aria-hidden=\"true\"></i>\n }\n\n @if (type() === 'password') {\n <button\n type=\"button\"\n class=\"password-toggle\"\n (click)=\"togglePasswordVisibility()\"\n [attr.aria-label]=\"passwordToggleLabel()\"\n [disabled]=\"disabled() || readonly()\"\n >\n <i \n [class]=\"'ph ph-' + (passwordVisible() ? 'eye-slash' : 'eye')\"\n aria-hidden=\"true\"\n ></i>\n </button>\n }\n\n @if (loading()) {\n <div class=\"input-loader\" aria-hidden=\"true\">\n <div class=\"loader\"></div>\n </div>\n }\n\n @if (showSuggestions()) {\n <div class=\"suggestions-list\" role=\"listbox\">\n @for (suggestion of filteredSuggestions(); track suggestion; let i = $index) {\n <div \n class=\"suggestion-item\"\n [class.focused]=\"i === focusedSuggestionIndex()\"\n role=\"option\"\n [attr.aria-selected]=\"i === focusedSuggestionIndex()\"\n (click)=\"handleSuggestionClick(suggestion)\"\n (mouseenter)=\"focusedSuggestionIndex.set(i)\"\n >\n {{ suggestion }}\n </div>\n }\n </div>\n }\n </div>\n\n @if (error()) {\n <div id=\"error-message\" class=\"input-error\" role=\"alert\">\n <ng-content select=\"[input-error]\">\n {{ error() }}\n </ng-content>\n </div>\n }\n\n @if (success()) {\n <div id=\"success-message\" class=\"input-success\" role=\"status\">\n <ng-content select=\"[input-success]\">\n {{ success() }}\n </ng-content>\n </div>\n }\n\n @if (hint()) {\n <div id=\"hint-message\" class=\"input-hint\">\n <ng-content select=\"[input-hint]\">\n {{ hint() }}\n </ng-content>\n </div>\n }\n</div>", styles: [":host{display:block;width:100%;max-width:18.75rem;transition:all var(--animation-duration-default) var(--animation-easing-default)}:host.full-width{max-width:none}.input-container{position:relative;width:100%}.input-label{display:block;color:var(--text-color);font-size:.875rem;font-weight:500;margin-bottom:.25rem;width:100%;cursor:pointer}.input-label.required:after{content:\"*\";color:var(--danger-color);margin-left:.125rem}.input-wrapper{position:relative;display:flex;align-items:center;width:100%}input{width:100%;height:2.5rem;padding:0 1rem;font-family:inherit;font-size:1rem;color:var(--text-color);background:var(--surface-0);border:.0625rem solid var(--surface-border);border-radius:var(--border-radius);transition:all var(--animation-duration-default) var(--animation-easing-default)}input:hover:not(:disabled):not(:focus){border-color:var(--primary-color)}input::placeholder{color:var(--text-color-tertiary);opacity:1}input:focus{outline:none;border-color:var(--primary-color);box-shadow:0 0 0 .125rem var(--focus-ring-color)}:host.outlined input{background:transparent;border:.125rem solid var(--surface-border)}:host.filled input{background:var(--surface-ground);border:.0625rem solid transparent}:host.filled input:hover:not(:disabled):not(:focus){background:var(--surface-hover)}:host.filled input:focus{background:var(--surface-0)}:host.error input{border-color:var(--danger-color)}:host.error input:focus{box-shadow:0 0 0 .125rem var(--focus-ring-error)}:host.success input{border-color:var(--success-color)}:host.success input:focus{box-shadow:0 0 0 .125rem var(--focus-ring-success)}:host.disabled input{background:var(--surface-ground);cursor:not-allowed;opacity:var(--opacity-disabled)}:host.readonly input{background:var(--surface-ground);cursor:default}:host.small input{height:2rem;font-size:.875rem}:host.large input{height:3rem;font-size:1.125rem}:host.has-start-icon input{padding-left:2.75rem}:host.has-end-icon input{padding-right:2.75rem}.input-wrapper i{position:absolute;top:50%;transform:translateY(-50%);font-size:1.25rem;color:var(--text-color-secondary);pointer-events:none;z-index:2}.input-wrapper i:first-of-type{padding-left:1rem}.input-wrapper i:last-of-type{padding-right:1rem}.password-toggle{position:absolute;right:.5rem;top:50%;transform:translateY(-50%);width:2rem;height:2rem;background:transparent;border:none;color:var(--text-color-secondary);cursor:pointer;padding:0;border-radius:var(--border-radius);display:flex;align-items:center;justify-content:center;transition:all .2s ease;z-index:3}.password-toggle:hover:not(:disabled){background:var(--surface-hover);color:var(--text-color)}.password-toggle i{position:static;transform:none;pointer-events:auto}.input-loader{position:absolute;right:1rem;top:50%;transform:translateY(-50%);z-index:3}.loader{width:1rem;height:1rem;border:.125rem solid var(--surface-border);border-top-color:var(--primary-color);border-radius:50%;animation:spin .8s linear infinite}.suggestions-list{position:absolute;top:100%;left:0;right:0;background:var(--surface-0);border:.0625rem solid var(--surface-border);border-radius:var(--border-radius);box-shadow:var(--shadow-lg);z-index:var(--z-index-dropdown);max-height:12.5rem;overflow-y:auto;margin-top:.25rem}.suggestion-item{padding:.5rem 1rem;cursor:pointer;color:var(--text-color)}.suggestion-item:hover,.suggestion-item.focused{background:var(--surface-hover);color:var(--primary-color)}.input-error,.input-success,.input-hint{font-size:.875rem;margin-top:.25rem}.input-error{color:var(--danger-color)}.input-success{color:var(--success-color)}.input-hint{color:var(--text-color-secondary)}@keyframes spin{to{transform:translateY(-50%) rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1607
1571
  }
1608
1572
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: PshInputComponent, decorators: [{
1609
1573
  type: Component,
1610
1574
  args: [{ selector: 'psh-input', imports: [CommonModule], providers: [
1611
1575
  {
1612
1576
  provide: NG_VALUE_ACCESSOR,
1613
- useExisting: forwardRef(() => PshInputComponent),
1577
+ useExisting: PshInputComponent,
1614
1578
  multi: true
1615
1579
  }
1616
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div \n class=\"input-container\"\n [class.full-width]=\"fullWidth()\"\n [class.small]=\"size() === 'small'\"\n [class.large]=\"size() === 'large'\"\n [class.error]=\"!!error()\"\n [class.success]=\"!!success()\"\n [class.disabled]=\"disabled()\"\n [class.readonly]=\"readonly()\"\n [class.loading]=\"loading()\"\n [class.focused]=\"focused()\"\n [class.has-start-icon]=\"!!iconStart()\"\n [class.has-end-icon]=\"!!iconEnd() || type() === 'password'\"\n [class.outlined]=\"variant() === 'outlined'\"\n [class.filled]=\"variant() === 'filled'\"\n>\n <!-- Label slot -->\n @if (showLabel()) {\n <label class=\"input-label\" [for]=\"inputId\" (click)=\"focusSelect()\" [class.required]=\"required()\">\n <ng-content select=\"[input-label]\"></ng-content>\n @if (!hasLabelContent()) {\n {{ label() }}\n }\n </label>\n }\n\n <div class=\"input-wrapper\">\n @if (iconStart()) {\n <i class=\"ph ph-{{ iconStart() }}\" aria-hidden=\"true\"></i>\n }\n\n <input\n [id]=\"inputId\"\n [type]=\"effectiveType()\"\n [attr.placeholder]=\"placeholder()\"\n [attr.aria-label]=\"computedAriaLabel()\"\n [attr.aria-invalid]=\"!!error()\"\n [attr.aria-required]=\"required()\"\n [attr.aria-describedby]=\"error() ? 'error-message' : success() ? 'success-message' : hint() ? 'hint-message' : null\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [required]=\"required()\"\n [value]=\"value()\"\n (input)=\"handleInput($event)\"\n (keydown)=\"handleKeydown($event)\"\n (focus)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n [attr.data-state]=\"state()\"\n />\n\n @if (iconEnd()) {\n <i class=\"ph ph-{{ iconEnd() }}\" aria-hidden=\"true\"></i>\n }\n\n @if (type() === 'password') {\n <button\n type=\"button\"\n class=\"password-toggle\"\n (click)=\"togglePasswordVisibility()\"\n [attr.aria-label]=\"passwordToggleLabel()\"\n [disabled]=\"disabled() || readonly()\"\n >\n <i \n [class]=\"'ph ph-' + (passwordVisible() ? 'eye-slash' : 'eye')\"\n aria-hidden=\"true\"\n ></i>\n </button>\n }\n\n @if (loading()) {\n <div class=\"input-loader\" aria-hidden=\"true\">\n <div class=\"loader\"></div>\n </div>\n }\n\n @if (showSuggestions()) {\n <div class=\"suggestions-list\" role=\"listbox\">\n @for (suggestion of filteredSuggestions(); track suggestion; let i = $index) {\n <div \n class=\"suggestion-item\"\n [class.focused]=\"i === focusedSuggestionIndex()\"\n role=\"option\"\n [attr.aria-selected]=\"i === focusedSuggestionIndex()\"\n (click)=\"handleSuggestionClick(suggestion)\"\n (mouseenter)=\"focusedSuggestionIndex.set(i)\"\n >\n {{ suggestion }}\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Error message slot -->\n @if (error()) {\n <div id=\"error-message\" class=\"input-error\" role=\"alert\">\n <ng-content select=\"[input-error]\">\n {{ error() }}\n </ng-content>\n </div>\n }\n\n <!-- Success message slot -->\n @if (success()) {\n <div id=\"success-message\" class=\"input-success\" role=\"status\">\n <ng-content select=\"[input-success]\">\n {{ success() }}\n </ng-content>\n </div>\n }\n\n <!-- Hint message slot -->\n @if (hint()) {\n <div id=\"hint-message\" class=\"input-hint\">\n <ng-content select=\"[input-hint]\">\n {{ hint() }}\n </ng-content>\n </div>\n }\n</div>", styles: [".input-container{position:relative;width:100%;max-width:300px}.input-container.full-width{max-width:none}.input-label{display:block;color:var(--text-color);font-size:var(--font-size-sm);font-weight:500;margin-bottom:var(--spacing-xs);width:100%;cursor:pointer}.input-label.required:after{content:\"*\";color:var(--danger-color);margin-left:var(--spacing-xxs)}.input-wrapper{position:relative;display:flex;align-items:center;width:100%}input{width:100%;height:var(--height-input-md);padding:0 var(--spacing-md);font-family:inherit;font-size:var(--font-size-base);color:var(--text-color);background:var(--surface-0);border:var(--border-width-1) solid var(--surface-border);border-radius:var(--border-radius);transition:all var(--animation-duration-default) var(--animation-easing-default)}input:hover:not(:disabled):not(:focus){border-color:var(--primary-color)}input::placeholder{color:var(--text-color-tertiary);opacity:1}input:focus{outline:none;border-color:var(--primary-color);box-shadow:0 0 0 var(--focus-ring-width) var(--focus-ring-color)}.input-container.outlined input{background:transparent;border:var(--border-width-2) solid var(--surface-border)}.input-container.outlined input:hover:not(:disabled):not(:focus){border-color:var(--primary-color)}.input-container.outlined input:focus{border-color:var(--primary-color);box-shadow:0 0 0 var(--focus-ring-width) var(--focus-ring-color)}.input-container.filled input{background:var(--surface-ground);border:var(--border-width-1) solid transparent}.input-container.filled input:hover:not(:disabled):not(:focus){background:var(--surface-hover)}.input-container.filled input:focus{background:var(--surface-0);border-color:var(--primary-color);box-shadow:0 0 0 var(--focus-ring-width) var(--focus-ring-color)}.input-container.error input{border-color:var(--danger-color)}.input-container.error input:focus{box-shadow:0 0 0 var(--focus-ring-width) var(--focus-ring-error)}.input-container.success input{border-color:var(--success-color)}.input-container.success input:focus{box-shadow:0 0 0 var(--focus-ring-width) var(--focus-ring-success)}.input-container.disabled input{background:var(--surface-ground);cursor:not-allowed;opacity:var(--opacity-disabled)}.input-container.readonly input{background:var(--surface-ground);cursor:default}.input-container.has-start-icon input{padding-left:calc(var(--spacing-md) * 2 + 1rem)}.input-container.has-end-icon input{padding-right:calc(var(--spacing-md) * 2 + 1rem)}.input-wrapper i{position:absolute;font-size:var(--icon-size-md);color:var(--text-color-secondary);pointer-events:none}.input-wrapper i:first-child{left:var(--spacing-md)}.input-wrapper i:last-child{right:var(--spacing-md)}.password-toggle{position:absolute;right:var(--spacing-md);background:transparent;border:none;color:var(--text-color-secondary);cursor:pointer;padding:var(--spacing-xs);border-radius:var(--border-radius);display:flex;align-items:center;justify-content:center;transition:all .2s ease}.password-toggle:hover{background:var(--surface-hover);color:var(--text-color)}.password-toggle:focus{outline:none;box-shadow:0 0 0 var(--focus-ring-width) var(--focus-ring-color)}.password-toggle i{font-size:var(--icon-size-md);position:static;pointer-events:auto}.input-container.small input{height:var(--height-input-sm);padding:0 var(--spacing-md);font-size:var(--font-size-sm)}.input-container.large input{height:var(--height-input-lg);padding:0 var(--spacing-lg);font-size:var(--font-size-lg)}.input-error,.input-success,.input-hint{font-size:var(--font-size-sm);margin-top:var(--spacing-xs)}.input-error{color:var(--danger-color);display:flex;align-items:center;gap:var(--spacing-xs)}.input-error i{font-size:var(--icon-size-sm)}.input-success{color:var(--success-color)}.input-hint{color:var(--text-color-secondary)}.input-loader{position:absolute;right:var(--spacing-md);display:flex;align-items:center;justify-content:center}.loader{width:var(--icon-size-sm);height:var(--icon-size-sm);border:var(--border-width-2) solid var(--surface-border);border-top-color:var(--primary-color);border-radius:50%;animation:spin .8s linear infinite}.suggestions-list{position:absolute;top:100%;left:0;right:0;background:var(--surface-0);border:var(--border-width-1) solid var(--surface-border);border-radius:var(--border-radius);box-shadow:var(--shadow-lg);z-index:var(--z-index-dropdown);max-height:var(--size-48);overflow-y:auto;margin-top:var(--spacing-xs)}.suggestion-item{padding:var(--spacing-sm) var(--spacing-md);cursor:pointer;transition:all var(--animation-duration-default) var(--animation-easing-default);color:var(--text-color)}.suggestion-item:hover,.suggestion-item.focused{background:var(--surface-hover);color:var(--primary-color)}@keyframes spin{to{transform:rotate(360deg)}}\n"] }]
1580
+ ], changeDetection: ChangeDetectionStrategy.OnPush, host: {
1581
+ '[class.full-width]': 'fullWidth()',
1582
+ '[class.small]': 'size() === "small"',
1583
+ '[class.large]': 'size() === "large"',
1584
+ '[class.error]': '!!error()',
1585
+ '[class.success]': '!!success()',
1586
+ '[class.disabled]': 'disabled()',
1587
+ '[class.readonly]': 'readonly()',
1588
+ '[class.loading]': 'loading()',
1589
+ '[class.focused]': 'focused()',
1590
+ '[class.has-start-icon]': '!!iconStart()',
1591
+ '[class.has-end-icon]': '!!iconEnd() || type() === "password"',
1592
+ '[class.outlined]': 'variant() === "outlined"',
1593
+ '[class.filled]': 'variant() === "filled"',
1594
+ }, template: "<div class=\"input-container\">\n @if (showLabel()) {\n <label \n class=\"input-label\" \n [for]=\"inputId\" \n (click)=\"focusSelect()\" \n [class.required]=\"required()\"\n >\n <ng-content select=\"[input-label]\"></ng-content>\n @if (!hasLabelContent()) {\n {{ label() }}\n }\n </label>\n }\n\n <div class=\"input-wrapper\">\n @if (iconStart()) {\n <i class=\"ph ph-{{ iconStart() }}\" aria-hidden=\"true\"></i>\n }\n\n <input\n [id]=\"inputId\"\n [type]=\"effectiveType()\"\n [attr.placeholder]=\"placeholder()\"\n [attr.aria-label]=\"computedAriaLabel()\"\n [attr.aria-invalid]=\"!!error()\"\n [attr.aria-required]=\"required()\"\n [attr.aria-describedby]=\"error() ? 'error-message' : success() ? 'success-message' : hint() ? 'hint-message' : null\"\n [disabled]=\"disabled()\"\n [readonly]=\"readonly()\"\n [required]=\"required()\"\n [value]=\"value()\"\n (input)=\"handleInput($event)\"\n (keydown)=\"handleKeydown($event)\"\n (focus)=\"handleFocus()\"\n (blur)=\"handleBlur()\"\n [attr.data-state]=\"state()\"\n />\n\n @if (iconEnd()) {\n <i class=\"ph ph-{{ iconEnd() }}\" aria-hidden=\"true\"></i>\n }\n\n @if (type() === 'password') {\n <button\n type=\"button\"\n class=\"password-toggle\"\n (click)=\"togglePasswordVisibility()\"\n [attr.aria-label]=\"passwordToggleLabel()\"\n [disabled]=\"disabled() || readonly()\"\n >\n <i \n [class]=\"'ph ph-' + (passwordVisible() ? 'eye-slash' : 'eye')\"\n aria-hidden=\"true\"\n ></i>\n </button>\n }\n\n @if (loading()) {\n <div class=\"input-loader\" aria-hidden=\"true\">\n <div class=\"loader\"></div>\n </div>\n }\n\n @if (showSuggestions()) {\n <div class=\"suggestions-list\" role=\"listbox\">\n @for (suggestion of filteredSuggestions(); track suggestion; let i = $index) {\n <div \n class=\"suggestion-item\"\n [class.focused]=\"i === focusedSuggestionIndex()\"\n role=\"option\"\n [attr.aria-selected]=\"i === focusedSuggestionIndex()\"\n (click)=\"handleSuggestionClick(suggestion)\"\n (mouseenter)=\"focusedSuggestionIndex.set(i)\"\n >\n {{ suggestion }}\n </div>\n }\n </div>\n }\n </div>\n\n @if (error()) {\n <div id=\"error-message\" class=\"input-error\" role=\"alert\">\n <ng-content select=\"[input-error]\">\n {{ error() }}\n </ng-content>\n </div>\n }\n\n @if (success()) {\n <div id=\"success-message\" class=\"input-success\" role=\"status\">\n <ng-content select=\"[input-success]\">\n {{ success() }}\n </ng-content>\n </div>\n }\n\n @if (hint()) {\n <div id=\"hint-message\" class=\"input-hint\">\n <ng-content select=\"[input-hint]\">\n {{ hint() }}\n </ng-content>\n </div>\n }\n</div>", styles: [":host{display:block;width:100%;max-width:18.75rem;transition:all var(--animation-duration-default) var(--animation-easing-default)}:host.full-width{max-width:none}.input-container{position:relative;width:100%}.input-label{display:block;color:var(--text-color);font-size:.875rem;font-weight:500;margin-bottom:.25rem;width:100%;cursor:pointer}.input-label.required:after{content:\"*\";color:var(--danger-color);margin-left:.125rem}.input-wrapper{position:relative;display:flex;align-items:center;width:100%}input{width:100%;height:2.5rem;padding:0 1rem;font-family:inherit;font-size:1rem;color:var(--text-color);background:var(--surface-0);border:.0625rem solid var(--surface-border);border-radius:var(--border-radius);transition:all var(--animation-duration-default) var(--animation-easing-default)}input:hover:not(:disabled):not(:focus){border-color:var(--primary-color)}input::placeholder{color:var(--text-color-tertiary);opacity:1}input:focus{outline:none;border-color:var(--primary-color);box-shadow:0 0 0 .125rem var(--focus-ring-color)}:host.outlined input{background:transparent;border:.125rem solid var(--surface-border)}:host.filled input{background:var(--surface-ground);border:.0625rem solid transparent}:host.filled input:hover:not(:disabled):not(:focus){background:var(--surface-hover)}:host.filled input:focus{background:var(--surface-0)}:host.error input{border-color:var(--danger-color)}:host.error input:focus{box-shadow:0 0 0 .125rem var(--focus-ring-error)}:host.success input{border-color:var(--success-color)}:host.success input:focus{box-shadow:0 0 0 .125rem var(--focus-ring-success)}:host.disabled input{background:var(--surface-ground);cursor:not-allowed;opacity:var(--opacity-disabled)}:host.readonly input{background:var(--surface-ground);cursor:default}:host.small input{height:2rem;font-size:.875rem}:host.large input{height:3rem;font-size:1.125rem}:host.has-start-icon input{padding-left:2.75rem}:host.has-end-icon input{padding-right:2.75rem}.input-wrapper i{position:absolute;top:50%;transform:translateY(-50%);font-size:1.25rem;color:var(--text-color-secondary);pointer-events:none;z-index:2}.input-wrapper i:first-of-type{padding-left:1rem}.input-wrapper i:last-of-type{padding-right:1rem}.password-toggle{position:absolute;right:.5rem;top:50%;transform:translateY(-50%);width:2rem;height:2rem;background:transparent;border:none;color:var(--text-color-secondary);cursor:pointer;padding:0;border-radius:var(--border-radius);display:flex;align-items:center;justify-content:center;transition:all .2s ease;z-index:3}.password-toggle:hover:not(:disabled){background:var(--surface-hover);color:var(--text-color)}.password-toggle i{position:static;transform:none;pointer-events:auto}.input-loader{position:absolute;right:1rem;top:50%;transform:translateY(-50%);z-index:3}.loader{width:1rem;height:1rem;border:.125rem solid var(--surface-border);border-top-color:var(--primary-color);border-radius:50%;animation:spin .8s linear infinite}.suggestions-list{position:absolute;top:100%;left:0;right:0;background:var(--surface-0);border:.0625rem solid var(--surface-border);border-radius:var(--border-radius);box-shadow:var(--shadow-lg);z-index:var(--z-index-dropdown);max-height:12.5rem;overflow-y:auto;margin-top:.25rem}.suggestion-item{padding:.5rem 1rem;cursor:pointer;color:var(--text-color)}.suggestion-item:hover,.suggestion-item.focused{background:var(--surface-hover);color:var(--primary-color)}.input-error,.input-success,.input-hint{font-size:.875rem;margin-top:.25rem}.input-error{color:var(--danger-color)}.input-success{color:var(--success-color)}.input-hint{color:var(--text-color-secondary)}@keyframes spin{to{transform:translateY(-50%) rotate(360deg)}}\n"] }]
1617
1595
  }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }, { type: i0.Output, args: ["disabledChange"] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }, { type: i0.Output, args: ["readonlyChange"] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }, { type: i0.Output, args: ["loadingChange"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], showLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLabel", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], iconStart: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconStart", required: false }] }], iconEnd: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconEnd", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], success: [{ type: i0.Input, args: [{ isSignal: true, alias: "success", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], suggestions: [{ type: i0.Input, args: [{ isSignal: true, alias: "suggestions", required: false }] }], autocompleteConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "autocompleteConfig", required: false }] }], inputFocus: [{ type: i0.Output, args: ["inputFocus"] }], inputBlur: [{ type: i0.Output, args: ["inputBlur"] }], suggestionSelect: [{ type: i0.Output, args: ["suggestionSelect"] }] } });
1618
1596
 
1619
1597
  const TOOLTIP_CONFIG = new InjectionToken('TOOLTIP_CONFIG', {
@@ -2865,10 +2843,11 @@ class PshSelectComponent {
2865
2843
  this.elementRef = inject(ElementRef);
2866
2844
  this.cdr = inject(ChangeDetectorRef);
2867
2845
  this.destroyRef = inject(DestroyRef);
2868
- this.selectId = `select-${Math.random().toString(36).substring(2, 11)}`;
2846
+ this.selectId = `psh-sel-${Math.random().toString(36).substring(2, 11)}`;
2869
2847
  this.value = model(null, ...(ngDevMode ? [{ debugName: "value" }] : []));
2870
2848
  this.disabled = model(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
2871
2849
  this.touched = model(false, ...(ngDevMode ? [{ debugName: "touched" }] : []));
2850
+ // Rétablissement de l'API complète pour la démo
2872
2851
  this.size = input('medium', ...(ngDevMode ? [{ debugName: "size" }] : []));
2873
2852
  this.searchable = input(false, ...(ngDevMode ? [{ debugName: "searchable" }] : []));
2874
2853
  this.multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple" }] : []));
@@ -2878,14 +2857,9 @@ class PshSelectComponent {
2878
2857
  this.required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : []));
2879
2858
  this.options = input([], ...(ngDevMode ? [{ debugName: "options" }] : []));
2880
2859
  this.label = input('', ...(ngDevMode ? [{ debugName: "label" }] : []));
2881
- this.ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
2882
2860
  this.placeholder = input('Sélectionner une option', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
2883
2861
  this.multiplePlaceholder = input('Sélectionner des options', ...(ngDevMode ? [{ debugName: "multiplePlaceholder" }] : []));
2884
- this.error = input('', ...(ngDevMode ? [{ debugName: "error" }] : []));
2885
- this.success = input('', ...(ngDevMode ? [{ debugName: "success" }] : []));
2886
- this.hint = input('', ...(ngDevMode ? [{ debugName: "hint" }] : []));
2887
- this.maxSelections = input(undefined, ...(ngDevMode ? [{ debugName: "maxSelections" }] : []));
2888
- this.minSelections = input(undefined, ...(ngDevMode ? [{ debugName: "minSelections" }] : []));
2862
+ this.error = input(undefined, ...(ngDevMode ? [{ debugName: "error" }] : []));
2889
2863
  this.compareWith = input((a, b) => a === b, ...(ngDevMode ? [{ debugName: "compareWith" }] : []));
2890
2864
  this.searchConfig = input({
2891
2865
  debounceTime: 300,
@@ -2894,27 +2868,26 @@ class PshSelectComponent {
2894
2868
  }, ...(ngDevMode ? [{ debugName: "searchConfig" }] : []));
2895
2869
  this.isOpenSignal = signal(false, ...(ngDevMode ? [{ debugName: "isOpenSignal" }] : []));
2896
2870
  this.searchTermSignal = signal('', ...(ngDevMode ? [{ debugName: "searchTermSignal" }] : []));
2897
- this.selectedLabelSignal = signal('', ...(ngDevMode ? [{ debugName: "selectedLabelSignal" }] : []));
2898
- this.focusedOptionIndex = signal(-1, ...(ngDevMode ? [{ debugName: "focusedOptionIndex" }] : []));
2899
- this.hasLabelContentSignal = signal(false, ...(ngDevMode ? [{ debugName: "hasLabelContentSignal" }] : []));
2900
2871
  this.initializedSignal = signal(false, ...(ngDevMode ? [{ debugName: "initializedSignal" }] : []));
2901
- this.activeDescendantId = signal(null, ...(ngDevMode ? [{ debugName: "activeDescendantId" }] : []));
2902
2872
  this.opened = output();
2903
2873
  this.closed = output();
2874
+ this.searched = output(); // Émet une string, pas un Event
2904
2875
  this.scrollEnd = output();
2905
- this.searched = output();
2906
2876
  this.isOpen = computed(() => this.isOpenSignal(), ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
2907
2877
  this.searchTerm = computed(() => this.searchTermSignal(), ...(ngDevMode ? [{ debugName: "searchTerm" }] : []));
2908
- this.hasLabelContent = computed(() => this.hasLabelContentSignal(), ...(ngDevMode ? [{ debugName: "hasLabelContent" }] : []));
2909
- this.activeDescendant = computed(() => this.activeDescendantId(), ...(ngDevMode ? [{ debugName: "activeDescendant" }] : []));
2910
- this.computedAriaLabel = computed(() => {
2911
- return this.ariaLabel() || this.label() || this.placeholder();
2912
- }, ...(ngDevMode ? [{ debugName: "computedAriaLabel" }] : []));
2878
+ this.state = computed(() => this.disabled() ? 'disabled' : this.error() ? 'error' : 'default', ...(ngDevMode ? [{ debugName: "state" }] : []));
2913
2879
  this.selectedLabel = computed(() => {
2914
- if (!this.initializedSignal() || !this.hasValue()) {
2880
+ const currentValue = this.value();
2881
+ const currentOptions = this.flattenOptions(this.options());
2882
+ if (!this.initializedSignal() || (currentValue === null || currentValue === undefined)) {
2915
2883
  return this.multiple() ? this.multiplePlaceholder() : this.placeholder();
2916
2884
  }
2917
- return this.selectedLabelSignal() || (this.multiple() ? this.multiplePlaceholder() : this.placeholder());
2885
+ if (this.multiple() && Array.isArray(currentValue)) {
2886
+ const selected = currentOptions.filter(opt => currentValue.some(v => this.compareWith()(v, opt.value)));
2887
+ return selected.length > 0 ? selected.map(o => o.label).join(', ') : this.multiplePlaceholder();
2888
+ }
2889
+ const selected = currentOptions.find(opt => this.compareWith()(opt.value, currentValue));
2890
+ return selected ? selected.label : this.placeholder();
2918
2891
  }, ...(ngDevMode ? [{ debugName: "selectedLabel" }] : []));
2919
2892
  this.filteredOptions = computed(() => {
2920
2893
  const term = this.searchTermSignal().toLowerCase();
@@ -2923,349 +2896,115 @@ class PshSelectComponent {
2923
2896
  return opts;
2924
2897
  return opts.map(opt => {
2925
2898
  if (this.isOptionGroup(opt)) {
2926
- const filteredOptions = opt.options.filter(o => o.label.toLowerCase().includes(term) ||
2927
- o.description?.toLowerCase().includes(term));
2928
- return filteredOptions.length > 0 ? { ...opt, options: filteredOptions } : null;
2899
+ const filtered = opt.options.filter(o => o.label.toLowerCase().includes(term));
2900
+ return filtered.length > 0 ? { ...opt, options: filtered } : null;
2929
2901
  }
2930
- return opt.label.toLowerCase().includes(term) ||
2931
- opt.description?.toLowerCase().includes(term)
2932
- ? opt
2933
- : null;
2902
+ return opt.label.toLowerCase().includes(term) ? opt : null;
2934
2903
  }).filter((opt) => opt !== null);
2935
2904
  }, ...(ngDevMode ? [{ debugName: "filteredOptions" }] : []));
2936
2905
  this.onChange = (_) => { };
2937
2906
  this.onTouched = () => { };
2938
2907
  const clickHandler = (event) => {
2939
- if (this.isOpen()) {
2940
- const target = event.target;
2941
- if (!this.elementRef.nativeElement.contains(target)) {
2942
- this.close();
2943
- }
2908
+ if (this.isOpen() && !this.elementRef.nativeElement.contains(event.target)) {
2909
+ this.close();
2944
2910
  }
2945
2911
  };
2946
2912
  document.addEventListener('click', clickHandler);
2947
- this.destroyRef.onDestroy(() => {
2948
- document.removeEventListener('click', clickHandler);
2949
- });
2913
+ this.destroyRef.onDestroy(() => document.removeEventListener('click', clickHandler));
2950
2914
  }
2951
2915
  ngAfterContentInit() {
2952
- Promise.resolve().then(() => {
2953
- const hasLabel = !!this.elementRef.nativeElement.querySelector('[select-label]');
2954
- this.hasLabelContentSignal.set(hasLabel);
2955
- this.initializedSignal.set(true);
2956
- this.cdr.markForCheck();
2957
- });
2958
- }
2959
- handleKeyDown(event) {
2960
- if (this.disabled() || this.loading())
2961
- return;
2962
- switch (event.key) {
2963
- case 'Enter':
2964
- case ' ':
2965
- event.preventDefault();
2966
- if (!this.isOpen()) {
2967
- this.toggle();
2968
- }
2969
- else if (this.focusedOptionIndex() >= 0) {
2970
- const options = this.flattenOptions(this.filteredOptions());
2971
- const option = options[this.focusedOptionIndex()];
2972
- if (option)
2973
- this.select(option);
2974
- }
2975
- break;
2976
- case 'ArrowDown':
2977
- event.preventDefault();
2978
- if (!this.isOpen()) {
2979
- this.toggle();
2980
- }
2981
- else {
2982
- this.focusNextOption();
2983
- }
2984
- break;
2985
- case 'ArrowUp':
2986
- event.preventDefault();
2987
- if (this.isOpen()) {
2988
- this.focusPreviousOption();
2989
- }
2990
- break;
2991
- case 'Escape':
2992
- if (this.isOpen()) {
2993
- event.preventDefault();
2994
- this.close();
2995
- }
2996
- break;
2997
- case 'Tab':
2998
- if (this.isOpen()) {
2999
- this.close();
3000
- }
3001
- break;
3002
- case 'Home':
3003
- if (this.isOpen()) {
3004
- event.preventDefault();
3005
- this.focusFirstOption();
3006
- }
3007
- break;
3008
- case 'End':
3009
- if (this.isOpen()) {
3010
- event.preventDefault();
3011
- this.focusLastOption();
3012
- }
3013
- break;
3014
- }
3015
- }
3016
- handleOptionKeyDown(event, option) {
3017
- switch (event.key) {
3018
- case 'Enter':
3019
- case ' ':
3020
- event.preventDefault();
3021
- this.select(option);
3022
- break;
3023
- case 'Escape':
3024
- event.preventDefault();
3025
- this.close();
3026
- break;
3027
- }
3028
- }
3029
- focusNextOption() {
3030
- const options = this.flattenOptions(this.filteredOptions());
3031
- if (options.length === 0)
3032
- return;
3033
- const currentIndex = this.focusedOptionIndex();
3034
- const nextIndex = currentIndex < options.length - 1 ? currentIndex + 1 : 0;
3035
- this.focusedOptionIndex.set(nextIndex);
3036
- const nextOption = options[nextIndex];
3037
- if (nextOption) {
3038
- this.updateActiveDescendant(nextOption);
3039
- }
3040
- this.scrollOptionIntoView();
3041
- }
3042
- focusPreviousOption() {
3043
- const options = this.flattenOptions(this.filteredOptions());
3044
- if (options.length === 0)
3045
- return;
3046
- const currentIndex = this.focusedOptionIndex();
3047
- const previousIndex = currentIndex > 0 ? currentIndex - 1 : options.length - 1;
3048
- this.focusedOptionIndex.set(previousIndex);
3049
- const prevOption = options[previousIndex];
3050
- if (prevOption) {
3051
- this.updateActiveDescendant(prevOption);
3052
- }
3053
- this.scrollOptionIntoView();
3054
- }
3055
- focusFirstOption() {
3056
- const options = this.flattenOptions(this.filteredOptions());
3057
- if (options.length === 0)
3058
- return;
3059
- this.focusedOptionIndex.set(0);
3060
- const firstOption = options[0];
3061
- if (firstOption) {
3062
- this.updateActiveDescendant(firstOption);
3063
- }
3064
- this.scrollOptionIntoView();
3065
- }
3066
- focusLastOption() {
3067
- const options = this.flattenOptions(this.filteredOptions());
3068
- if (options.length === 0)
3069
- return;
3070
- const lastIndex = options.length - 1;
3071
- this.focusedOptionIndex.set(lastIndex);
3072
- const lastOption = options[lastIndex];
3073
- if (lastOption) {
3074
- this.updateActiveDescendant(lastOption);
3075
- }
3076
- this.scrollOptionIntoView();
3077
- }
3078
- scrollOptionIntoView() {
3079
- requestAnimationFrame(() => {
3080
- const activeId = this.activeDescendantId();
3081
- if (activeId) {
3082
- const option = this.elementRef.nativeElement.querySelector(`#${activeId}`);
3083
- if (option) {
3084
- option.scrollIntoView({ block: 'nearest' });
3085
- }
3086
- }
3087
- });
3088
- }
3089
- updateActiveDescendant(option) {
3090
- const optionId = `${this.selectId}-option-${String(option.value)}`;
3091
- this.activeDescendantId.set(optionId);
3092
- this.cdr.markForCheck();
3093
- }
3094
- isFocused(option) {
3095
- const activeId = this.activeDescendantId();
3096
- if (!activeId)
3097
- return false;
3098
- const optionId = `${this.selectId}-option-${String(option.value)}`;
3099
- return activeId === optionId;
2916
+ this.initializedSignal.set(true);
3100
2917
  }
3101
2918
  writeValue(value) {
3102
- this.initializedSignal.set(true);
3103
2919
  this.value.set(value);
3104
- this.updateSelectedLabel();
2920
+ this.initializedSignal.set(true);
3105
2921
  this.cdr.markForCheck();
3106
2922
  }
3107
- registerOnChange(fn) {
3108
- this.onChange = fn;
3109
- }
3110
- registerOnTouched(fn) {
3111
- this.onTouched = fn;
3112
- }
3113
- setDisabledState(isDisabled) {
3114
- this.disabled.set(isDisabled);
3115
- }
3116
- isOptionGroup(option) {
3117
- return 'options' in option;
3118
- }
3119
- getOptionKey(option) {
3120
- return this.isOptionGroup(option) ? `group-${option.label}` : `option-${String(option.value)}`;
3121
- }
3122
- hasValue() {
3123
- const currentValue = this.value();
3124
- if (this.multiple()) {
3125
- return Array.isArray(currentValue) && currentValue.length > 0;
3126
- }
3127
- return currentValue !== null && currentValue !== undefined;
3128
- }
3129
- focus() {
3130
- const trigger = this.elementRef.nativeElement.querySelector('.select-trigger');
3131
- if (trigger) {
3132
- trigger.focus();
3133
- }
2923
+ registerOnChange(fn) { this.onChange = fn; }
2924
+ registerOnTouched(fn) { this.onTouched = fn; }
2925
+ setDisabledState(isDisabled) { this.disabled.set(isDisabled); }
2926
+ toggle() {
2927
+ if (this.disabled() || this.loading())
2928
+ return;
2929
+ this.isOpenSignal.update(v => !v);
2930
+ this.isOpen() ? this.opened.emit() : this.closed.emit();
3134
2931
  }
3135
- focusSelect() {
3136
- this.focus();
2932
+ close() {
2933
+ this.isOpenSignal.set(false);
2934
+ this.searchTermSignal.set('');
3137
2935
  }
3138
2936
  select(option) {
3139
- if (!this.disabled() && !option.disabled) {
3140
- this.activeDescendantId.set(null);
3141
- if (this.multiple()) {
3142
- const currentValue = this.value();
3143
- const values = Array.isArray(currentValue) ? [...currentValue] : [];
3144
- const index = values.findIndex(v => this.compareWith()(v, option.value));
3145
- let changed = false;
3146
- if (index === -1) {
3147
- const maxSelections = this.maxSelections();
3148
- if (!maxSelections || values.length < maxSelections) {
3149
- values.push(option.value);
3150
- changed = true;
3151
- }
3152
- }
3153
- else {
3154
- const minSelections = this.minSelections();
3155
- if (!minSelections || values.length > minSelections) {
3156
- values.splice(index, 1);
3157
- changed = true;
3158
- }
3159
- }
3160
- if (changed) {
3161
- this.value.set(values);
3162
- this.onChange(values);
3163
- this.updateSelectedLabel();
3164
- }
3165
- }
3166
- else {
3167
- this.value.set(option.value);
3168
- this.onChange(option.value);
3169
- this.updateSelectedLabel();
3170
- this.close();
3171
- }
3172
- this.onTouched();
3173
- this.touched.set(true);
3174
- }
3175
- }
3176
- isSelected(option) {
3177
- const currentValue = this.value();
3178
- if (this.multiple() && Array.isArray(currentValue)) {
3179
- return currentValue.some(v => this.compareWith()(v, option.value));
3180
- }
3181
- return currentValue !== null && this.compareWith()(currentValue, option.value);
3182
- }
3183
- toggle() {
3184
- if (!this.disabled() && !this.loading()) {
3185
- const newValue = !this.isOpenSignal();
3186
- this.isOpenSignal.set(newValue);
3187
- if (newValue) {
3188
- this.opened.emit();
2937
+ if (this.disabled() || option.disabled)
2938
+ return;
2939
+ if (this.multiple()) {
2940
+ const current = Array.isArray(this.value()) ? [...this.value()] : [];
2941
+ const index = current.findIndex(v => this.compareWith()(v, option.value));
2942
+ if (index === -1) {
2943
+ current.push(option.value);
3189
2944
  }
3190
2945
  else {
3191
- this.activeDescendantId.set(null);
3192
- this.closed.emit();
2946
+ current.splice(index, 1);
3193
2947
  }
2948
+ this.value.set(current);
2949
+ this.onChange(current);
3194
2950
  }
3195
- }
3196
- close() {
3197
- if (this.isOpenSignal()) {
3198
- this.isOpenSignal.set(false);
3199
- this.focusedOptionIndex.set(-1);
3200
- this.activeDescendantId.set(null);
3201
- this.searchTermSignal.set('');
3202
- this.closed.emit();
2951
+ else {
2952
+ this.value.set(option.value);
2953
+ this.onChange(option.value);
2954
+ this.close();
3203
2955
  }
2956
+ this.onTouched();
2957
+ this.touched.set(true);
3204
2958
  }
3205
2959
  clear(event) {
3206
2960
  event.stopPropagation();
3207
- if (!this.disabled() && !this.loading()) {
3208
- const newValue = this.multiple() ? [] : null;
3209
- this.value.set(newValue);
3210
- this.onChange(newValue);
3211
- this.updateSelectedLabel();
3212
- this.onTouched();
3213
- this.touched.set(true);
3214
- }
2961
+ this.value.set(this.multiple() ? [] : null);
2962
+ this.onChange(this.value());
3215
2963
  }
3216
2964
  onSearch(event) {
3217
2965
  const term = event.target.value;
3218
2966
  this.searchTermSignal.set(term);
3219
- if (term.length >= (this.searchConfig().minLength ?? 1)) {
3220
- this.searched.emit(term);
3221
- }
2967
+ this.searched.emit(term);
3222
2968
  }
3223
2969
  onScroll(event) {
3224
- const element = event.target;
3225
- if (element.scrollHeight - element.scrollTop === element.clientHeight) {
2970
+ const el = event.target;
2971
+ if (el.scrollHeight - el.scrollTop === el.clientHeight) {
3226
2972
  this.scrollEnd.emit();
3227
2973
  }
3228
2974
  }
3229
- updateSelectedLabel() {
3230
- const currentValue = this.value();
3231
- const currentOptions = this.flattenOptions(this.options());
3232
- if (this.multiple() && Array.isArray(currentValue)) {
3233
- const selected = currentOptions.filter(opt => currentValue.some(v => this.compareWith()(v, opt.value)));
3234
- if (selected.length > 0) {
3235
- const labels = selected.map(opt => opt.label);
3236
- this.selectedLabelSignal.set(labels.join(', '));
3237
- }
3238
- else {
3239
- this.selectedLabelSignal.set('');
3240
- }
3241
- }
3242
- else {
3243
- const selected = currentOptions.find(opt => currentValue !== null && this.compareWith()(opt.value, currentValue));
3244
- if (selected) {
3245
- this.selectedLabelSignal.set(selected.label);
3246
- }
3247
- else {
3248
- this.selectedLabelSignal.set('');
3249
- }
2975
+ isOptionGroup(item) {
2976
+ return 'options' in item;
2977
+ }
2978
+ getOptionKey(item) {
2979
+ return this.isOptionGroup(item) ? `g-${item.label}` : `o-${item.label}`;
2980
+ }
2981
+ isSelected(option) {
2982
+ const val = this.value();
2983
+ if (this.multiple() && Array.isArray(val)) {
2984
+ return val.some(v => this.compareWith()(v, option.value));
3250
2985
  }
3251
- this.cdr.markForCheck();
2986
+ return val !== null && this.compareWith()(val, option.value);
2987
+ }
2988
+ hasValue() {
2989
+ const val = this.value();
2990
+ if (this.multiple())
2991
+ return Array.isArray(val) && val.length > 0;
2992
+ return val !== null && val !== undefined;
3252
2993
  }
3253
2994
  flattenOptions(options) {
3254
- return options.reduce((acc, opt) => {
3255
- if (this.isOptionGroup(opt)) {
3256
- return [...acc, ...opt.options];
3257
- }
3258
- return [...acc, opt];
3259
- }, []);
2995
+ return options.reduce((acc, opt) => this.isOptionGroup(opt) ? [...acc, ...opt.options] : [...acc, opt], []);
2996
+ }
2997
+ focusSelect() {
2998
+ this.elementRef.nativeElement.querySelector('.select-trigger')?.focus();
3260
2999
  }
3261
3000
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: PshSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3262
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: PshSelectComponent, isStandalone: true, selector: "psh-select", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, multiplePlaceholder: { classPropertyName: "multiplePlaceholder", publicName: "multiplePlaceholder", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, success: { classPropertyName: "success", publicName: "success", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, maxSelections: { classPropertyName: "maxSelections", publicName: "maxSelections", isSignal: true, isRequired: false, transformFunction: null }, minSelections: { classPropertyName: "minSelections", publicName: "minSelections", isSignal: true, isRequired: false, transformFunction: null }, compareWith: { classPropertyName: "compareWith", publicName: "compareWith", isSignal: true, isRequired: false, transformFunction: null }, searchConfig: { classPropertyName: "searchConfig", publicName: "searchConfig", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", disabled: "disabledChange", touched: "touchedChange", opened: "opened", closed: "closed", scrollEnd: "scrollEnd", searched: "searched" }, host: { properties: { "class.full-width": "fullWidth()", "class.small": "size() === \"small\"", "class.large": "size() === \"large\"", "class.error": "!!error()", "class.success": "!!success()", "class.disabled": "disabled()", "class.loading": "loading()" } }, providers: [
3001
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: PshSelectComponent, isStandalone: true, selector: "psh-select", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, multiplePlaceholder: { classPropertyName: "multiplePlaceholder", publicName: "multiplePlaceholder", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, compareWith: { classPropertyName: "compareWith", publicName: "compareWith", isSignal: true, isRequired: false, transformFunction: null }, searchConfig: { classPropertyName: "searchConfig", publicName: "searchConfig", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", disabled: "disabledChange", touched: "touchedChange", opened: "opened", closed: "closed", searched: "searched", scrollEnd: "scrollEnd" }, host: { properties: { "class.select-full-width": "fullWidth()", "class.select-small": "size() === \"small\"", "class.select-large": "size() === \"large\"", "class.select-error": "!!error()", "class.select-disabled": "disabled()", "class.select-loading": "loading()", "attr.aria-expanded": "isOpen().toString()", "attr.data-state": "state()" } }, providers: [
3263
3002
  {
3264
3003
  provide: NG_VALUE_ACCESSOR,
3265
3004
  useExisting: PshSelectComponent,
3266
3005
  multi: true
3267
3006
  }
3268
- ], ngImport: i0, template: "<div class=\"select-container\">\n <!-- Label slot -->\n @if (label() || hasLabelContent()) {\n <label class=\"select-label\" [for]=\"selectId\" (click)=\"focusSelect()\" [class.required]=\"!!required()\">\n <ng-content select=\"[select-label]\" />\n @if (!hasLabelContent()) {\n {{ label() }}\n }\n </label>\n }\n\n <div class=\"select-trigger-wrapper\">\n <div\n class=\"select-trigger\"\n [id]=\"selectId\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n [attr.aria-controls]=\"selectId + '-listbox'\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-disabled]=\"disabled()\"\n [attr.aria-busy]=\"loading() ? 'true' : null\"\n [attr.aria-required]=\"required() ? 'true' : 'false'\"\n [attr.aria-invalid]=\"!!error()\"\n [attr.aria-label]=\"computedAriaLabel()\"\n [attr.aria-describedby]=\"error() ? 'error-message' : success() ? 'success-message' : hint() ? 'hint-message' : null\"\n [attr.aria-activedescendant]=\"activeDescendant()\"\n [attr.tabindex]=\"disabled() || loading() ? -1 : 0\"\n (click)=\"toggle()\"\n (keydown)=\"handleKeyDown($event)\"\n >\n <div class=\"select-value\">\n <span [class.placeholder]=\"!hasValue()\">{{ selectedLabel() }}</span>\n </div>\n\n <div class=\"select-actions\">\n @if (clearable() && hasValue() && !loading()) {\n <button\n type=\"button\"\n class=\"select-clear\"\n (click)=\"clear($event)\"\n [attr.aria-label]=\"'Effacer la s\u00E9lection'\"\n [tabindex]=\"disabled() ? -1 : 0\"\n >\n <i class=\"ph ph-x\" aria-hidden=\"true\"></i>\n </button>\n }\n @if (loading()) {\n <div class=\"select-loader-trigger\" aria-hidden=\"true\"></div>\n } @else {\n <i\n class=\"ph ph-caret-down select-arrow\"\n [class.open]=\"isOpen()\"\n aria-hidden=\"true\"\n ></i>\n }\n </div>\n </div>\n\n @if (isOpen()) {\n <div\n class=\"select-dropdown\"\n role=\"listbox\"\n [id]=\"selectId + '-listbox'\"\n [attr.aria-multiselectable]=\"multiple()\"\n >\n @if (searchable()) {\n <div class=\"select-search\">\n <input\n type=\"text\"\n [placeholder]=\"searchConfig().placeholder\"\n [value]=\"searchTerm()\"\n (input)=\"onSearch($event)\"\n (click)=\"$event.stopPropagation()\"\n [attr.aria-label]=\"searchConfig().placeholder\"\n />\n </div>\n }\n\n <div class=\"select-options\" (scroll)=\"onScroll($event)\">\n @if (loading()) {\n <div class=\"select-loading\">\n <div class=\"select-loader\"></div>\n </div>\n } @else if (filteredOptions().length === 0) {\n <div class=\"select-no-results\">\n Aucun r\u00E9sultat\n </div>\n } @else {\n @for (option of filteredOptions(); track getOptionKey(option)) {\n @if (isOptionGroup(option)) {\n <div class=\"select-group\">\n <div class=\"select-group-label\">{{ option.label }}</div>\n @for (groupOption of option.options; track getOptionKey(groupOption)) {\n <div\n class=\"select-option\"\n role=\"option\"\n [class.selected]=\"isSelected(groupOption)\"\n [class.focused]=\"isFocused(groupOption)\"\n [class.disabled]=\"option.disabled || groupOption.disabled\"\n [attr.aria-selected]=\"isSelected(groupOption)\"\n [attr.aria-disabled]=\"(option.disabled || groupOption.disabled) || null\"\n [attr.id]=\"selectId + '-option-' + groupOption.value\"\n [attr.tabindex]=\"option.disabled || groupOption.disabled ? -1 : 0\"\n (click)=\"!option.disabled && select(groupOption)\"\n (keydown)=\"handleOptionKeyDown($event, groupOption)\"\n >\n @if (multiple()) {\n <div class=\"select-checkbox\">\n <i class=\"ph ph-check\" aria-hidden=\"true\"></i>\n </div>\n }\n @if (groupOption.icon) {\n <i class=\"ph ph-{{ groupOption.icon }}\" aria-hidden=\"true\"></i>\n }\n <div class=\"option-content\">\n <div class=\"option-label\">{{ groupOption.label }}</div>\n @if (groupOption.description) {\n <div class=\"option-description\">{{ groupOption.description }}</div>\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <div\n class=\"select-option\"\n role=\"option\"\n [class.selected]=\"isSelected(option)\"\n [class.focused]=\"isFocused(option)\"\n [class.disabled]=\"option.disabled\"\n [attr.aria-selected]=\"isSelected(option)\"\n [attr.aria-disabled]=\"option.disabled || null\"\n [attr.id]=\"selectId + '-option-' + option.value\"\n [attr.tabindex]=\"option.disabled ? -1 : 0\"\n (click)=\"select(option)\"\n (keydown)=\"handleOptionKeyDown($event, option)\"\n >\n @if (multiple()) {\n <div class=\"select-checkbox\">\n <i class=\"ph ph-check\" aria-hidden=\"true\"></i>\n </div>\n }\n @if (option.icon) {\n <i class=\"ph ph-{{ option.icon }}\" aria-hidden=\"true\"></i>\n }\n <div class=\"option-content\">\n <div class=\"option-label\">{{ option.label }}</div>\n @if (option.description) {\n <div class=\"option-description\">{{ option.description }}</div>\n }\n </div>\n </div>\n }\n }\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Error message slot -->\n @if (error()) {\n <div id=\"error-message\" class=\"select-error\" role=\"alert\">\n <ng-content select=\"[select-error]\">\n {{ error() }}\n </ng-content>\n </div>\n }\n\n <!-- Success message slot -->\n @if (success()) {\n <div id=\"success-message\" class=\"select-success\" role=\"status\">\n <ng-content select=\"[select-success]\">\n {{ success() }}\n </ng-content>\n </div>\n }\n\n <!-- Hint message slot -->\n @if (hint()) {\n <div id=\"hint-message\" class=\"select-hint\">\n <ng-content select=\"[select-hint]\">\n {{ hint() }}\n </ng-content>\n </div>\n }\n</div>", styles: [":host{display:block;width:100%;max-width:var(--select-max-width)}:host(.full-width){max-width:none}.select-container{width:100%}.select-trigger-wrapper{position:relative;width:100%}.select-label{display:block;color:var(--text-color);font-size:var(--font-size-sm);font-weight:500;margin-bottom:var(--spacing-xs);width:100%;cursor:pointer}.select-label.required:after{content:\"*\";color:var(--danger-color);margin-left:var(--spacing-xxs)}.select-trigger{display:flex;align-items:center;width:100%;min-width:12rem;height:var(--height-input-md);padding:0 var(--spacing-md);background:var(--surface-card);border:var(--border-width-1) solid var(--surface-border);border-radius:var(--border-radius);cursor:pointer;transition:all var(--animation-duration-normal) var(--animation-easing-default);outline:none}.select-trigger:hover{border-color:var(--primary-color)}:host(.disabled) .select-trigger:hover,:host(.loading) .select-trigger:hover{border-color:var(--surface-border)}.select-trigger:focus-visible{border-color:var(--primary-color);box-shadow:0 0 0 .125rem rgba(var(--primary-color-rgb),.2)}.select-value{display:flex;align-items:center;gap:var(--spacing-xs);flex:1;min-width:0;margin-right:var(--spacing-sm)}.select-value span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--text-color)}.select-value span.placeholder{color:var(--text-color-secondary)}.select-actions{display:flex;align-items:center;gap:var(--spacing-sm);flex-shrink:0}.select-arrow{transition:transform var(--animation-duration-normal) var(--animation-easing-default);font-size:var(--icon-size-sm);color:var(--text-color-secondary);flex-shrink:0}.select-arrow.open{transform:rotate(180deg)}.select-clear{display:flex;align-items:center;justify-content:center;width:var(--size-5);height:var(--size-5);padding:0;background:transparent;border:none;border-radius:50%;color:var(--text-color-secondary);cursor:pointer;transition:all var(--animation-duration-normal) var(--animation-easing-default);flex-shrink:0}.select-clear:hover{background:rgba(var(--danger-color-rgb),.1);color:var(--danger-color)}.select-dropdown{position:absolute;top:calc(100% + var(--spacing-xs));left:0;width:100%;background:var(--surface-card);border:var(--border-width-1) solid var(--surface-border);border-radius:var(--border-radius);box-shadow:var(--shadow-lg);z-index:1000;animation:fadeIn var(--animation-duration-normal) var(--animation-easing-default)}.select-search{display:flex;align-items:center;gap:var(--spacing-sm);padding:var(--spacing-sm);border-bottom:var(--border-width-1) solid var(--surface-border)}.select-search input{width:100%;padding:var(--spacing-xs) var(--spacing-sm);border:var(--border-width-1) solid var(--surface-border);border-radius:var(--border-radius);background:var(--surface-ground)}.select-search input:focus{outline:none;border-color:var(--primary-color)}.select-options{max-height:var(--dropdown-max-height);overflow-y:auto}.select-group{padding:var(--spacing-xs) 0}.select-group-label{padding:var(--spacing-xs) var(--spacing-md);color:var(--text-color-secondary);font-weight:500;font-size:var(--font-size-sm)}.select-option{display:flex;align-items:center;gap:var(--spacing-md);padding:var(--spacing-sm) var(--spacing-md);cursor:pointer;transition:all var(--animation-duration-normal) var(--animation-easing-default)}.select-option:hover:not(.disabled){background:var(--surface-hover)}.select-option.focused:not(.disabled){background:var(--surface-hover);outline:2px solid var(--primary-color);outline-offset:-2px}.select-option.selected{background:rgba(var(--primary-color-rgb),.1);color:var(--primary-color)}.select-option.selected.focused{background:rgba(var(--primary-color-rgb),.15);outline:2px solid var(--primary-color);outline-offset:-2px}.select-option.disabled{opacity:.6;cursor:not-allowed}.select-option i{font-size:var(--icon-size-md);color:var(--text-color-secondary);flex-shrink:0}.select-option.selected i{color:var(--primary-color)}.option-content{flex:1;min-width:0}.option-label{color:inherit;font-size:var(--font-size-base)}.option-description{color:var(--text-color-secondary);font-size:var(--font-size-sm);margin-top:var(--spacing-xs)}.select-checkbox{display:flex;align-items:center;justify-content:center;width:var(--select-checkbox-size);height:var(--select-checkbox-size);border:var(--border-width-2) solid var(--surface-border);border-radius:var(--border-radius);transition:all var(--animation-duration-normal) var(--animation-easing-default)}.selected .select-checkbox{background:var(--primary-gradient);border-color:var(--primary-color);color:var(--primary-color-text)}.select-no-results{padding:var(--spacing-md);text-align:center;color:var(--text-color-secondary)}.select-loading{padding:var(--spacing-md);text-align:center}.select-loader{width:var(--size-6);height:var(--size-6);border:var(--border-width-2) solid var(--surface-border);border-top-color:var(--primary-color);border-radius:50%;animation:spin var(--animation-duration-slow) linear infinite;margin:0 auto}.select-loader-trigger{width:var(--icon-size-sm);height:var(--icon-size-sm);border:var(--border-width-2) solid var(--surface-border);border-top-color:var(--primary-color);border-radius:50%;animation:spin var(--animation-duration-slow) linear infinite;flex-shrink:0}.select-error{margin-top:var(--spacing-xs);color:var(--danger-color);font-size:var(--font-size-sm)}.select-success{margin-top:var(--spacing-xs);color:var(--success-color);font-size:var(--font-size-sm)}.select-hint{font-size:var(--font-size-sm);color:var(--text-color-secondary);margin-top:var(--spacing-xs)}.virtual-scroll{position:relative;overflow:hidden}:host(.disabled) .select-trigger{background:var(--surface-ground);cursor:not-allowed;opacity:.6}:host(.loading) .select-trigger{cursor:wait;opacity:.7}:host(.error) .select-trigger{border-color:var(--danger-color)}:host(.success) .select-trigger{border-color:var(--success-color)}:host(.small) .select-trigger{height:var(--height-input-sm);font-size:var(--font-size-sm);padding:0 var(--spacing-sm)}:host(.small) .select-arrow{font-size:var(--icon-size-xs)}:host(.small) .select-value{margin-right:var(--spacing-xs)}:host(.small) .select-actions{gap:var(--spacing-xs)}:host(.small) .select-dropdown{font-size:var(--font-size-sm)}:host(.small) .select-search{padding:var(--spacing-xs)}:host(.small) .select-search input{padding:var(--spacing-xxs) var(--spacing-xs);font-size:var(--font-size-sm)}:host(.small) .select-option{padding:var(--spacing-xs) var(--spacing-sm);gap:var(--spacing-sm)}:host(.small) .select-option i{font-size:var(--icon-size-sm)}:host(.small) .option-label{font-size:var(--font-size-sm)}:host(.small) .option-description{font-size:var(--font-size-xs);margin-top:var(--spacing-xxs)}:host(.small) .select-group-label{padding:var(--spacing-xxs) var(--spacing-sm);font-size:var(--font-size-xs)}:host(.small) .select-checkbox{width:calc(var(--select-checkbox-size) * .85);height:calc(var(--select-checkbox-size) * .85)}:host(.large) .select-trigger{height:var(--height-input-lg);font-size:var(--font-size-lg);padding:0 var(--spacing-lg)}:host(.large) .select-arrow{font-size:var(--icon-size-md)}:host(.large) .select-value{margin-right:var(--spacing-md)}:host(.large) .select-actions{gap:var(--spacing-md)}:host(.large) .select-dropdown{font-size:var(--font-size-lg)}:host(.large) .select-search{padding:var(--spacing-md)}:host(.large) .select-search input{padding:var(--spacing-sm) var(--spacing-md);font-size:var(--font-size-lg)}:host(.large) .select-option{padding:var(--spacing-md) var(--spacing-lg);gap:var(--spacing-lg)}:host(.large) .select-option i{font-size:var(--icon-size-lg)}:host(.large) .option-label{font-size:var(--font-size-lg)}:host(.large) .option-description{font-size:var(--font-size-base);margin-top:var(--spacing-xs)}:host(.large) .select-group-label{padding:var(--spacing-sm) var(--spacing-lg);font-size:var(--font-size-base)}:host(.large) .select-checkbox{width:calc(var(--select-checkbox-size) * 1.15);height:calc(var(--select-checkbox-size) * 1.15)}@media(max-width:36em){:host{max-width:none}}@keyframes fadeIn{0%{opacity:0;transform:translateY(calc(-1 * var(--spacing-sm)))}to{opacity:1;transform:translateY(0)}}@keyframes spin{to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3007
+ ], ngImport: i0, template: "<div class=\"select-container\">\n\n @if (label()) {\n\n <label class=\"select-label\" [attr.for]=\"selectId\" (click)=\"focusSelect()\">\n\n {{ label() }}\n\n @if (required()) { <span class=\"required-mark\">*</span> }\n\n </label>\n\n }\n\n\n\n <div class=\"select-trigger\" [id]=\"selectId\" (click)=\"toggle()\" tabindex=\"0\">\n\n <div class=\"select-value\">\n\n <span [class.placeholder]=\"!hasValue()\">\n\n {{ selectedLabel() }}\n\n </span>\n\n </div>\n\n \n\n <div class=\"select-actions\">\n\n @if (clearable() && hasValue() && !disabled()) {\n\n <button class=\"select-clear\" (click)=\"clear($event)\">\n\n <i class=\"ph ph-x\"></i>\n\n </button>\n\n }\n\n @if (loading()) {\n\n <div class=\"select-loader-trigger\"></div>\n\n } @else {\n\n <i class=\"ph ph-caret-down select-arrow\"></i>\n\n }\n\n </div>\n\n </div>\n\n\n\n @if (isOpen()) {\n\n <div class=\"select-dropdown\">\n\n @if (searchable()) {\n\n <div class=\"select-search\">\n\n <i class=\"ph ph-magnifying-glass select-search-icon\"></i>\n\n <input type=\"text\"\n\n [placeholder]=\"searchConfig().placeholder\"\n\n [value]=\"searchTerm()\"\n\n (input)=\"onSearch($event)\"\n\n (click)=\"$event.stopPropagation()\">\n\n </div>\n\n }\n\n <div class=\"select-options\" (scroll)=\"onScroll($event)\">\n\n @for (item of filteredOptions(); track getOptionKey(item)) {\n\n @if (isOptionGroup(item)) {\n\n <div class=\"select-group\">\n\n <div class=\"select-group-label\">{{ item.label }}</div>\n\n @for (opt of item.options; track opt.label) {\n\n <div class=\"select-option\" \n\n [class.selected]=\"isSelected(opt)\"\n\n (click)=\"select(opt)\">\n\n {{ opt.label }}\n\n </div>\n\n }\n\n </div>\n\n } @else {\n\n <div class=\"select-option\" \n\n [class.selected]=\"isSelected(item)\"\n\n (click)=\"select(item)\">\n\n {{ item.label }}\n\n </div>\n\n }\n\n } @empty {\n\n <div class=\"select-no-results\">Aucun r\u00E9sultat</div>\n\n }\n\n </div>\n\n </div>\n\n }\n\n</div>", styles: [":host{display:block;width:100%;max-width:18.75rem}:host.select-full-width{max-width:none}.select-container{position:relative;width:100%}.select-label{display:block;color:var(--text-color);font-size:.875rem;font-weight:500;margin-bottom:.25rem;cursor:pointer}.select-trigger{display:flex;align-items:center;justify-content:space-between;width:100%;height:2.5rem;padding:0 1rem;background:var(--surface-card);border:.0625rem solid var(--surface-border);border-radius:var(--border-radius);cursor:pointer;box-sizing:border-box}.select-trigger:focus{border-color:var(--primary-color);outline:none}.select-value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select-actions{display:flex;align-items:center;gap:.5rem;flex-shrink:0}.select-clear{background:none;border:none;cursor:pointer;padding:0;color:var(--text-color-secondary);display:flex}.select-clear:hover{color:var(--danger-color)}.select-loader-trigger{width:1rem;height:1rem;border:2px solid var(--surface-border);border-top-color:var(--primary-color);border-radius:50%;animation:spin .8s linear infinite}.select-arrow{transition:transform .2s;font-size:1rem;color:var(--text-color-secondary)}:host[aria-expanded=true] .select-arrow{transform:rotate(180deg)}.select-dropdown{position:absolute;top:calc(100% + .25rem);left:0;right:0;z-index:1000;background:var(--surface-card);border:.0625rem solid var(--surface-border);border-radius:var(--border-radius);box-shadow:var(--shadow-lg)}.select-search{position:relative;padding:.5rem;border-bottom:.0625rem solid var(--surface-border)}.select-search-icon{position:absolute;left:1.25rem;top:50%;transform:translateY(-50%);color:var(--text-color-secondary);font-size:.875rem;pointer-events:none}.select-search input{width:100%;height:2rem;padding:0 .75rem 0 2rem;background:var(--surface-ground);border:.0625rem solid var(--surface-border);border-radius:var(--border-radius);color:var(--text-color);font-size:.875rem;outline:none;box-sizing:border-box;transition:border-color .15s}.select-search input::placeholder{color:var(--text-color-secondary)}.select-search input:focus{border-color:var(--primary-color)}.select-options{max-height:15rem;overflow-y:auto}.select-group-label{padding:.5rem 1rem;font-size:.75rem;font-weight:600;color:var(--text-color-secondary);background:var(--surface-ground)}.select-option{padding:.625rem 1rem;cursor:pointer}.select-option:hover{background:var(--surface-hover)}.select-option.selected{background:rgba(var(--primary-color-rgb),.1);color:var(--primary-color);font-weight:500}:host.select-small .select-trigger{text-overflow:ellipsis;height:2rem;font-size:.875rem}:host.select-large .select-trigger{text-overflow:ellipsis;height:3rem;font-size:1.125rem}@keyframes spin{to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3269
3008
  }
3270
3009
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: PshSelectComponent, decorators: [{
3271
3010
  type: Component,
@@ -3276,15 +3015,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
3276
3015
  multi: true
3277
3016
  }
3278
3017
  ], changeDetection: ChangeDetectionStrategy.OnPush, host: {
3279
- '[class.full-width]': 'fullWidth()',
3280
- '[class.small]': 'size() === "small"',
3281
- '[class.large]': 'size() === "large"',
3282
- '[class.error]': '!!error()',
3283
- '[class.success]': '!!success()',
3284
- '[class.disabled]': 'disabled()',
3285
- '[class.loading]': 'loading()',
3286
- }, template: "<div class=\"select-container\">\n <!-- Label slot -->\n @if (label() || hasLabelContent()) {\n <label class=\"select-label\" [for]=\"selectId\" (click)=\"focusSelect()\" [class.required]=\"!!required()\">\n <ng-content select=\"[select-label]\" />\n @if (!hasLabelContent()) {\n {{ label() }}\n }\n </label>\n }\n\n <div class=\"select-trigger-wrapper\">\n <div\n class=\"select-trigger\"\n [id]=\"selectId\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n [attr.aria-controls]=\"selectId + '-listbox'\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-disabled]=\"disabled()\"\n [attr.aria-busy]=\"loading() ? 'true' : null\"\n [attr.aria-required]=\"required() ? 'true' : 'false'\"\n [attr.aria-invalid]=\"!!error()\"\n [attr.aria-label]=\"computedAriaLabel()\"\n [attr.aria-describedby]=\"error() ? 'error-message' : success() ? 'success-message' : hint() ? 'hint-message' : null\"\n [attr.aria-activedescendant]=\"activeDescendant()\"\n [attr.tabindex]=\"disabled() || loading() ? -1 : 0\"\n (click)=\"toggle()\"\n (keydown)=\"handleKeyDown($event)\"\n >\n <div class=\"select-value\">\n <span [class.placeholder]=\"!hasValue()\">{{ selectedLabel() }}</span>\n </div>\n\n <div class=\"select-actions\">\n @if (clearable() && hasValue() && !loading()) {\n <button\n type=\"button\"\n class=\"select-clear\"\n (click)=\"clear($event)\"\n [attr.aria-label]=\"'Effacer la s\u00E9lection'\"\n [tabindex]=\"disabled() ? -1 : 0\"\n >\n <i class=\"ph ph-x\" aria-hidden=\"true\"></i>\n </button>\n }\n @if (loading()) {\n <div class=\"select-loader-trigger\" aria-hidden=\"true\"></div>\n } @else {\n <i\n class=\"ph ph-caret-down select-arrow\"\n [class.open]=\"isOpen()\"\n aria-hidden=\"true\"\n ></i>\n }\n </div>\n </div>\n\n @if (isOpen()) {\n <div\n class=\"select-dropdown\"\n role=\"listbox\"\n [id]=\"selectId + '-listbox'\"\n [attr.aria-multiselectable]=\"multiple()\"\n >\n @if (searchable()) {\n <div class=\"select-search\">\n <input\n type=\"text\"\n [placeholder]=\"searchConfig().placeholder\"\n [value]=\"searchTerm()\"\n (input)=\"onSearch($event)\"\n (click)=\"$event.stopPropagation()\"\n [attr.aria-label]=\"searchConfig().placeholder\"\n />\n </div>\n }\n\n <div class=\"select-options\" (scroll)=\"onScroll($event)\">\n @if (loading()) {\n <div class=\"select-loading\">\n <div class=\"select-loader\"></div>\n </div>\n } @else if (filteredOptions().length === 0) {\n <div class=\"select-no-results\">\n Aucun r\u00E9sultat\n </div>\n } @else {\n @for (option of filteredOptions(); track getOptionKey(option)) {\n @if (isOptionGroup(option)) {\n <div class=\"select-group\">\n <div class=\"select-group-label\">{{ option.label }}</div>\n @for (groupOption of option.options; track getOptionKey(groupOption)) {\n <div\n class=\"select-option\"\n role=\"option\"\n [class.selected]=\"isSelected(groupOption)\"\n [class.focused]=\"isFocused(groupOption)\"\n [class.disabled]=\"option.disabled || groupOption.disabled\"\n [attr.aria-selected]=\"isSelected(groupOption)\"\n [attr.aria-disabled]=\"(option.disabled || groupOption.disabled) || null\"\n [attr.id]=\"selectId + '-option-' + groupOption.value\"\n [attr.tabindex]=\"option.disabled || groupOption.disabled ? -1 : 0\"\n (click)=\"!option.disabled && select(groupOption)\"\n (keydown)=\"handleOptionKeyDown($event, groupOption)\"\n >\n @if (multiple()) {\n <div class=\"select-checkbox\">\n <i class=\"ph ph-check\" aria-hidden=\"true\"></i>\n </div>\n }\n @if (groupOption.icon) {\n <i class=\"ph ph-{{ groupOption.icon }}\" aria-hidden=\"true\"></i>\n }\n <div class=\"option-content\">\n <div class=\"option-label\">{{ groupOption.label }}</div>\n @if (groupOption.description) {\n <div class=\"option-description\">{{ groupOption.description }}</div>\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <div\n class=\"select-option\"\n role=\"option\"\n [class.selected]=\"isSelected(option)\"\n [class.focused]=\"isFocused(option)\"\n [class.disabled]=\"option.disabled\"\n [attr.aria-selected]=\"isSelected(option)\"\n [attr.aria-disabled]=\"option.disabled || null\"\n [attr.id]=\"selectId + '-option-' + option.value\"\n [attr.tabindex]=\"option.disabled ? -1 : 0\"\n (click)=\"select(option)\"\n (keydown)=\"handleOptionKeyDown($event, option)\"\n >\n @if (multiple()) {\n <div class=\"select-checkbox\">\n <i class=\"ph ph-check\" aria-hidden=\"true\"></i>\n </div>\n }\n @if (option.icon) {\n <i class=\"ph ph-{{ option.icon }}\" aria-hidden=\"true\"></i>\n }\n <div class=\"option-content\">\n <div class=\"option-label\">{{ option.label }}</div>\n @if (option.description) {\n <div class=\"option-description\">{{ option.description }}</div>\n }\n </div>\n </div>\n }\n }\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Error message slot -->\n @if (error()) {\n <div id=\"error-message\" class=\"select-error\" role=\"alert\">\n <ng-content select=\"[select-error]\">\n {{ error() }}\n </ng-content>\n </div>\n }\n\n <!-- Success message slot -->\n @if (success()) {\n <div id=\"success-message\" class=\"select-success\" role=\"status\">\n <ng-content select=\"[select-success]\">\n {{ success() }}\n </ng-content>\n </div>\n }\n\n <!-- Hint message slot -->\n @if (hint()) {\n <div id=\"hint-message\" class=\"select-hint\">\n <ng-content select=\"[select-hint]\">\n {{ hint() }}\n </ng-content>\n </div>\n }\n</div>", styles: [":host{display:block;width:100%;max-width:var(--select-max-width)}:host(.full-width){max-width:none}.select-container{width:100%}.select-trigger-wrapper{position:relative;width:100%}.select-label{display:block;color:var(--text-color);font-size:var(--font-size-sm);font-weight:500;margin-bottom:var(--spacing-xs);width:100%;cursor:pointer}.select-label.required:after{content:\"*\";color:var(--danger-color);margin-left:var(--spacing-xxs)}.select-trigger{display:flex;align-items:center;width:100%;min-width:12rem;height:var(--height-input-md);padding:0 var(--spacing-md);background:var(--surface-card);border:var(--border-width-1) solid var(--surface-border);border-radius:var(--border-radius);cursor:pointer;transition:all var(--animation-duration-normal) var(--animation-easing-default);outline:none}.select-trigger:hover{border-color:var(--primary-color)}:host(.disabled) .select-trigger:hover,:host(.loading) .select-trigger:hover{border-color:var(--surface-border)}.select-trigger:focus-visible{border-color:var(--primary-color);box-shadow:0 0 0 .125rem rgba(var(--primary-color-rgb),.2)}.select-value{display:flex;align-items:center;gap:var(--spacing-xs);flex:1;min-width:0;margin-right:var(--spacing-sm)}.select-value span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--text-color)}.select-value span.placeholder{color:var(--text-color-secondary)}.select-actions{display:flex;align-items:center;gap:var(--spacing-sm);flex-shrink:0}.select-arrow{transition:transform var(--animation-duration-normal) var(--animation-easing-default);font-size:var(--icon-size-sm);color:var(--text-color-secondary);flex-shrink:0}.select-arrow.open{transform:rotate(180deg)}.select-clear{display:flex;align-items:center;justify-content:center;width:var(--size-5);height:var(--size-5);padding:0;background:transparent;border:none;border-radius:50%;color:var(--text-color-secondary);cursor:pointer;transition:all var(--animation-duration-normal) var(--animation-easing-default);flex-shrink:0}.select-clear:hover{background:rgba(var(--danger-color-rgb),.1);color:var(--danger-color)}.select-dropdown{position:absolute;top:calc(100% + var(--spacing-xs));left:0;width:100%;background:var(--surface-card);border:var(--border-width-1) solid var(--surface-border);border-radius:var(--border-radius);box-shadow:var(--shadow-lg);z-index:1000;animation:fadeIn var(--animation-duration-normal) var(--animation-easing-default)}.select-search{display:flex;align-items:center;gap:var(--spacing-sm);padding:var(--spacing-sm);border-bottom:var(--border-width-1) solid var(--surface-border)}.select-search input{width:100%;padding:var(--spacing-xs) var(--spacing-sm);border:var(--border-width-1) solid var(--surface-border);border-radius:var(--border-radius);background:var(--surface-ground)}.select-search input:focus{outline:none;border-color:var(--primary-color)}.select-options{max-height:var(--dropdown-max-height);overflow-y:auto}.select-group{padding:var(--spacing-xs) 0}.select-group-label{padding:var(--spacing-xs) var(--spacing-md);color:var(--text-color-secondary);font-weight:500;font-size:var(--font-size-sm)}.select-option{display:flex;align-items:center;gap:var(--spacing-md);padding:var(--spacing-sm) var(--spacing-md);cursor:pointer;transition:all var(--animation-duration-normal) var(--animation-easing-default)}.select-option:hover:not(.disabled){background:var(--surface-hover)}.select-option.focused:not(.disabled){background:var(--surface-hover);outline:2px solid var(--primary-color);outline-offset:-2px}.select-option.selected{background:rgba(var(--primary-color-rgb),.1);color:var(--primary-color)}.select-option.selected.focused{background:rgba(var(--primary-color-rgb),.15);outline:2px solid var(--primary-color);outline-offset:-2px}.select-option.disabled{opacity:.6;cursor:not-allowed}.select-option i{font-size:var(--icon-size-md);color:var(--text-color-secondary);flex-shrink:0}.select-option.selected i{color:var(--primary-color)}.option-content{flex:1;min-width:0}.option-label{color:inherit;font-size:var(--font-size-base)}.option-description{color:var(--text-color-secondary);font-size:var(--font-size-sm);margin-top:var(--spacing-xs)}.select-checkbox{display:flex;align-items:center;justify-content:center;width:var(--select-checkbox-size);height:var(--select-checkbox-size);border:var(--border-width-2) solid var(--surface-border);border-radius:var(--border-radius);transition:all var(--animation-duration-normal) var(--animation-easing-default)}.selected .select-checkbox{background:var(--primary-gradient);border-color:var(--primary-color);color:var(--primary-color-text)}.select-no-results{padding:var(--spacing-md);text-align:center;color:var(--text-color-secondary)}.select-loading{padding:var(--spacing-md);text-align:center}.select-loader{width:var(--size-6);height:var(--size-6);border:var(--border-width-2) solid var(--surface-border);border-top-color:var(--primary-color);border-radius:50%;animation:spin var(--animation-duration-slow) linear infinite;margin:0 auto}.select-loader-trigger{width:var(--icon-size-sm);height:var(--icon-size-sm);border:var(--border-width-2) solid var(--surface-border);border-top-color:var(--primary-color);border-radius:50%;animation:spin var(--animation-duration-slow) linear infinite;flex-shrink:0}.select-error{margin-top:var(--spacing-xs);color:var(--danger-color);font-size:var(--font-size-sm)}.select-success{margin-top:var(--spacing-xs);color:var(--success-color);font-size:var(--font-size-sm)}.select-hint{font-size:var(--font-size-sm);color:var(--text-color-secondary);margin-top:var(--spacing-xs)}.virtual-scroll{position:relative;overflow:hidden}:host(.disabled) .select-trigger{background:var(--surface-ground);cursor:not-allowed;opacity:.6}:host(.loading) .select-trigger{cursor:wait;opacity:.7}:host(.error) .select-trigger{border-color:var(--danger-color)}:host(.success) .select-trigger{border-color:var(--success-color)}:host(.small) .select-trigger{height:var(--height-input-sm);font-size:var(--font-size-sm);padding:0 var(--spacing-sm)}:host(.small) .select-arrow{font-size:var(--icon-size-xs)}:host(.small) .select-value{margin-right:var(--spacing-xs)}:host(.small) .select-actions{gap:var(--spacing-xs)}:host(.small) .select-dropdown{font-size:var(--font-size-sm)}:host(.small) .select-search{padding:var(--spacing-xs)}:host(.small) .select-search input{padding:var(--spacing-xxs) var(--spacing-xs);font-size:var(--font-size-sm)}:host(.small) .select-option{padding:var(--spacing-xs) var(--spacing-sm);gap:var(--spacing-sm)}:host(.small) .select-option i{font-size:var(--icon-size-sm)}:host(.small) .option-label{font-size:var(--font-size-sm)}:host(.small) .option-description{font-size:var(--font-size-xs);margin-top:var(--spacing-xxs)}:host(.small) .select-group-label{padding:var(--spacing-xxs) var(--spacing-sm);font-size:var(--font-size-xs)}:host(.small) .select-checkbox{width:calc(var(--select-checkbox-size) * .85);height:calc(var(--select-checkbox-size) * .85)}:host(.large) .select-trigger{height:var(--height-input-lg);font-size:var(--font-size-lg);padding:0 var(--spacing-lg)}:host(.large) .select-arrow{font-size:var(--icon-size-md)}:host(.large) .select-value{margin-right:var(--spacing-md)}:host(.large) .select-actions{gap:var(--spacing-md)}:host(.large) .select-dropdown{font-size:var(--font-size-lg)}:host(.large) .select-search{padding:var(--spacing-md)}:host(.large) .select-search input{padding:var(--spacing-sm) var(--spacing-md);font-size:var(--font-size-lg)}:host(.large) .select-option{padding:var(--spacing-md) var(--spacing-lg);gap:var(--spacing-lg)}:host(.large) .select-option i{font-size:var(--icon-size-lg)}:host(.large) .option-label{font-size:var(--font-size-lg)}:host(.large) .option-description{font-size:var(--font-size-base);margin-top:var(--spacing-xs)}:host(.large) .select-group-label{padding:var(--spacing-sm) var(--spacing-lg);font-size:var(--font-size-base)}:host(.large) .select-checkbox{width:calc(var(--select-checkbox-size) * 1.15);height:calc(var(--select-checkbox-size) * 1.15)}@media(max-width:36em){:host{max-width:none}}@keyframes fadeIn{0%{opacity:0;transform:translateY(calc(-1 * var(--spacing-sm)))}to{opacity:1;transform:translateY(0)}}@keyframes spin{to{transform:rotate(360deg)}}\n"] }]
3287
- }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }, { type: i0.Output, args: ["disabledChange"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], multiplePlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiplePlaceholder", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], success: [{ type: i0.Input, args: [{ isSignal: true, alias: "success", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], maxSelections: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSelections", required: false }] }], minSelections: [{ type: i0.Input, args: [{ isSignal: true, alias: "minSelections", required: false }] }], compareWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "compareWith", required: false }] }], searchConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchConfig", required: false }] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], scrollEnd: [{ type: i0.Output, args: ["scrollEnd"] }], searched: [{ type: i0.Output, args: ["searched"] }] } });
3018
+ '[class.select-full-width]': 'fullWidth()',
3019
+ '[class.select-small]': 'size() === "small"',
3020
+ '[class.select-large]': 'size() === "large"',
3021
+ '[class.select-error]': '!!error()',
3022
+ '[class.select-disabled]': 'disabled()',
3023
+ '[class.select-loading]': 'loading()',
3024
+ '[attr.aria-expanded]': 'isOpen().toString()',
3025
+ '[attr.data-state]': 'state()'
3026
+ }, template: "<div class=\"select-container\">\n\n @if (label()) {\n\n <label class=\"select-label\" [attr.for]=\"selectId\" (click)=\"focusSelect()\">\n\n {{ label() }}\n\n @if (required()) { <span class=\"required-mark\">*</span> }\n\n </label>\n\n }\n\n\n\n <div class=\"select-trigger\" [id]=\"selectId\" (click)=\"toggle()\" tabindex=\"0\">\n\n <div class=\"select-value\">\n\n <span [class.placeholder]=\"!hasValue()\">\n\n {{ selectedLabel() }}\n\n </span>\n\n </div>\n\n \n\n <div class=\"select-actions\">\n\n @if (clearable() && hasValue() && !disabled()) {\n\n <button class=\"select-clear\" (click)=\"clear($event)\">\n\n <i class=\"ph ph-x\"></i>\n\n </button>\n\n }\n\n @if (loading()) {\n\n <div class=\"select-loader-trigger\"></div>\n\n } @else {\n\n <i class=\"ph ph-caret-down select-arrow\"></i>\n\n }\n\n </div>\n\n </div>\n\n\n\n @if (isOpen()) {\n\n <div class=\"select-dropdown\">\n\n @if (searchable()) {\n\n <div class=\"select-search\">\n\n <i class=\"ph ph-magnifying-glass select-search-icon\"></i>\n\n <input type=\"text\"\n\n [placeholder]=\"searchConfig().placeholder\"\n\n [value]=\"searchTerm()\"\n\n (input)=\"onSearch($event)\"\n\n (click)=\"$event.stopPropagation()\">\n\n </div>\n\n }\n\n <div class=\"select-options\" (scroll)=\"onScroll($event)\">\n\n @for (item of filteredOptions(); track getOptionKey(item)) {\n\n @if (isOptionGroup(item)) {\n\n <div class=\"select-group\">\n\n <div class=\"select-group-label\">{{ item.label }}</div>\n\n @for (opt of item.options; track opt.label) {\n\n <div class=\"select-option\" \n\n [class.selected]=\"isSelected(opt)\"\n\n (click)=\"select(opt)\">\n\n {{ opt.label }}\n\n </div>\n\n }\n\n </div>\n\n } @else {\n\n <div class=\"select-option\" \n\n [class.selected]=\"isSelected(item)\"\n\n (click)=\"select(item)\">\n\n {{ item.label }}\n\n </div>\n\n }\n\n } @empty {\n\n <div class=\"select-no-results\">Aucun r\u00E9sultat</div>\n\n }\n\n </div>\n\n </div>\n\n }\n\n</div>", styles: [":host{display:block;width:100%;max-width:18.75rem}:host.select-full-width{max-width:none}.select-container{position:relative;width:100%}.select-label{display:block;color:var(--text-color);font-size:.875rem;font-weight:500;margin-bottom:.25rem;cursor:pointer}.select-trigger{display:flex;align-items:center;justify-content:space-between;width:100%;height:2.5rem;padding:0 1rem;background:var(--surface-card);border:.0625rem solid var(--surface-border);border-radius:var(--border-radius);cursor:pointer;box-sizing:border-box}.select-trigger:focus{border-color:var(--primary-color);outline:none}.select-value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select-actions{display:flex;align-items:center;gap:.5rem;flex-shrink:0}.select-clear{background:none;border:none;cursor:pointer;padding:0;color:var(--text-color-secondary);display:flex}.select-clear:hover{color:var(--danger-color)}.select-loader-trigger{width:1rem;height:1rem;border:2px solid var(--surface-border);border-top-color:var(--primary-color);border-radius:50%;animation:spin .8s linear infinite}.select-arrow{transition:transform .2s;font-size:1rem;color:var(--text-color-secondary)}:host[aria-expanded=true] .select-arrow{transform:rotate(180deg)}.select-dropdown{position:absolute;top:calc(100% + .25rem);left:0;right:0;z-index:1000;background:var(--surface-card);border:.0625rem solid var(--surface-border);border-radius:var(--border-radius);box-shadow:var(--shadow-lg)}.select-search{position:relative;padding:.5rem;border-bottom:.0625rem solid var(--surface-border)}.select-search-icon{position:absolute;left:1.25rem;top:50%;transform:translateY(-50%);color:var(--text-color-secondary);font-size:.875rem;pointer-events:none}.select-search input{width:100%;height:2rem;padding:0 .75rem 0 2rem;background:var(--surface-ground);border:.0625rem solid var(--surface-border);border-radius:var(--border-radius);color:var(--text-color);font-size:.875rem;outline:none;box-sizing:border-box;transition:border-color .15s}.select-search input::placeholder{color:var(--text-color-secondary)}.select-search input:focus{border-color:var(--primary-color)}.select-options{max-height:15rem;overflow-y:auto}.select-group-label{padding:.5rem 1rem;font-size:.75rem;font-weight:600;color:var(--text-color-secondary);background:var(--surface-ground)}.select-option{padding:.625rem 1rem;cursor:pointer}.select-option:hover{background:var(--surface-hover)}.select-option.selected{background:rgba(var(--primary-color-rgb),.1);color:var(--primary-color);font-weight:500}:host.select-small .select-trigger{text-overflow:ellipsis;height:2rem;font-size:.875rem}:host.select-large .select-trigger{text-overflow:ellipsis;height:3rem;font-size:1.125rem}@keyframes spin{to{transform:rotate(360deg)}}\n"] }]
3027
+ }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }, { type: i0.Output, args: ["disabledChange"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], multiplePlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiplePlaceholder", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], compareWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "compareWith", required: false }] }], searchConfig: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchConfig", required: false }] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], searched: [{ type: i0.Output, args: ["searched"] }], scrollEnd: [{ type: i0.Output, args: ["scrollEnd"] }] } });
3288
3028
 
3289
3029
  const SIDEBAR_CONFIG = new InjectionToken('SIDEBAR_CONFIG', {
3290
3030
  factory: () => ({