ps-helix 4.1.0 → 4.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  A comprehensive Angular component library built with Angular 21+ featuring modern design patterns, accessibility-first development, and optimal developer experience.
4
4
 
5
- [![npm version](https://img.shields.io/badge/npm-4.1.0-blue.svg)](https://www.npmjs.com/package/ps-helix)
5
+ [![npm version](https://img.shields.io/badge/npm-4.1.1-blue.svg)](https://www.npmjs.com/package/ps-helix)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
7
  [![Angular](https://img.shields.io/badge/Angular-21.0.3-red.svg)](https://angular.dev/)
8
8
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.9.0-blue.svg)](https://www.typescriptlang.org/)
@@ -106,7 +106,7 @@ After installation, verify that ps-helix is in your `package.json`:
106
106
  ```json
107
107
  {
108
108
  "dependencies": {
109
- "ps-helix": "^4.1.0"
109
+ "ps-helix": "^4.1.1"
110
110
  }
111
111
  }
112
112
  ```
@@ -1182,7 +1182,7 @@ Copyright (c) 2025 PACK Solutions
1182
1182
 
1183
1183
  ---
1184
1184
 
1185
- **Version**: 4.1.0
1185
+ **Version**: 4.1.1
1186
1186
  **Built with**: Angular 21.0.3, TypeScript 5.9.0, Phosphor Icons 2.0.3
1187
1187
  **Author**: Fabrice PEREZ | Product Designer at PACK Solutions
1188
1188
  **Last Updated**: January 2026
@@ -1567,7 +1567,7 @@ class PshInputComponent {
1567
1567
  useExisting: PshInputComponent,
1568
1568
  multi: true
1569
1569
  }
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 }); }
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:.125rem 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}:host.filled input{background:var(--surface-ground);border:.125rem solid var(--surface-border)}: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 }); }
1571
1571
  }
