ps-helix 4.0.5 → 4.0.6

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.0.5-blue.svg)](https://www.npmjs.com/package/ps-helix)
5
+ [![npm version](https://img.shields.io/badge/npm-4.0.6-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.0.5"
109
+ "ps-helix": "^4.0.6"
110
110
  }
111
111
  }
112
112
  ```
@@ -1182,7 +1182,7 @@ Copyright (c) 2025 PACK Solutions
1182
1182
 
1183
1183
  ---
1184
1184
 
1185
- **Version**: 4.0.5
1185
+ **Version**: 4.0.6
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
@@ -3304,7 +3304,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
3304
3304
  }]
3305
3305
  }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], completed: [{ type: i0.Input, args: [{ isSignal: true, alias: "completed", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], warning: [{ type: i0.Input, args: [{ isSignal: true, alias: "warning", required: false }] }], success: [{ type: i0.Input, args: [{ isSignal: true, alias: "success", required: false }] }] } });
3306
3306
 
3307
- const DEFAULT_ARIA_LABELS = {
3307
+ const DEFAULT_ARIA_LABELS$1 = {
3308
3308
  step: 'Étape',
3309
3309
  completed: 'Étape complétée',
3310
3310
  active: 'Étape active',
@@ -3315,7 +3315,7 @@ const STEPPER_CONFIG = new InjectionToken('STEPPER_CONFIG', {
3315
3315
  factory: () => ({
3316
3316
  variant: 'default',
3317
3317
  linear: true,
3318
- ariaLabels: DEFAULT_ARIA_LABELS
3318
+ ariaLabels: DEFAULT_ARIA_LABELS$1
3319
3319
  })
3320
3320
  });
3321
3321
  class PshStepperComponent {
@@ -3341,7 +3341,7 @@ class PshStepperComponent {
3341
3341
  warning: step.warning(),
3342
3342
  success: step.success()
3343
3343
  })), ...(ngDevMode ? [{ debugName: "steps" }] : []));
3344
- this.effectiveAriaLabels = computed(() => this.ariaLabels() ?? this.config.ariaLabels ?? DEFAULT_ARIA_LABELS, ...(ngDevMode ? [{ debugName: "effectiveAriaLabels" }] : []));
3344
+ this.effectiveAriaLabels = computed(() => this.ariaLabels() ?? this.config.ariaLabels ?? DEFAULT_ARIA_LABELS$1, ...(ngDevMode ? [{ debugName: "effectiveAriaLabels" }] : []));
3345
3345
  this.isFirstStep = computed(() => this.activeStep() === 0, ...(ngDevMode ? [{ debugName: "isFirstStep" }] : []));
3346
3346
  this.isLastStep = computed(() => this.activeStep() === this.steps().length - 1, ...(ngDevMode ? [{ debugName: "isLastStep" }] : []));
3347
3347
  this.progress = computed(() => this.steps().length > 0
@@ -3511,6 +3511,252 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
3511
3511
  }, template: "<div class=\"stepper-header\" role=\"tablist\">\n @for (step of steps(); track $index; let i = $index) {\n <div\n class=\"step-header\"\n [class.active]=\"i === activeStep()\"\n [class.completed]=\"step.completed\"\n [class.disabled]=\"step.disabled\"\n [class.error]=\"!!step.error\"\n [class.warning]=\"!!step.warning\"\n [class.success]=\"!!step.success\"\n >\n <div\n class=\"step-indicator\"\n role=\"tab\"\n tabindex=\"0\"\n [attr.id]=\"'step-' + i\"\n [attr.aria-selected]=\"i === activeStep()\"\n [attr.aria-disabled]=\"step.disabled\"\n [attr.aria-label]=\"getStepAriaLabel(step, i)\"\n [attr.aria-current]=\"i === activeStep() ? 'step' : null\"\n [attr.aria-describedby]=\"getStepDescribedBy(step, i)\"\n [attr.aria-busy]=\"step.loading\"\n (click)=\"handleStepClick(i)\"\n (keydown)=\"handleKeydown($event, i)\"\n >\n @if (step.loading && variant() === 'progress') {\n <i class=\"ph ph-circle-notch spinner\" aria-hidden=\"true\"></i>\n } @else if (step.completed) {\n <i class=\"ph ph-check\" aria-hidden=\"true\"></i>\n } @else if (variant() === 'numbered') {\n {{ i + 1 }}\n } @else if (step.icon) {\n <i class=\"ph ph-{{ step.icon }}\" aria-hidden=\"true\"></i>\n } @else {\n <span class=\"step-dot\"></span>\n }\n </div>\n\n <div class=\"step-label\">\n <span class=\"step-title\">{{ step.title }}</span>\n @if (step.subtitle) {\n <span class=\"step-subtitle\">{{ step.subtitle }}</span>\n }\n @if (step.error) {\n <span class=\"step-error\" [id]=\"'error-' + i\" role=\"alert\" aria-live=\"polite\">{{ step.error }}</span>\n }\n @if (step.warning) {\n <span class=\"step-warning\" [id]=\"'warning-' + i\" role=\"status\" aria-live=\"polite\">{{ step.warning }}</span>\n }\n @if (step.success) {\n <span class=\"step-success\" [id]=\"'success-' + i\" role=\"status\" aria-live=\"polite\">{{ step.success }}</span>\n }\n </div>\n\n @if (i < steps().length - 1) {\n <div class=\"step-connector\" aria-hidden=\"true\">\n <span class=\"connector-line\"></span>\n </div>\n }\n </div>\n }\n</div>\n\n<div class=\"stepper-content\">\n <ng-content />\n</div>\n", styles: [".stepper-container{display:flex;flex-direction:column;width:100%;container-type:inline-size}.stepper-header{display:flex;flex-direction:row}.step-header{display:flex;flex-direction:row;align-items:center;flex:1;min-width:0;position:relative}.step-indicator{display:flex;align-items:center;justify-content:center;width:var(--size-8);height:var(--size-8);position:relative;z-index:1;border-radius:var(--radius-full);background:var(--surface-card);border:var(--border-width-2) solid var(--surface-border);color:var(--text-color-secondary);transition:all var(--animation-duration-normal) var(--animation-easing-smooth);cursor:pointer;flex-shrink:0}.step-indicator:focus-visible{outline:var(--focus-outline-width) var(--focus-outline-style) var(--focus-outline-color);outline-offset:var(--focus-outline-offset)}.step-header.active .step-indicator{background:var(--primary-gradient);border-color:var(--primary-color);color:var(--primary-color-text)}.step-header.completed .step-indicator{background:var(--success-color);border-color:var(--success-color);color:var(--success-color-text)}.step-header.disabled .step-indicator{cursor:not-allowed;opacity:var(--opacity-disabled)}.step-header.error .step-indicator{background:color-mix(in srgb,var(--danger-color) 10%,transparent);border-color:var(--danger-color);color:var(--danger-color)}.step-header.warning .step-indicator{background:color-mix(in srgb,var(--warning-color) 10%,transparent);border-color:var(--warning-color);color:var(--warning-color)}.step-header.success:not(.completed):not(.active) .step-indicator{background:var(--surface-card);border-color:var(--success-color);border-width:var(--border-width-3);color:var(--success-color);box-shadow:0 0 0 2px color-mix(in srgb,var(--success-color) 15%,transparent)}.step-label{display:flex;flex-direction:column;margin:0 var(--spacing-md);min-width:0}.step-title{color:var(--text-color);font-weight:var(--font-weight-medium);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.step-subtitle{color:var(--text-color-secondary);font-size:var(--font-size-sm);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.step-success{color:var(--success-color);font-size:var(--font-size-sm);margin-top:var(--spacing-xs)}.step-error{color:var(--danger-color);font-size:var(--font-size-sm);margin-top:var(--spacing-xs)}.step-warning{color:var(--warning-color);font-size:var(--font-size-sm);margin-top:var(--spacing-xs)}.step-connector{flex:1;padding:0 var(--spacing-sm);display:flex;align-items:center}.connector-line{height:var(--border-width-2);background:var(--surface-border);width:100%;transition:background var(--animation-duration-normal) var(--animation-easing-smooth)}.step-header.completed .connector-line{background:var(--success-color)}.numbered .step-indicator{font-weight:var(--font-weight-semibold);font-size:var(--font-size-sm)}.progress .step-indicator{position:relative;overflow:hidden}.progress .step-indicator:after{content:\"\";position:absolute;top:0;left:0;width:100%;height:100%;background:var(--primary-color);transform:scaleX(0);transform-origin:left;transition:transform var(--animation-duration-default) var(--animation-easing-smooth)}.progress .step-header.active .step-indicator:after{transform:scaleX(1)}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.spinner{animation:spin 1s linear infinite}@media(prefers-reduced-motion:reduce){.spinner{animation:spin 2s linear infinite}}.stepper-content{flex:1;min-width:0}psh-step{display:block;animation:fadeIn var(--animation-duration-default) var(--animation-easing-smooth)}@keyframes fadeIn{0%{opacity:0;transform:translateY(var(--animation-distance-sm))}to{opacity:1;transform:translateY(0)}}@container (max-width: 768px){.stepper-header{gap:var(--spacing-xs)}.step-label{margin:0 var(--spacing-sm)}.step-title{white-space:normal;word-break:break-word;max-width:120px}.step-subtitle{white-space:normal;word-break:break-word;font-size:var(--font-size-xs)}.step-connector{padding:0 var(--spacing-xs)}}@container (max-width: 640px){.stepper-header{flex-wrap:wrap;gap:var(--spacing-md)}.step-header{flex-direction:column;align-items:center;text-align:center;gap:var(--spacing-xs);flex:0 0 auto;min-width:80px}.step-label{margin:var(--spacing-xs) 0 0 0;align-items:center}.step-title,.step-subtitle{white-space:normal;text-align:center;font-size:var(--font-size-sm);max-width:none}.step-connector{display:none}.step-indicator{width:var(--size-10);height:var(--size-10)}}@container (max-width: 480px){.step-indicator{width:var(--size-8);height:var(--size-8);font-size:var(--font-size-sm)}.step-title{font-size:var(--font-size-sm);max-width:100px}.step-subtitle{font-size:var(--font-size-xs);display:none}}\n"] }]
3512
3512
  }], ctorParameters: () => [], propDecorators: { activeStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeStep", required: false }] }, { type: i0.Output, args: ["activeStepChange"] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], linear: [{ type: i0.Input, args: [{ isSignal: true, alias: "linear", required: false }] }], ariaLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabels", required: false }] }], beforeStepChange: [{ type: i0.Input, args: [{ isSignal: true, alias: "beforeStepChange", required: false }] }], stepChange: [{ type: i0.Output, args: ["stepChange"] }], completed: [{ type: i0.Output, args: ["completed"] }], navigationError: [{ type: i0.Output, args: ["navigationError"] }], stepComponents: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => PshStepComponent), { isSignal: true }] }] } });
3513
3513
 
3514
+ class PshFlowStepComponent {
3515
+ constructor() {
3516
+ this.title = input.required(...(ngDevMode ? [{ debugName: "title" }] : []));
3517
+ this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
3518
+ this.completed = input(false, ...(ngDevMode ? [{ debugName: "completed" }] : []));
3519
+ this.loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
3520
+ this.error = input(...(ngDevMode ? [undefined, { debugName: "error" }] : []));
3521
+ this.warning = input(...(ngDevMode ? [undefined, { debugName: "warning" }] : []));
3522
+ this._index = signal(0, ...(ngDevMode ? [{ debugName: "_index" }] : []));
3523
+ this._isActive = signal(false, ...(ngDevMode ? [{ debugName: "_isActive" }] : []));
3524
+ this.index = this._index.asReadonly();
3525
+ this.isActive = this._isActive.asReadonly();
3526
+ }
3527
+ setIndex(value) {
3528
+ this._index.set(value);
3529
+ }
3530
+ setActive(value) {
3531
+ this._isActive.set(value);
3532
+ }
3533
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: PshFlowStepComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3534
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.1.5", type: PshFlowStepComponent, isStandalone: true, selector: "psh-flow-step", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, completed: { classPropertyName: "completed", publicName: "completed", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, warning: { classPropertyName: "warning", publicName: "warning", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.display": "\"none\"" } }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3535
+ }
3536
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: PshFlowStepComponent, decorators: [{
3537
+ type: Component,
3538
+ args: [{
3539
+ selector: 'psh-flow-step',
3540
+ template: '',
3541
+ changeDetection: ChangeDetectionStrategy.OnPush,
3542
+ host: {
3543
+ '[style.display]': '"none"'
3544
+ }
3545
+ }]
3546
+ }], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], completed: [{ type: i0.Input, args: [{ isSignal: true, alias: "completed", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], warning: [{ type: i0.Input, args: [{ isSignal: true, alias: "warning", required: false }] }] } });
3547
+
3548
+ const DEFAULT_ARIA_LABELS = {
3549
+ step: 'Étape',
3550
+ completed: 'Étape complétée',
3551
+ active: 'Étape active',
3552
+ incomplete: 'Étape incomplète',
3553
+ disabled: 'Étape désactivée',
3554
+ warning: 'Étape avec avertissement',
3555
+ error: 'Étape en erreur'
3556
+ };
3557
+ const STATE_FLOW_INDICATOR_CONFIG = new InjectionToken('STATE_FLOW_INDICATOR_CONFIG', {
3558
+ factory: () => ({
3559
+ linear: true,
3560
+ ariaLabels: DEFAULT_ARIA_LABELS
3561
+ })
3562
+ });
3563
+ class PshStateFlowIndicatorComponent {
3564
+ constructor() {
3565
+ this.config = inject(STATE_FLOW_INDICATOR_CONFIG);
3566
+ this.activeStep = model(0, ...(ngDevMode ? [{ debugName: "activeStep" }] : []));
3567
+ this.linear = input(this.config.linear ?? true, ...(ngDevMode ? [{ debugName: "linear" }] : []));
3568
+ this.size = input('medium', ...(ngDevMode ? [{ debugName: "size" }] : []));
3569
+ this.ariaLabels = input(...(ngDevMode ? [undefined, { debugName: "ariaLabels" }] : []));
3570
+ this.beforeStepChange = input(...(ngDevMode ? [undefined, { debugName: "beforeStepChange" }] : []));
3571
+ this.stepChange = output();
3572
+ this.completed = output();
3573
+ this.navigationError = output();
3574
+ this.stepComponents = contentChildren(PshFlowStepComponent, ...(ngDevMode ? [{ debugName: "stepComponents" }] : []));
3575
+ this.steps = computed(() => this.stepComponents().map(step => ({
3576
+ title: step.title(),
3577
+ disabled: step.disabled(),
3578
+ completed: step.completed(),
3579
+ loading: step.loading(),
3580
+ error: step.error(),
3581
+ warning: step.warning()
3582
+ })), ...(ngDevMode ? [{ debugName: "steps" }] : []));
3583
+ this.effectiveAriaLabels = computed(() => this.ariaLabels() ?? this.config.ariaLabels ?? DEFAULT_ARIA_LABELS, ...(ngDevMode ? [{ debugName: "effectiveAriaLabels" }] : []));
3584
+ this.isFirstStep = computed(() => this.activeStep() === 0, ...(ngDevMode ? [{ debugName: "isFirstStep" }] : []));
3585
+ this.isLastStep = computed(() => this.activeStep() === this.steps().length - 1, ...(ngDevMode ? [{ debugName: "isLastStep" }] : []));
3586
+ this.progress = computed(() => this.steps().length > 0
3587
+ ? ((this.activeStep() + 1) / this.steps().length) * 100
3588
+ : 0, ...(ngDevMode ? [{ debugName: "progress" }] : []));
3589
+ this.completedSteps = computed(() => this.steps().filter(step => step.completed).length, ...(ngDevMode ? [{ debugName: "completedSteps" }] : []));
3590
+ afterNextRender(() => {
3591
+ this.syncStepStates();
3592
+ });
3593
+ effect(() => {
3594
+ this.syncStepStates();
3595
+ });
3596
+ }
3597
+ syncStepStates() {
3598
+ const components = this.stepComponents();
3599
+ if (components.length === 0)
3600
+ return;
3601
+ const active = this.activeStep();
3602
+ components.forEach((step, index) => {
3603
+ step.setIndex(index);
3604
+ step.setActive(index === active);
3605
+ });
3606
+ }
3607
+ async next() {
3608
+ if (this.canGoNext()) {
3609
+ await this.goToStep(this.activeStep() + 1);
3610
+ }
3611
+ }
3612
+ async previous() {
3613
+ if (this.canGoPrevious()) {
3614
+ await this.goToStep(this.activeStep() - 1);
3615
+ }
3616
+ }
3617
+ async goToStep(index) {
3618
+ if (index < 0 || index >= this.steps().length) {
3619
+ const errorMsg = `Invalid step index: ${index}. Valid range: 0-${this.steps().length - 1}`;
3620
+ this.navigationError.emit(errorMsg);
3621
+ return;
3622
+ }
3623
+ if (index === this.activeStep()) {
3624
+ return;
3625
+ }
3626
+ const beforeChange = this.beforeStepChange();
3627
+ if (beforeChange) {
3628
+ try {
3629
+ const canChange = await Promise.resolve(beforeChange(this.activeStep(), index));
3630
+ if (!canChange) {
3631
+ this.navigationError.emit(`Navigation from step ${this.activeStep()} to step ${index} was blocked by validation`);
3632
+ return;
3633
+ }
3634
+ }
3635
+ catch (error) {
3636
+ const errorMsg = error instanceof Error ? error.message : 'Unknown error in beforeStepChange';
3637
+ this.navigationError.emit(errorMsg);
3638
+ return;
3639
+ }
3640
+ }
3641
+ if (!this.canActivateStep(index)) {
3642
+ this.navigationError.emit(`Cannot activate step ${index}. Please complete previous steps first`);
3643
+ return;
3644
+ }
3645
+ this.activeStep.set(index);
3646
+ this.stepChange.emit(index);
3647
+ const currentStep = this.steps()[index];
3648
+ if (this.isLastStep() && currentStep?.completed) {
3649
+ this.completed.emit();
3650
+ }
3651
+ }
3652
+ canGoNext() {
3653
+ const nextIndex = this.activeStep() + 1;
3654
+ return nextIndex < this.steps().length && this.canActivateStep(nextIndex);
3655
+ }
3656
+ canGoPrevious() {
3657
+ return this.activeStep() > 0;
3658
+ }
3659
+ canActivateStep(index) {
3660
+ if (index < 0 || index >= this.steps().length) {
3661
+ return false;
3662
+ }
3663
+ if (!this.linear())
3664
+ return true;
3665
+ if (index === 0)
3666
+ return true;
3667
+ const step = this.steps()[index];
3668
+ if (step?.disabled)
3669
+ return false;
3670
+ return this.steps()
3671
+ .slice(0, index)
3672
+ .every(s => s.completed && !s.error);
3673
+ }
3674
+ isStepValid(index) {
3675
+ const step = this.steps()[index];
3676
+ return step ? !!step.completed && !step.error : false;
3677
+ }
3678
+ getStepAriaLabel(step, index) {
3679
+ const labels = this.effectiveAriaLabels();
3680
+ let status;
3681
+ if (step.error) {
3682
+ status = labels.error;
3683
+ }
3684
+ else if (step.warning) {
3685
+ status = labels.warning;
3686
+ }
3687
+ else if (step.completed) {
3688
+ status = labels.completed;
3689
+ }
3690
+ else if (index === this.activeStep()) {
3691
+ status = labels.active;
3692
+ }
3693
+ else if (step.disabled) {
3694
+ status = labels.disabled;
3695
+ }
3696
+ else {
3697
+ status = labels.incomplete;
3698
+ }
3699
+ return `${labels.step} ${index + 1}: ${step.title} - ${status}`;
3700
+ }
3701
+ reset() {
3702
+ this.activeStep.set(0);
3703
+ this.stepChange.emit(0);
3704
+ }
3705
+ handleStepClick(index) {
3706
+ const step = this.steps()[index];
3707
+ if (step && !step.disabled && this.canActivateStep(index)) {
3708
+ this.goToStep(index);
3709
+ }
3710
+ }
3711
+ handleKeydown(event, index) {
3712
+ switch (event.key) {
3713
+ case 'Enter':
3714
+ case ' ':
3715
+ event.preventDefault();
3716
+ this.handleStepClick(index);
3717
+ break;
3718
+ case 'ArrowRight':
3719
+ event.preventDefault();
3720
+ if (this.canGoNext()) {
3721
+ this.next();
3722
+ }
3723
+ break;
3724
+ case 'ArrowLeft':
3725
+ event.preventDefault();
3726
+ if (this.canGoPrevious()) {
3727
+ this.previous();
3728
+ }
3729
+ break;
3730
+ case 'Home':
3731
+ event.preventDefault();
3732
+ if (this.canActivateStep(0)) {
3733
+ this.goToStep(0);
3734
+ }
3735
+ break;
3736
+ case 'End':
3737
+ event.preventDefault();
3738
+ const lastIndex = this.steps().length - 1;
3739
+ if (this.canActivateStep(lastIndex)) {
3740
+ this.goToStep(lastIndex);
3741
+ }
3742
+ break;
3743
+ }
3744
+ }
3745
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: PshStateFlowIndicatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3746
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.5", type: PshStateFlowIndicatorComponent, isStandalone: true, selector: "psh-state-flow-indicator", inputs: { activeStep: { classPropertyName: "activeStep", publicName: "activeStep", isSignal: true, isRequired: false, transformFunction: null }, linear: { classPropertyName: "linear", publicName: "linear", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, ariaLabels: { classPropertyName: "ariaLabels", publicName: "ariaLabels", isSignal: true, isRequired: false, transformFunction: null }, beforeStepChange: { classPropertyName: "beforeStepChange", publicName: "beforeStepChange", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeStep: "activeStepChange", stepChange: "stepChange", completed: "completed", navigationError: "navigationError" }, host: { properties: { "class.state-flow-indicator": "true", "class.size-small": "size() === \"small\"", "class.size-medium": "size() === \"medium\"", "class.size-large": "size() === \"large\"", "attr.role": "\"region\"", "attr.aria-label": "\"Indicateur de progression\"" } }, queries: [{ propertyName: "stepComponents", predicate: PshFlowStepComponent, isSignal: true }], ngImport: i0, template: "<div class=\"flow-track\" role=\"tablist\">\n @for (step of steps(); track $index; let i = $index) {\n <div\n class=\"flow-segment\"\n [class.active]=\"i === activeStep()\"\n [class.completed]=\"step.completed\"\n [class.disabled]=\"step.disabled || (!step.completed && i !== activeStep() && !canActivateStep(i))\"\n [class.error]=\"!!step.error\"\n [class.warning]=\"!!step.warning\"\n [class.loading]=\"step.loading\"\n [class.first]=\"i === 0\"\n [class.last]=\"i === steps().length - 1\"\n role=\"tab\"\n [attr.tabindex]=\"step.disabled ? -1 : 0\"\n [attr.id]=\"'flow-step-' + i\"\n [attr.aria-selected]=\"i === activeStep()\"\n [attr.aria-disabled]=\"step.disabled || (!step.completed && i !== activeStep() && !canActivateStep(i))\"\n [attr.aria-label]=\"getStepAriaLabel(step, i)\"\n [attr.aria-current]=\"i === activeStep() ? 'step' : null\"\n [attr.aria-busy]=\"step.loading\"\n (click)=\"handleStepClick(i)\"\n (keydown)=\"handleKeydown($event, i)\"\n >\n <span class=\"flow-segment-content\">\n @if (step.loading) {\n <i class=\"ph ph-circle-notch spinner\" aria-hidden=\"true\"></i>\n } @else if (step.error) {\n <i class=\"ph ph-x-circle\" aria-hidden=\"true\"></i>\n } @else if (step.warning) {\n <i class=\"ph ph-warning\" aria-hidden=\"true\"></i>\n } @else if (step.completed) {\n <i class=\"ph ph-check-circle\" aria-hidden=\"true\"></i>\n }\n <span class=\"flow-segment-title\">{{ step.title }}</span>\n </span>\n </div>\n }\n</div>\n", styles: [".state-flow-indicator{display:block;width:100%;container-type:inline-size}.flow-track{display:flex;flex-direction:row;width:100%}.flow-segment{flex:1;display:flex;align-items:center;justify-content:center;position:relative;background:var(--surface-200);color:var(--text-color-disabled);cursor:not-allowed;transition:background var(--animation-duration-normal) var(--animation-easing-smooth),color var(--animation-duration-normal) var(--animation-easing-smooth),opacity var(--animation-duration-normal) var(--animation-easing-smooth);clip-path:polygon(0 0,calc(100% - 14px) 0,100% 50%,calc(100% - 14px) 100%,0 100%,14px 50%);margin-left:-2px;opacity:var(--opacity-disabled)}.flow-segment.first{clip-path:polygon(0 0,calc(100% - 14px) 0,100% 50%,calc(100% - 14px) 100%,0 100%);margin-left:0;border-radius:var(--radius-lg) 0 0 var(--radius-lg)}.flow-segment.last{clip-path:polygon(0 0,100% 0,100% 100%,0 100%,14px 50%);border-radius:0 var(--radius-lg) var(--radius-lg) 0}.flow-segment.first.last{clip-path:none;border-radius:var(--radius-lg)}.flow-segment.active{background:var(--primary-gradient);color:var(--primary-color-text);cursor:default;opacity:1}.flow-segment.completed{background:var(--success-color);color:var(--success-color-text);cursor:pointer;opacity:1}.flow-segment.completed:hover{filter:brightness(1.1)}.flow-segment.warning{background:var(--warning-color);color:var(--warning-color-text);cursor:pointer;opacity:1}.flow-segment.warning:hover{filter:brightness(1.1)}.flow-segment.error{background:var(--danger-color);color:var(--danger-color-text);cursor:pointer;opacity:1}.flow-segment.error:hover{filter:brightness(1.1)}.flow-segment.loading{opacity:1;cursor:wait}.flow-segment.loading.active{background:var(--primary-gradient);color:var(--primary-color-text)}.flow-segment:focus-visible{outline:var(--focus-outline-width) var(--focus-outline-style) var(--focus-outline-color);outline-offset:var(--focus-outline-offset);z-index:1}.flow-segment-content{display:flex;align-items:center;gap:var(--spacing-xs);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding:0 var(--spacing-lg);pointer-events:none}.flow-segment-content i{flex-shrink:0;font-size:var(--icon-size-md)}.flow-segment-title{font-weight:var(--font-weight-medium);overflow:hidden;text-overflow:ellipsis}:host(.size-small) .flow-segment{height:var(--size-9)}:host(.size-small) .flow-segment-title{font-size:var(--font-size-sm)}:host(.size-small) .flow-segment-content i{font-size:var(--icon-size-sm)}:host(.size-small) .flow-segment-content{gap:var(--spacing-xxs);padding:0 var(--spacing-md)}:host(.size-medium) .flow-segment{height:var(--size-11)}:host(.size-medium) .flow-segment-title{font-size:var(--font-size-base)}:host(.size-large) .flow-segment{height:var(--size-14)}:host(.size-large) .flow-segment-title{font-size:var(--font-size-lg)}:host(.size-large) .flow-segment-content i{font-size:var(--icon-size-lg)}:host(.size-large) .flow-segment-content{gap:var(--spacing-sm);padding:0 var(--spacing-xl)}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.spinner{animation:spin 1s linear infinite}@media(prefers-reduced-motion:reduce){.spinner{animation:spin 2s linear infinite}}@container (max-width: 640px){.flow-segment-content{padding:0 var(--spacing-md)}.flow-segment-title{font-size:var(--font-size-sm)}.flow-segment-content i{font-size:var(--icon-size-sm)}}@container (max-width: 480px){.flow-track{flex-direction:column;gap:var(--spacing-xxs)}.flow-segment{clip-path:none;margin-left:0;border-radius:var(--radius-md)}.flow-segment.first,.flow-segment.last{clip-path:none;border-radius:var(--radius-md)}.flow-segment-content{justify-content:center;padding:0 var(--spacing-sm)}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3747
+ }
3748
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImport: i0, type: PshStateFlowIndicatorComponent, decorators: [{
3749
+ type: Component,
3750
+ args: [{ selector: 'psh-state-flow-indicator', changeDetection: ChangeDetectionStrategy.OnPush, host: {
3751
+ '[class.state-flow-indicator]': 'true',
3752
+ '[class.size-small]': 'size() === "small"',
3753
+ '[class.size-medium]': 'size() === "medium"',
3754
+ '[class.size-large]': 'size() === "large"',
3755
+ '[attr.role]': '"region"',
3756
+ '[attr.aria-label]': '"Indicateur de progression"'
3757
+ }, template: "<div class=\"flow-track\" role=\"tablist\">\n @for (step of steps(); track $index; let i = $index) {\n <div\n class=\"flow-segment\"\n [class.active]=\"i === activeStep()\"\n [class.completed]=\"step.completed\"\n [class.disabled]=\"step.disabled || (!step.completed && i !== activeStep() && !canActivateStep(i))\"\n [class.error]=\"!!step.error\"\n [class.warning]=\"!!step.warning\"\n [class.loading]=\"step.loading\"\n [class.first]=\"i === 0\"\n [class.last]=\"i === steps().length - 1\"\n role=\"tab\"\n [attr.tabindex]=\"step.disabled ? -1 : 0\"\n [attr.id]=\"'flow-step-' + i\"\n [attr.aria-selected]=\"i === activeStep()\"\n [attr.aria-disabled]=\"step.disabled || (!step.completed && i !== activeStep() && !canActivateStep(i))\"\n [attr.aria-label]=\"getStepAriaLabel(step, i)\"\n [attr.aria-current]=\"i === activeStep() ? 'step' : null\"\n [attr.aria-busy]=\"step.loading\"\n (click)=\"handleStepClick(i)\"\n (keydown)=\"handleKeydown($event, i)\"\n >\n <span class=\"flow-segment-content\">\n @if (step.loading) {\n <i class=\"ph ph-circle-notch spinner\" aria-hidden=\"true\"></i>\n } @else if (step.error) {\n <i class=\"ph ph-x-circle\" aria-hidden=\"true\"></i>\n } @else if (step.warning) {\n <i class=\"ph ph-warning\" aria-hidden=\"true\"></i>\n } @else if (step.completed) {\n <i class=\"ph ph-check-circle\" aria-hidden=\"true\"></i>\n }\n <span class=\"flow-segment-title\">{{ step.title }}</span>\n </span>\n </div>\n }\n</div>\n", styles: [".state-flow-indicator{display:block;width:100%;container-type:inline-size}.flow-track{display:flex;flex-direction:row;width:100%}.flow-segment{flex:1;display:flex;align-items:center;justify-content:center;position:relative;background:var(--surface-200);color:var(--text-color-disabled);cursor:not-allowed;transition:background var(--animation-duration-normal) var(--animation-easing-smooth),color var(--animation-duration-normal) var(--animation-easing-smooth),opacity var(--animation-duration-normal) var(--animation-easing-smooth);clip-path:polygon(0 0,calc(100% - 14px) 0,100% 50%,calc(100% - 14px) 100%,0 100%,14px 50%);margin-left:-2px;opacity:var(--opacity-disabled)}.flow-segment.first{clip-path:polygon(0 0,calc(100% - 14px) 0,100% 50%,calc(100% - 14px) 100%,0 100%);margin-left:0;border-radius:var(--radius-lg) 0 0 var(--radius-lg)}.flow-segment.last{clip-path:polygon(0 0,100% 0,100% 100%,0 100%,14px 50%);border-radius:0 var(--radius-lg) var(--radius-lg) 0}.flow-segment.first.last{clip-path:none;border-radius:var(--radius-lg)}.flow-segment.active{background:var(--primary-gradient);color:var(--primary-color-text);cursor:default;opacity:1}.flow-segment.completed{background:var(--success-color);color:var(--success-color-text);cursor:pointer;opacity:1}.flow-segment.completed:hover{filter:brightness(1.1)}.flow-segment.warning{background:var(--warning-color);color:var(--warning-color-text);cursor:pointer;opacity:1}.flow-segment.warning:hover{filter:brightness(1.1)}.flow-segment.error{background:var(--danger-color);color:var(--danger-color-text);cursor:pointer;opacity:1}.flow-segment.error:hover{filter:brightness(1.1)}.flow-segment.loading{opacity:1;cursor:wait}.flow-segment.loading.active{background:var(--primary-gradient);color:var(--primary-color-text)}.flow-segment:focus-visible{outline:var(--focus-outline-width) var(--focus-outline-style) var(--focus-outline-color);outline-offset:var(--focus-outline-offset);z-index:1}.flow-segment-content{display:flex;align-items:center;gap:var(--spacing-xs);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding:0 var(--spacing-lg);pointer-events:none}.flow-segment-content i{flex-shrink:0;font-size:var(--icon-size-md)}.flow-segment-title{font-weight:var(--font-weight-medium);overflow:hidden;text-overflow:ellipsis}:host(.size-small) .flow-segment{height:var(--size-9)}:host(.size-small) .flow-segment-title{font-size:var(--font-size-sm)}:host(.size-small) .flow-segment-content i{font-size:var(--icon-size-sm)}:host(.size-small) .flow-segment-content{gap:var(--spacing-xxs);padding:0 var(--spacing-md)}:host(.size-medium) .flow-segment{height:var(--size-11)}:host(.size-medium) .flow-segment-title{font-size:var(--font-size-base)}:host(.size-large) .flow-segment{height:var(--size-14)}:host(.size-large) .flow-segment-title{font-size:var(--font-size-lg)}:host(.size-large) .flow-segment-content i{font-size:var(--icon-size-lg)}:host(.size-large) .flow-segment-content{gap:var(--spacing-sm);padding:0 var(--spacing-xl)}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.spinner{animation:spin 1s linear infinite}@media(prefers-reduced-motion:reduce){.spinner{animation:spin 2s linear infinite}}@container (max-width: 640px){.flow-segment-content{padding:0 var(--spacing-md)}.flow-segment-title{font-size:var(--font-size-sm)}.flow-segment-content i{font-size:var(--icon-size-sm)}}@container (max-width: 480px){.flow-track{flex-direction:column;gap:var(--spacing-xxs)}.flow-segment{clip-path:none;margin-left:0;border-radius:var(--radius-md)}.flow-segment.first,.flow-segment.last{clip-path:none;border-radius:var(--radius-md)}.flow-segment-content{justify-content:center;padding:0 var(--spacing-sm)}}\n"] }]
3758
+ }], ctorParameters: () => [], propDecorators: { activeStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeStep", required: false }] }, { type: i0.Output, args: ["activeStepChange"] }], linear: [{ type: i0.Input, args: [{ isSignal: true, alias: "linear", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], ariaLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabels", required: false }] }], beforeStepChange: [{ type: i0.Input, args: [{ isSignal: true, alias: "beforeStepChange", required: false }] }], stepChange: [{ type: i0.Output, args: ["stepChange"] }], completed: [{ type: i0.Output, args: ["completed"] }], navigationError: [{ type: i0.Output, args: ["navigationError"] }], stepComponents: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => PshFlowStepComponent), { isSignal: true }] }] } });
3759
+
3514
3760
  const SWITCH_CONFIG = new InjectionToken('SWITCH_CONFIG', {
3515
3761
  factory: () => ({
3516
3762
  checked: false,
@@ -4500,5 +4746,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.5", ngImpor
4500
4746
  * Generated bundle index. Do not edit.
4501
4747
  */
4502
4748
 
4503
- export { CHECKBOX_CONFIG, INPUT_LABELS, INSURER_CONTEXT_SERVICE, MODAL_CONFIG, ModalService, NgxTranslateProvider, PAGINATION_CONFIG, PROGRESSBAR_CONFIG, PshAlertComponent, PshAvatarComponent, PshBadgeComponent, PshButtonComponent, PshCardComponent, PshCheckboxComponent, PshCollapseComponent, PshDropdownComponent, PshHorizontalCardComponent, PshInfoCardComponent, PshInputComponent, PshMenuComponent, PshModalComponent, PshPaginationComponent, PshProgressbarComponent, PshRadioComponent, PshSelectComponent, PshSidebarComponent, PshSpinLoaderComponent, PshStatCardComponent, PshStepComponent, PshStepperComponent, PshSwitchComponent, PshTabBarComponent, PshTabComponent, PshTableComponent, PshTabsComponent, PshTagComponent, PshToastComponent, PshToastService, PshTooltipComponent, RADIO_CONFIG, RADIO_STYLES, SIDEBAR_CONFIG, SPINLOADER_CONFIG, STEPPER_CONFIG, SWITCH_CONFIG, ScrollService, TABLE_CONFIG, TABS_CONFIG, TAB_BAR_CONFIG, TAG_CONFIG, TOAST_CONFIG, TOOLTIP_CONFIG, TRANSLATION_PROVIDER, ThemeService, ToastComponent, ToastService, provideTranslation };
4749
+ export { CHECKBOX_CONFIG, INPUT_LABELS, INSURER_CONTEXT_SERVICE, MODAL_CONFIG, ModalService, NgxTranslateProvider, PAGINATION_CONFIG, PROGRESSBAR_CONFIG, PshAlertComponent, PshAvatarComponent, PshBadgeComponent, PshButtonComponent, PshCardComponent, PshCheckboxComponent, PshCollapseComponent, PshDropdownComponent, PshFlowStepComponent, PshHorizontalCardComponent, PshInfoCardComponent, PshInputComponent, PshMenuComponent, PshModalComponent, PshPaginationComponent, PshProgressbarComponent, PshRadioComponent, PshSelectComponent, PshSidebarComponent, PshSpinLoaderComponent, PshStatCardComponent, PshStateFlowIndicatorComponent, PshStepComponent, PshStepperComponent, PshSwitchComponent, PshTabBarComponent, PshTabComponent, PshTableComponent, PshTabsComponent, PshTagComponent, PshToastComponent, PshToastService, PshTooltipComponent, RADIO_CONFIG, RADIO_STYLES, SIDEBAR_CONFIG, SPINLOADER_CONFIG, STATE_FLOW_INDICATOR_CONFIG, STEPPER_CONFIG, SWITCH_CONFIG, ScrollService, TABLE_CONFIG, TABS_CONFIG, TAB_BAR_CONFIG, TAG_CONFIG, TOAST_CONFIG, TOOLTIP_CONFIG, TRANSLATION_PROVIDER, ThemeService, ToastComponent, ToastService, provideTranslation };
4504
4750
  //# sourceMappingURL=ps-helix.mjs.map