1572
1572
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: PshInputComponent, decorators: [{
1573
1573
  type: Component,
@@ -1591,7 +1591,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImpor
1591
1591
  '[class.has-end-icon]': '!!iconEnd() || type() === "password"',
1592
1592
  '[class.outlined]': 'variant() === "outlined"',
1593
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"] }]
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:.125rem 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}:host.filled input{background:var(--surface-ground);border:.125rem solid var(--surface-border)}: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"] }]
1595
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"] }] } });
1596
1596
 
1597
1597
  const TOOLTIP_CONFIG = new InjectionToken('TOOLTIP_CONFIG', {
@@ -2847,6 +2847,7 @@ class PshSelectComponent {
2847
2847
  this.disabled = model(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
2848
2848
  this.touched = model(false, ...(ngDevMode ? [{ debugName: "touched" }] : /* istanbul ignore next */ []));
2849
2849
  this.size = input('medium', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
2850
+ this.variant = input('outlined', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
2850
2851
  this.searchable = input(false, ...(ngDevMode ? [{ debugName: "searchable" }] : /* istanbul ignore next */ []));
2851
2852
  this.multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple" }] : /* istanbul ignore next */ []));
2852
2853
  this.clearable = input(false, ...(ngDevMode ? [{ debugName: "clearable" }] : /* istanbul ignore next */ []));
@@ -3141,13 +3142,13 @@ class PshSelectComponent {
3141
3142
  }
3142
3143
  }
3143
3144
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: PshSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3144
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.2", 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 }, success: { classPropertyName: "success", publicName: "success", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", 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", searched: "searched", scrollEnd: "scrollEnd" }, 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()", "attr.aria-expanded": "isOpen().toString()", "attr.data-state": "state()" } }, providers: [
3145
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.2", 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 }, variant: { classPropertyName: "variant", publicName: "variant", 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 }, success: { classPropertyName: "success", publicName: "success", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", 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", searched: "searched", scrollEnd: "scrollEnd" }, host: { properties: { "class.full-width": "fullWidth()", "class.small": "size() === \"small\"", "class.large": "size() === \"large\"", "class.outlined": "variant() === \"outlined\"", "class.filled": "variant() === \"filled\"", "class.error": "!!error()", "class.success": "!!success()", "class.disabled": "disabled()", "class.loading": "loading()", "attr.aria-expanded": "isOpen().toString()", "attr.data-state": "state()" } }, providers: [
3145
3146
  {
3146
3147
  provide: NG_VALUE_ACCESSOR,
3147
3148
  useExisting: PshSelectComponent,
3148
3149
  multi: true
3149
3150
  }
3150
- ], ngImport: i0, template: "<div class=\"select-container\">\n @if (label()) {\n <label class=\"select-label\" [attr.for]=\"selectId\" (click)=\"focusSelect()\" [class.required]=\"required()\">\n {{ label() }}\n @if (required()) { <span class=\"required-mark\">*</span> }\n </label>\n }\n\n <div class=\"select-trigger-wrapper\">\n <div class=\"select-trigger\"\n role=\"combobox\"\n [id]=\"selectId\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-controls]=\"selectId + '-listbox'\"\n [attr.aria-activedescendant]=\"activeDescendant()\"\n [attr.aria-label]=\"computedAriaLabel()\"\n [attr.aria-invalid]=\"!!error()\"\n [attr.aria-required]=\"required()\"\n [attr.aria-disabled]=\"disabled()\"\n [attr.aria-busy]=\"loading()\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.tabindex]=\"disabled() || loading() ? -1 : 0\"\n (keydown)=\"handleKeydown($event)\"\n (click)=\"toggle()\">\n <div class=\"select-value\">\n <span [class.placeholder]=\"!hasValue()\">\n {{ selectedLabel() }}\n </span>\n </div>\n <div class=\"select-actions\">\n @if (clearable() && hasValue() && !disabled()) {\n <button class=\"select-clear\" (click)=\"clear($event)\">\n <i class=\"ph ph-x\"></i>\n </button>\n }\n @if (loading()) {\n <div class=\"select-loader-trigger\"></div>\n } @else {\n <i class=\"ph ph-caret-down select-arrow\"></i>\n }\n </div>\n </div>\n\n @if (isOpen()) {\n <div class=\"select-dropdown\">\n @if (searchable()) {\n <div class=\"select-search\">\n <i class=\"ph ph-magnifying-glass select-search-icon\"></i>\n <input type=\"text\"\n [placeholder]=\"searchConfig().placeholder\"\n [value]=\"searchTerm()\"\n (input)=\"onSearch($event)\"\n (click)=\"$event.stopPropagation()\">\n </div>\n }\n <div class=\"select-options\"\n role=\"listbox\"\n [id]=\"selectId + '-listbox'\"\n [attr.aria-multiselectable]=\"multiple() || null\"\n (scroll)=\"onScroll($event)\">\n @for (item of filteredOptions(); track getOptionKey(item)) {\n @if (isOptionGroup(item)) {\n <div class=\"select-group\" role=\"group\" [attr.aria-label]=\"item.label\">\n <div class=\"select-group-label\">{{ item.label }}</div>\n @for (opt of item.options; track opt.label) {\n <div class=\"select-option\"\n role=\"option\"\n [id]=\"selectId + '-' + opt.value\"\n [attr.aria-selected]=\"isSelected(opt)\"\n [attr.aria-disabled]=\"(item.disabled || opt.disabled) ? true : null\"\n [attr.tabindex]=\"(item.disabled || opt.disabled) ? -1 : null\"\n [class.selected]=\"isSelected(opt)\"\n [class.disabled]=\"item.disabled || opt.disabled\"\n [class.focused]=\"getFlatIndex(opt) === focusedIndex()\"\n (click)=\"select(opt, !!item.disabled)\">\n @if (opt.icon) { <i [class]=\"'ph ph-' + opt.icon\" aria-hidden=\"true\"></i> }\n <div class=\"select-option-content\">\n <span class=\"select-option-label\">{{ opt.label }}</span>\n @if (opt.description) { <span class=\"select-option-description\">{{ opt.description }}</span> }\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"select-option\"\n role=\"option\"\n [id]=\"selectId + '-' + item.value\"\n [attr.aria-selected]=\"isSelected(item)\"\n [attr.aria-disabled]=\"item.disabled ? true : null\"\n [attr.tabindex]=\"item.disabled ? -1 : null\"\n [class.selected]=\"isSelected(item)\"\n [class.disabled]=\"item.disabled\"\n [class.focused]=\"getFlatIndex(item) === focusedIndex()\"\n (click)=\"select(item)\">\n @if (item.icon) { <i [class]=\"'ph ph-' + item.icon\" aria-hidden=\"true\"></i> }\n <div class=\"select-option-content\">\n <span class=\"select-option-label\">{{ item.label }}</span>\n @if (item.description) { <span class=\"select-option-description\">{{ item.description }}</span> }\n </div>\n </div>\n }\n } @empty {\n <div class=\"select-no-results\">Aucun r\u00E9sultat</div>\n }\n </div>\n </div>\n }\n </div>\n\n @if (error()) {\n <div id=\"error-message\" class=\"select-error-message\" role=\"alert\">{{ error() }}</div>\n }\n @if (!error() && success()) {\n <div id=\"success-message\" class=\"select-success-message\" role=\"status\">{{ success() }}</div>\n }\n @if (!error() && !success() && hint()) {\n <div id=\"hint-message\" class=\"select-hint\">{{ hint() }}</div>\n }\n</div>\n", styles: [":host{display:block;width:100%;max-width:18.75rem}:host.full-width{max-width:none}.select-container{width:100%}.select-trigger-wrapper{position:relative}.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}:host.error .select-trigger{border-color:var(--danger-color)}:host.error .select-trigger:focus{box-shadow:0 0 0 .125rem var(--focus-ring-error)}:host.success .select-trigger{border-color:var(--success-color)}:host.success .select-trigger:focus{box-shadow:0 0 0 .125rem var(--focus-ring-success)}:host.disabled .select-trigger{background:var(--surface-ground);cursor:not-allowed;opacity:var(--opacity-disabled)}.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;display:flex;align-items:flex-start;gap:.5rem}.select-option:hover{background:var(--surface-hover)}.select-option.selected{background:rgba(var(--primary-color-rgb),.1);color:var(--primary-color);font-weight:500}.select-option.focused{background:var(--surface-hover)}.select-option.disabled{opacity:var(--opacity-disabled);cursor:not-allowed}.select-option i{flex-shrink:0;line-height:1.4}.select-option-content{flex:1;min-width:0;display:flex;flex-direction:column;gap:.125rem}.select-option-label{min-width:0}.select-option-description{font-size:.75rem;color:var(--text-color-secondary)}.select-error-message,.select-success-message,.select-hint{font-size:.875rem;margin-top:.25rem}.select-error-message{color:var(--danger-color)}.select-success-message{color:var(--success-color)}.select-hint{color:var(--text-color-secondary)}:host.small .select-trigger{text-overflow:ellipsis;height:2rem;font-size:.875rem}:host.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 }); }
3151
+ ], ngImport: i0, template: "<div class=\"select-container\">\n @if (label()) {\n <label class=\"select-label\" [attr.for]=\"selectId\" (click)=\"focusSelect()\" [class.required]=\"required()\">\n {{ label() }}\n @if (required()) { <span class=\"required-mark\">*</span> }\n </label>\n }\n\n <div class=\"select-trigger-wrapper\">\n <div class=\"select-trigger\"\n role=\"combobox\"\n [id]=\"selectId\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-controls]=\"selectId + '-listbox'\"\n [attr.aria-activedescendant]=\"activeDescendant()\"\n [attr.aria-label]=\"computedAriaLabel()\"\n [attr.aria-invalid]=\"!!error()\"\n [attr.aria-required]=\"required()\"\n [attr.aria-disabled]=\"disabled()\"\n [attr.aria-busy]=\"loading()\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.tabindex]=\"disabled() || loading() ? -1 : 0\"\n (keydown)=\"handleKeydown($event)\"\n (click)=\"toggle()\">\n <div class=\"select-value\">\n <span [class.placeholder]=\"!hasValue()\">\n {{ selectedLabel() }}\n </span>\n </div>\n <div class=\"select-actions\">\n @if (clearable() && hasValue() && !disabled()) {\n <button class=\"select-clear\" (click)=\"clear($event)\">\n <i class=\"ph ph-x\"></i>\n </button>\n }\n @if (loading()) {\n <div class=\"select-loader-trigger\"></div>\n } @else {\n <i class=\"ph ph-caret-down select-arrow\"></i>\n }\n </div>\n </div>\n\n @if (isOpen()) {\n <div class=\"select-dropdown\">\n @if (searchable()) {\n <div class=\"select-search\">\n <i class=\"ph ph-magnifying-glass select-search-icon\"></i>\n <input type=\"text\"\n [placeholder]=\"searchConfig().placeholder\"\n [value]=\"searchTerm()\"\n (input)=\"onSearch($event)\"\n (click)=\"$event.stopPropagation()\">\n </div>\n }\n <div class=\"select-options\"\n role=\"listbox\"\n [id]=\"selectId + '-listbox'\"\n [attr.aria-multiselectable]=\"multiple() || null\"\n (scroll)=\"onScroll($event)\">\n @for (item of filteredOptions(); track getOptionKey(item)) {\n @if (isOptionGroup(item)) {\n <div class=\"select-group\" role=\"group\" [attr.aria-label]=\"item.label\">\n <div class=\"select-group-label\">{{ item.label }}</div>\n @for (opt of item.options; track opt.label) {\n <div class=\"select-option\"\n role=\"option\"\n [id]=\"selectId + '-' + opt.value\"\n [attr.aria-selected]=\"isSelected(opt)\"\n [attr.aria-disabled]=\"(item.disabled || opt.disabled) ? true : null\"\n [attr.tabindex]=\"(item.disabled || opt.disabled) ? -1 : null\"\n [class.selected]=\"isSelected(opt)\"\n [class.disabled]=\"item.disabled || opt.disabled\"\n [class.focused]=\"getFlatIndex(opt) === focusedIndex()\"\n (click)=\"select(opt, !!item.disabled)\">\n @if (opt.icon) { <i [class]=\"'ph ph-' + opt.icon\" aria-hidden=\"true\"></i> }\n <div class=\"select-option-content\">\n <span class=\"select-option-label\">{{ opt.label }}</span>\n @if (opt.description) { <span class=\"select-option-description\">{{ opt.description }}</span> }\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"select-option\"\n role=\"option\"\n [id]=\"selectId + '-' + item.value\"\n [attr.aria-selected]=\"isSelected(item)\"\n [attr.aria-disabled]=\"item.disabled ? true : null\"\n [attr.tabindex]=\"item.disabled ? -1 : null\"\n [class.selected]=\"isSelected(item)\"\n [class.disabled]=\"item.disabled\"\n [class.focused]=\"getFlatIndex(item) === focusedIndex()\"\n (click)=\"select(item)\">\n @if (item.icon) { <i [class]=\"'ph ph-' + item.icon\" aria-hidden=\"true\"></i> }\n <div class=\"select-option-content\">\n <span class=\"select-option-label\">{{ item.label }}</span>\n @if (item.description) { <span class=\"select-option-description\">{{ item.description }}</span> }\n </div>\n </div>\n }\n } @empty {\n <div class=\"select-no-results\">Aucun r\u00E9sultat</div>\n }\n </div>\n </div>\n }\n </div>\n\n @if (error()) {\n <div id=\"error-message\" class=\"select-error-message\" role=\"alert\">{{ error() }}</div>\n }\n @if (!error() && success()) {\n <div id=\"success-message\" class=\"select-success-message\" role=\"status\">{{ success() }}</div>\n }\n @if (!error() && !success() && hint()) {\n <div id=\"hint-message\" class=\"select-hint\">{{ hint() }}</div>\n }\n</div>\n", styles: [":host{display:block;width:100%;max-width:18.75rem}:host.full-width{max-width:none}.select-container{width:100%}.select-trigger-wrapper{position:relative}.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-0);border:.125rem 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;box-shadow:0 0 0 .125rem var(--focus-ring-color)}:host.error .select-trigger{border-color:var(--danger-color)}:host.error .select-trigger:focus{box-shadow:0 0 0 .125rem var(--focus-ring-error)}:host.success .select-trigger{border-color:var(--success-color)}:host.success .select-trigger:focus{box-shadow:0 0 0 .125rem var(--focus-ring-success)}:host.disabled .select-trigger{background:var(--surface-ground);cursor:not-allowed;opacity:var(--opacity-disabled)}:host.filled .select-trigger{background:var(--surface-ground);border:.125rem solid var(--surface-border)}:host.filled .select-trigger:hover:not([disabled]):not(:focus){background:var(--surface-hover)}.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-0);border:.125rem 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;display:flex;align-items:flex-start;gap:.5rem}.select-option:hover{background:var(--surface-hover)}.select-option.selected{background:rgba(var(--primary-color-rgb),.1);color:var(--primary-color);font-weight:500}.select-option.focused{background:var(--surface-hover)}.select-option.disabled{opacity:var(--opacity-disabled);cursor:not-allowed}.select-option i{flex-shrink:0;line-height:1.4}.select-option-content{flex:1;min-width:0;display:flex;flex-direction:column;gap:.125rem}.select-option-label{min-width:0}.select-option-description{font-size:.75rem;color:var(--text-color-secondary)}.select-error-message,.select-success-message,.select-hint{font-size:.875rem;margin-top:.25rem}.select-error-message{color:var(--danger-color)}.select-success-message{color:var(--success-color)}.select-hint{color:var(--text-color-secondary)}:host.small .select-trigger{text-overflow:ellipsis;height:2rem;font-size:.875rem}:host.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 }); }
3151
3152
  }
3152
3153
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImport: i0, type: PshSelectComponent, decorators: [{
3153
3154
  type: Component,
@@ -3161,14 +3162,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.2", ngImpor
3161
3162
  '[class.full-width]': 'fullWidth()',
3162
3163
  '[class.small]': 'size() === "small"',
3163
3164
  '[class.large]': 'size() === "large"',
3165
+ '[class.outlined]': 'variant() === "outlined"',
3166
+ '[class.filled]': 'variant() === "filled"',
3164
3167
  '[class.error]': '!!error()',
3165
3168
  '[class.success]': '!!success()',
3166
3169
  '[class.disabled]': 'disabled()',
3167
3170
  '[class.loading]': 'loading()',
3168
3171
  '[attr.aria-expanded]': 'isOpen().toString()',
3169
3172
  '[attr.data-state]': 'state()'
3170
- }, template: "<div class=\"select-container\">\n @if (label()) {\n <label class=\"select-label\" [attr.for]=\"selectId\" (click)=\"focusSelect()\" [class.required]=\"required()\">\n {{ label() }}\n @if (required()) { <span class=\"required-mark\">*</span> }\n </label>\n }\n\n <div class=\"select-trigger-wrapper\">\n <div class=\"select-trigger\"\n role=\"combobox\"\n [id]=\"selectId\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-controls]=\"selectId + '-listbox'\"\n [attr.aria-activedescendant]=\"activeDescendant()\"\n [attr.aria-label]=\"computedAriaLabel()\"\n [attr.aria-invalid]=\"!!error()\"\n [attr.aria-required]=\"required()\"\n [attr.aria-disabled]=\"disabled()\"\n [attr.aria-busy]=\"loading()\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.tabindex]=\"disabled() || loading() ? -1 : 0\"\n (keydown)=\"handleKeydown($event)\"\n (click)=\"toggle()\">\n <div class=\"select-value\">\n <span [class.placeholder]=\"!hasValue()\">\n {{ selectedLabel() }}\n </span>\n </div>\n <div class=\"select-actions\">\n @if (clearable() && hasValue() && !disabled()) {\n <button class=\"select-clear\" (click)=\"clear($event)\">\n <i class=\"ph ph-x\"></i>\n </button>\n }\n @if (loading()) {\n <div class=\"select-loader-trigger\"></div>\n } @else {\n <i class=\"ph ph-caret-down select-arrow\"></i>\n }\n </div>\n </div>\n\n @if (isOpen()) {\n <div class=\"select-dropdown\">\n @if (searchable()) {\n <div class=\"select-search\">\n <i class=\"ph ph-magnifying-glass select-search-icon\"></i>\n <input type=\"text\"\n [placeholder]=\"searchConfig().placeholder\"\n [value]=\"searchTerm()\"\n (input)=\"onSearch($event)\"\n (click)=\"$event.stopPropagation()\">\n </div>\n }\n <div class=\"select-options\"\n role=\"listbox\"\n [id]=\"selectId + '-listbox'\"\n [attr.aria-multiselectable]=\"multiple() || null\"\n (scroll)=\"onScroll($event)\">\n @for (item of filteredOptions(); track getOptionKey(item)) {\n @if (isOptionGroup(item)) {\n <div class=\"select-group\" role=\"group\" [attr.aria-label]=\"item.label\">\n <div class=\"select-group-label\">{{ item.label }}</div>\n @for (opt of item.options; track opt.label) {\n <div class=\"select-option\"\n role=\"option\"\n [id]=\"selectId + '-' + opt.value\"\n [attr.aria-selected]=\"isSelected(opt)\"\n [attr.aria-disabled]=\"(item.disabled || opt.disabled) ? true : null\"\n [attr.tabindex]=\"(item.disabled || opt.disabled) ? -1 : null\"\n [class.selected]=\"isSelected(opt)\"\n [class.disabled]=\"item.disabled || opt.disabled\"\n [class.focused]=\"getFlatIndex(opt) === focusedIndex()\"\n (click)=\"select(opt, !!item.disabled)\">\n @if (opt.icon) { <i [class]=\"'ph ph-' + opt.icon\" aria-hidden=\"true\"></i> }\n <div class=\"select-option-content\">\n <span class=\"select-option-label\">{{ opt.label }}</span>\n @if (opt.description) { <span class=\"select-option-description\">{{ opt.description }}</span> }\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"select-option\"\n role=\"option\"\n [id]=\"selectId + '-' + item.value\"\n [attr.aria-selected]=\"isSelected(item)\"\n [attr.aria-disabled]=\"item.disabled ? true : null\"\n [attr.tabindex]=\"item.disabled ? -1 : null\"\n [class.selected]=\"isSelected(item)\"\n [class.disabled]=\"item.disabled\"\n [class.focused]=\"getFlatIndex(item) === focusedIndex()\"\n (click)=\"select(item)\">\n @if (item.icon) { <i [class]=\"'ph ph-' + item.icon\" aria-hidden=\"true\"></i> }\n <div class=\"select-option-content\">\n <span class=\"select-option-label\">{{ item.label }}</span>\n @if (item.description) { <span class=\"select-option-description\">{{ item.description }}</span> }\n </div>\n </div>\n }\n } @empty {\n <div class=\"select-no-results\">Aucun r\u00E9sultat</div>\n }\n </div>\n </div>\n }\n </div>\n\n @if (error()) {\n <div id=\"error-message\" class=\"select-error-message\" role=\"alert\">{{ error() }}</div>\n }\n @if (!error() && success()) {\n <div id=\"success-message\" class=\"select-success-message\" role=\"status\">{{ success() }}</div>\n }\n @if (!error() && !success() && hint()) {\n <div id=\"hint-message\" class=\"select-hint\">{{ hint() }}</div>\n }\n</div>\n", styles: [":host{display:block;width:100%;max-width:18.75rem}:host.full-width{max-width:none}.select-container{width:100%}.select-trigger-wrapper{position:relative}.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}:host.error .select-trigger{border-color:var(--danger-color)}:host.error .select-trigger:focus{box-shadow:0 0 0 .125rem var(--focus-ring-error)}:host.success .select-trigger{border-color:var(--success-color)}:host.success .select-trigger:focus{box-shadow:0 0 0 .125rem var(--focus-ring-success)}:host.disabled .select-trigger{background:var(--surface-ground);cursor:not-allowed;opacity:var(--opacity-disabled)}.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;display:flex;align-items:flex-start;gap:.5rem}.select-option:hover{background:var(--surface-hover)}.select-option.selected{background:rgba(var(--primary-color-rgb),.1);color:var(--primary-color);font-weight:500}.select-option.focused{background:var(--surface-hover)}.select-option.disabled{opacity:var(--opacity-disabled);cursor:not-allowed}.select-option i{flex-shrink:0;line-height:1.4}.select-option-content{flex:1;min-width:0;display:flex;flex-direction:column;gap:.125rem}.select-option-label{min-width:0}.select-option-description{font-size:.75rem;color:var(--text-color-secondary)}.select-error-message,.select-success-message,.select-hint{font-size:.875rem;margin-top:.25rem}.select-error-message{color:var(--danger-color)}.select-success-message{color:var(--success-color)}.select-hint{color:var(--text-color-secondary)}:host.small .select-trigger{text-overflow:ellipsis;height:2rem;font-size:.875rem}:host.large .select-trigger{text-overflow:ellipsis;height:3rem;font-size:1.125rem}@keyframes spin{to{transform:rotate(360deg)}}\n"] }]
3171
- }], 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 }] }], success: [{ type: i0.Input, args: [{ isSignal: true, alias: "success", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", 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"] }], searched: [{ type: i0.Output, args: ["searched"] }], scrollEnd: [{ type: i0.Output, args: ["scrollEnd"] }] } });
3173
+ }, template: "<div class=\"select-container\">\n @if (label()) {\n <label class=\"select-label\" [attr.for]=\"selectId\" (click)=\"focusSelect()\" [class.required]=\"required()\">\n {{ label() }}\n @if (required()) { <span class=\"required-mark\">*</span> }\n </label>\n }\n\n <div class=\"select-trigger-wrapper\">\n <div class=\"select-trigger\"\n role=\"combobox\"\n [id]=\"selectId\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-controls]=\"selectId + '-listbox'\"\n [attr.aria-activedescendant]=\"activeDescendant()\"\n [attr.aria-label]=\"computedAriaLabel()\"\n [attr.aria-invalid]=\"!!error()\"\n [attr.aria-required]=\"required()\"\n [attr.aria-disabled]=\"disabled()\"\n [attr.aria-busy]=\"loading()\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.tabindex]=\"disabled() || loading() ? -1 : 0\"\n (keydown)=\"handleKeydown($event)\"\n (click)=\"toggle()\">\n <div class=\"select-value\">\n <span [class.placeholder]=\"!hasValue()\">\n {{ selectedLabel() }}\n </span>\n </div>\n <div class=\"select-actions\">\n @if (clearable() && hasValue() && !disabled()) {\n <button class=\"select-clear\" (click)=\"clear($event)\">\n <i class=\"ph ph-x\"></i>\n </button>\n }\n @if (loading()) {\n <div class=\"select-loader-trigger\"></div>\n } @else {\n <i class=\"ph ph-caret-down select-arrow\"></i>\n }\n </div>\n </div>\n\n @if (isOpen()) {\n <div class=\"select-dropdown\">\n @if (searchable()) {\n <div class=\"select-search\">\n <i class=\"ph ph-magnifying-glass select-search-icon\"></i>\n <input type=\"text\"\n [placeholder]=\"searchConfig().placeholder\"\n [value]=\"searchTerm()\"\n (input)=\"onSearch($event)\"\n (click)=\"$event.stopPropagation()\">\n </div>\n }\n <div class=\"select-options\"\n role=\"listbox\"\n [id]=\"selectId + '-listbox'\"\n [attr.aria-multiselectable]=\"multiple() || null\"\n (scroll)=\"onScroll($event)\">\n @for (item of filteredOptions(); track getOptionKey(item)) {\n @if (isOptionGroup(item)) {\n <div class=\"select-group\" role=\"group\" [attr.aria-label]=\"item.label\">\n <div class=\"select-group-label\">{{ item.label }}</div>\n @for (opt of item.options; track opt.label) {\n <div class=\"select-option\"\n role=\"option\"\n [id]=\"selectId + '-' + opt.value\"\n [attr.aria-selected]=\"isSelected(opt)\"\n [attr.aria-disabled]=\"(item.disabled || opt.disabled) ? true : null\"\n [attr.tabindex]=\"(item.disabled || opt.disabled) ? -1 : null\"\n [class.selected]=\"isSelected(opt)\"\n [class.disabled]=\"item.disabled || opt.disabled\"\n [class.focused]=\"getFlatIndex(opt) === focusedIndex()\"\n (click)=\"select(opt, !!item.disabled)\">\n @if (opt.icon) { <i [class]=\"'ph ph-' + opt.icon\" aria-hidden=\"true\"></i> }\n <div class=\"select-option-content\">\n <span class=\"select-option-label\">{{ opt.label }}</span>\n @if (opt.description) { <span class=\"select-option-description\">{{ opt.description }}</span> }\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"select-option\"\n role=\"option\"\n [id]=\"selectId + '-' + item.value\"\n [attr.aria-selected]=\"isSelected(item)\"\n [attr.aria-disabled]=\"item.disabled ? true : null\"\n [attr.tabindex]=\"item.disabled ? -1 : null\"\n [class.selected]=\"isSelected(item)\"\n [class.disabled]=\"item.disabled\"\n [class.focused]=\"getFlatIndex(item) === focusedIndex()\"\n (click)=\"select(item)\">\n @if (item.icon) { <i [class]=\"'ph ph-' + item.icon\" aria-hidden=\"true\"></i> }\n <div class=\"select-option-content\">\n <span class=\"select-option-label\">{{ item.label }}</span>\n @if (item.description) { <span class=\"select-option-description\">{{ item.description }}</span> }\n </div>\n </div>\n }\n } @empty {\n <div class=\"select-no-results\">Aucun r\u00E9sultat</div>\n }\n </div>\n </div>\n }\n </div>\n\n @if (error()) {\n <div id=\"error-message\" class=\"select-error-message\" role=\"alert\">{{ error() }}</div>\n }\n @if (!error() && success()) {\n <div id=\"success-message\" class=\"select-success-message\" role=\"status\">{{ success() }}</div>\n }\n @if (!error() && !success() && hint()) {\n <div id=\"hint-message\" class=\"select-hint\">{{ hint() }}</div>\n }\n</div>\n", styles: [":host{display:block;width:100%;max-width:18.75rem}:host.full-width{max-width:none}.select-container{width:100%}.select-trigger-wrapper{position:relative}.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-0);border:.125rem 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;box-shadow:0 0 0 .125rem var(--focus-ring-color)}:host.error .select-trigger{border-color:var(--danger-color)}:host.error .select-trigger:focus{box-shadow:0 0 0 .125rem var(--focus-ring-error)}:host.success .select-trigger{border-color:var(--success-color)}:host.success .select-trigger:focus{box-shadow:0 0 0 .125rem var(--focus-ring-success)}:host.disabled .select-trigger{background:var(--surface-ground);cursor:not-allowed;opacity:var(--opacity-disabled)}:host.filled .select-trigger{background:var(--surface-ground);border:.125rem solid var(--surface-border)}:host.filled .select-trigger:hover:not([disabled]):not(:focus){background:var(--surface-hover)}.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-0);border:.125rem 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;display:flex;align-items:flex-start;gap:.5rem}.select-option:hover{background:var(--surface-hover)}.select-option.selected{background:rgba(var(--primary-color-rgb),.1);color:var(--primary-color);font-weight:500}.select-option.focused{background:var(--surface-hover)}.select-option.disabled{opacity:var(--opacity-disabled);cursor:not-allowed}.select-option i{flex-shrink:0;line-height:1.4}.select-option-content{flex:1;min-width:0;display:flex;flex-direction:column;gap:.125rem}.select-option-label{min-width:0}.select-option-description{font-size:.75rem;color:var(--text-color-secondary)}.select-error-message,.select-success-message,.select-hint{font-size:.875rem;margin-top:.25rem}.select-error-message{color:var(--danger-color)}.select-success-message{color:var(--success-color)}.select-hint{color:var(--text-color-secondary)}:host.small .select-trigger{text-overflow:ellipsis;height:2rem;font-size:.875rem}:host.large .select-trigger{text-overflow:ellipsis;height:3rem;font-size:1.125rem}@keyframes spin{to{transform:rotate(360deg)}}\n"] }]
3174
+ }], 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 }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", 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 }] }], success: [{ type: i0.Input, args: [{ isSignal: true, alias: "success", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", 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"] }], searched: [{ type: i0.Output, args: ["searched"] }], scrollEnd: [{ type: i0.Output, args: ["scrollEnd"] }] } });
3172
3175
 
3173
3176
  const SIDEBAR_CONFIG = new InjectionToken('SIDEBAR_CONFIG', {
3174
3177
  factory: () => ({