@eui/ecl 15.0.0-rc.13 → 15.0.0-rc.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/docs/components/EclCarouselComponent.html +138 -1
  2. package/docs/components/EclMultiselectComponent.html +1 -0
  3. package/docs/components/EclRadioLabelComponent.html +1 -1
  4. package/docs/dependencies.html +2 -2
  5. package/docs/directives/EclRadioDirective.html +1 -2
  6. package/docs/injectables/EclDefaultLanguageService.html +1 -1
  7. package/docs/js/search/search_index.js +2 -2
  8. package/docs/miscellaneous/enumerations.html +34 -4
  9. package/esm2020/lib/components/ecl-carousel/ecl-carousel.component.mjs +52 -23
  10. package/esm2020/lib/components/ecl-multiselect/ecl-multiselect.component.mjs +238 -45
  11. package/esm2020/lib/components/ecl-radio/ecl-radio-label.component.mjs +3 -3
  12. package/esm2020/lib/components/ecl-radio/ecl-radio.directive.mjs +7 -10
  13. package/esm2020/lib/components/ecl-select/ecl-select.directive.mjs +3 -4
  14. package/esm2020/lib/services/ecl-default-language.service.mjs +3 -3
  15. package/fesm2015/eui-ecl.mjs +319 -100
  16. package/fesm2015/eui-ecl.mjs.map +1 -1
  17. package/fesm2020/eui-ecl.mjs +318 -100
  18. package/fesm2020/eui-ecl.mjs.map +1 -1
  19. package/lib/components/ecl-carousel/ecl-carousel.component.d.ts +13 -4
  20. package/lib/components/ecl-carousel/ecl-carousel.component.d.ts.map +1 -1
  21. package/lib/components/ecl-multiselect/ecl-multiselect.component.d.ts +29 -5
  22. package/lib/components/ecl-multiselect/ecl-multiselect.component.d.ts.map +1 -1
  23. package/lib/components/ecl-radio/ecl-radio.directive.d.ts +5 -6
  24. package/lib/components/ecl-radio/ecl-radio.directive.d.ts.map +1 -1
  25. package/lib/components/ecl-select/ecl-select.directive.d.ts.map +1 -1
  26. package/lib/services/ecl-default-language.service.d.ts.map +1 -1
  27. package/package.json +1 -1
@@ -8,7 +8,7 @@ import { __decorate } from 'tslib';
8
8
  import { coerceBoolean, coerceElement, coerceNumber, coerceArray, DefaultConfig, EuiPagination } from '@eui/base';
9
9
  import * as i2$1 from '@eui/core';
10
10
  import { GLOBAL_CONFIG_TOKEN } from '@eui/core';
11
- import { Subject, takeUntil, interval, delay, fromEvent, of } from 'rxjs';
11
+ import { ReplaySubject, Subject, takeUntil, switchMap, interval, delay, fromEvent, of } from 'rxjs';
12
12
  import { takeUntil as takeUntil$1, mergeWith } from 'rxjs/operators';
13
13
  import * as i1$1 from '@angular/forms';
14
14
  import { NG_VALUE_ACCESSOR, ReactiveFormsModule, FormsModule } from '@angular/forms';
@@ -546,7 +546,7 @@ class EclDefaultLanguageService {
546
546
  constructor(config, i18nService) {
547
547
  this.config = config;
548
548
  this.i18nService = i18nService;
549
- this.currentLanguage$ = new Subject();
549
+ this.currentLanguage$ = new ReplaySubject();
550
550
  this.FALLBACK_LANGUAGE = { code: 'en', label: 'English' };
551
551
  this.destroy$ = new Subject();
552
552
  this.handleActiveLanguageChangeState();
@@ -3948,6 +3948,9 @@ class EclCarouselComponent extends ECLBaseDirective {
3948
3948
  this.playInterval = 5000;
3949
3949
  this.slide = new EventEmitter();
3950
3950
  this.isPlaying = false;
3951
+ this.isPaused = false;
3952
+ this.playSubject = new Subject();
3953
+ this.stopSubject = new Subject();
3951
3954
  this.isMobileBreakpoint = false;
3952
3955
  this.destroy$ = new Subject();
3953
3956
  }
@@ -3956,6 +3959,9 @@ class EclCarouselComponent extends ECLBaseDirective {
3956
3959
  super.getCssClasses('ecl-carousel')
3957
3960
  ].join(' ').trim();
3958
3961
  }
3962
+ ngOnInit() {
3963
+ this.initAutoplay();
3964
+ }
3959
3965
  ngAfterContentInit() {
3960
3966
  this.observeBreakpointChanges();
3961
3967
  this.initializeSlider();
@@ -3986,6 +3992,15 @@ class EclCarouselComponent extends ECLBaseDirective {
3986
3992
  this.stopPlaying();
3987
3993
  this.goToPreviousSlide();
3988
3994
  }
3995
+ onSlideHover() {
3996
+ this.pausePlaying();
3997
+ }
3998
+ onSlideHoverout() {
3999
+ this.resumePlaying();
4000
+ }
4001
+ isPlayingState() {
4002
+ return this.isPlaying && !this.isPaused;
4003
+ }
3989
4004
  isPadded() {
3990
4005
  return !this.isMobileBreakpoint;
3991
4006
  }
@@ -4009,29 +4024,32 @@ class EclCarouselComponent extends ECLBaseDirective {
4009
4024
  var _a;
4010
4025
  return -1 * ((_a = this.carouselContainerElement) === null || _a === void 0 ? void 0 : _a.offsetWidth) * this.getCurrentSlideIndex();
4011
4026
  }
4027
+ initAutoplay() {
4028
+ const start$ = this.playSubject.asObservable();
4029
+ const stop$ = this.stopSubject.asObservable();
4030
+ start$.pipe(switchMap(() => interval(this.playInterval)
4031
+ .pipe(takeUntil(stop$))), takeUntil(this.destroy$)).subscribe(() => {
4032
+ this.goToNextSlide();
4033
+ });
4034
+ }
4012
4035
  initializeSlider() {
4013
4036
  this.slides.forEach((item, idx) => {
4014
- item.index = idx;
4015
- item.ariaLabel = `slide ${idx + 1} of ${this.getSlidesCount()}`;
4016
- item.width = 100 / this.getSlidesCount();
4037
+ this.initSlide(item, idx);
4017
4038
  });
4018
4039
  if (this.hasControls) {
4019
- this.playInterval$ = interval(this.playInterval);
4020
4040
  if (this.isNoSlideSelected()) {
4021
4041
  this.activateSlide(this.slides.first);
4022
4042
  }
4023
- if (this.isAutoplay) {
4043
+ if (this.isAutoplay && !this.isMobileBreakpoint) {
4024
4044
  this.startPlaying();
4025
4045
  }
4026
- this.slides.forEach(item => {
4027
- item.slideClick
4028
- .pipe(takeUntil(this.destroy$))
4029
- .subscribe(() => {
4030
- this.stopPlaying();
4031
- });
4032
- });
4033
4046
  }
4034
4047
  }
4048
+ initSlide(item, idx) {
4049
+ item.index = idx;
4050
+ item.ariaLabel = `slide ${idx + 1} of ${this.getSlidesCount()}`;
4051
+ item.width = 100 / this.getSlidesCount();
4052
+ }
4035
4053
  goToNextSlide() {
4036
4054
  this.activateSlide(this.getNextSlide());
4037
4055
  }
@@ -4049,16 +4067,24 @@ class EclCarouselComponent extends ECLBaseDirective {
4049
4067
  }
4050
4068
  startPlaying() {
4051
4069
  this.isPlaying = true;
4052
- this.playIntervalSubscription = this.playInterval$
4053
- .pipe(takeUntil(this.destroy$))
4054
- .subscribe(n => {
4055
- this.goToNextSlide();
4056
- });
4070
+ this.isPaused = false;
4071
+ this.playSubject.next();
4057
4072
  }
4058
4073
  stopPlaying() {
4059
4074
  this.isPlaying = false;
4060
- if (this.playIntervalSubscription) {
4061
- this.playIntervalSubscription.unsubscribe();
4075
+ this.isPaused = true;
4076
+ this.stopSubject.next();
4077
+ }
4078
+ pausePlaying() {
4079
+ if (this.isPlaying) {
4080
+ this.isPaused = true;
4081
+ this.stopSubject.next();
4082
+ }
4083
+ }
4084
+ resumePlaying() {
4085
+ if (this.isPlaying) {
4086
+ this.isPaused = false;
4087
+ this.playSubject.next();
4062
4088
  }
4063
4089
  }
4064
4090
  getNextSlide() {
@@ -4093,6 +4119,9 @@ class EclCarouselComponent extends ECLBaseDirective {
4093
4119
  .pipe(takeUntil(this.destroy$))
4094
4120
  .subscribe(result => {
4095
4121
  this.isMobileBreakpoint = result.matches;
4122
+ if (this.isMobileBreakpoint) {
4123
+ this.stopPlaying();
4124
+ }
4096
4125
  });
4097
4126
  }
4098
4127
  observeElementSizeChanges() {
@@ -4102,7 +4131,7 @@ class EclCarouselComponent extends ECLBaseDirective {
4102
4131
  }
4103
4132
  }
4104
4133
  /** @nocollapse */ EclCarouselComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: EclCarouselComponent, deps: [{ token: i0.Renderer2 }, { token: i1$2.BreakpointObserver }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4105
- /** @nocollapse */ EclCarouselComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.0", type: EclCarouselComponent, selector: "ecl-carousel", inputs: { isAutoplay: "isAutoplay", playInterval: "playInterval" }, outputs: { slide: "slide" }, host: { properties: { "class": "this.cssClasses" } }, queries: [{ propertyName: "slides", predicate: i0.forwardRef(function () { return EclCarouselItemComponent; }) }], viewQueries: [{ propertyName: "carouselContainerElement", first: true, predicate: ["carouselContainer"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div #carouselContainer \n class=\"ecl-carousel__container\" \n [class.ecl-carousel-container--padded]=\"isPadded()\">\n <div class=\"ecl-carousel__slides\"\n [style.width.px]=\"getCarouselSlidesWidth()\" \n [style.left.px]=\"getCarouselSlidesOffset()\">\n <ng-content></ng-content>\n </div>\n\n <button *ngIf=\"hasControls() && !isMobileBreakpoint\"\n class=\"ecl-carousel__prev\" \n (click)=\"onPreviousSlideClick()\">\n <ecl-icon \n icon=\"corner-arrow\" \n size=\"m\" \n transform=\"rotate-270\" \n isInverted \n class=\"ecl-carousel__icon-default\">\n </ecl-icon>\n <span class=\"ecl-u-sr-only\">{{ 'ecl.carousel.PREV-SLIDES' | translate }}</span>\n </button>\n\n <button *ngIf=\"hasControls() && !isMobileBreakpoint\"\n class=\"ecl-carousel__next\" \n (click)=\"onNextSlideClick()\">\n <ecl-icon \n icon=\"corner-arrow\" \n size=\"m\" \n transform=\"rotate-90\" \n isInverted \n class=\"ecl-carousel__icon-default\">\n </ecl-icon>\n <div class=\"ecl-u-sr-only\">{{ 'ecl.carousel.NEXT-SLIDES' | translate }}</div>\n </button>\n</div>\n\n<div *ngIf=\"hasControls()\" \n class=\"ecl-carousel__controls\">\n <div class=\"ecl-container\">\n <div class=\"ecl-carousel__autoplay\">\n <button *ngIf=\"!isPlaying\" \n class=\"ecl-carousel__play\"\n (click)=\"onPlayClick()\">\n <ecl-icon \n icon=\"play\" \n size=\"l\" \n class=\"ecl-carousel__icon-default\"\n isInverted>\n </ecl-icon>\n <ecl-icon \n icon=\"play-filled\" \n size=\"l\" \n class=\"ecl-carousel__icon-active\"\n isInverted>\n </ecl-icon>\n <div class=\"ecl-u-sr-only\">{{ 'ecl.carousel.AUTOPLAY' | translate }}</div>\n </button>\n <button *ngIf=\"isPlaying\" \n class=\"ecl-carousel__pause\"\n (click)=\"onPauseClick()\">\n <ecl-icon \n icon=\"pause\" \n size=\"l\" \n class=\"ecl-carousel__icon-default\"\n isInverted>\n </ecl-icon>\n <ecl-icon \n icon=\"pause-filled\" \n size=\"l\" \n class=\"ecl-carousel__icon-active\"\n isInverted>\n </ecl-icon>\n <div class=\"ecl-u-sr-only\">{{ 'ecl.carousel.PAUSE' | translate }}</div>\n </button>\n </div>\n\n <div class=\"ecl-carousel__navigation\">\n <button \n *ngFor=\"let slide of slides; let i = index\" \n [attr.aria-current]=\"slide.isCurrent\"\n class=\"ecl-carousel__navigation-item\"\n (click)=\"onSlideControlClick(slide)\">\n <span class=\"ecl-u-sr-only\">{{ 'ecl.carousel.GO-TO-SLIDE' | translate }} {{ i + 1 }}</span>\n </button>\n </div>\n\n <button *ngIf=\"isMobileBreakpoint\"\n class=\"ecl-carousel__prev\" \n (click)=\"onPreviousSlideClick()\">\n <ecl-icon \n icon=\"corner-arrow\" \n size=\"m\" \n transform=\"rotate-270\" \n isInverted \n class=\"ecl-carousel__icon-default\">\n </ecl-icon>\n <span class=\"ecl-u-sr-only\">{{ 'ecl.carousel.PREV-SLIDES' | translate }}</span>\n </button>\n \n <div class=\"ecl-carousel__pagination\">\n <span class=\"ecl-carousel__current\">{{ getCurrentSlideIndex() + 1 }}</span>\n {{ 'ecl.common.OF' | translate }}\n <span class=\"ecl-carousel__max\">{{ slides.length }}</span>\n </div>\n\n <button *ngIf=\"isMobileBreakpoint\"\n class=\"ecl-carousel__next\" \n (click)=\"onNextSlideClick()\">\n <ecl-icon \n icon=\"corner-arrow\" \n size=\"m\" \n transform=\"rotate-90\" \n isInverted \n class=\"ecl-carousel__icon-default\">\n </ecl-icon>\n <div class=\"ecl-u-sr-only\">{{ 'ecl.carousel.NEXT-SLIDES' | translate }}</div>\n </button>\n </div>\n</div>", styles: [":host{display:block}.ecl-carousel__container{width:100%}.ecl-carousel__slides{transition-duration:.4s}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: EclIconComponent, selector: "ecl-icon", inputs: ["iconSet", "icon", "size", "color", "transform", "ariaLabelledby", "role", "isInverted", "ariaHidden", "focusable"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] });
4134
+ /** @nocollapse */ EclCarouselComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.0", type: EclCarouselComponent, selector: "ecl-carousel", inputs: { isAutoplay: "isAutoplay", playInterval: "playInterval" }, outputs: { slide: "slide" }, host: { properties: { "class": "this.cssClasses" } }, queries: [{ propertyName: "slides", predicate: i0.forwardRef(function () { return EclCarouselItemComponent; }) }], viewQueries: [{ propertyName: "carouselContainerElement", first: true, predicate: ["carouselContainer"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<div #carouselContainer \n class=\"ecl-carousel__container\" \n [class.ecl-carousel-container--padded]=\"isPadded()\">\n <div class=\"ecl-carousel__slides\"\n [style.width.px]=\"getCarouselSlidesWidth()\" \n [style.left.px]=\"getCarouselSlidesOffset()\"\n (mouseover)=\"onSlideHover()\"\n (mouseout)=\"onSlideHoverout()\">\n <ng-content></ng-content>\n </div>\n\n <button *ngIf=\"hasControls() && !isMobileBreakpoint\"\n class=\"ecl-carousel__prev\" \n (click)=\"onPreviousSlideClick()\">\n <ecl-icon \n icon=\"corner-arrow\" \n size=\"m\" \n transform=\"rotate-270\" \n isInverted \n class=\"ecl-carousel__icon-default\">\n </ecl-icon>\n <span class=\"ecl-u-sr-only\">{{ 'ecl.carousel.PREV-SLIDES' | translate }}</span>\n </button>\n\n <button *ngIf=\"hasControls() && !isMobileBreakpoint\"\n class=\"ecl-carousel__next\" \n (click)=\"onNextSlideClick()\">\n <ecl-icon \n icon=\"corner-arrow\" \n size=\"m\" \n transform=\"rotate-90\" \n isInverted \n class=\"ecl-carousel__icon-default\">\n </ecl-icon>\n <div class=\"ecl-u-sr-only\">{{ 'ecl.carousel.NEXT-SLIDES' | translate }}</div>\n </button>\n</div>\n\n<div *ngIf=\"hasControls()\" \n class=\"ecl-carousel__controls\">\n <div class=\"ecl-container\">\n <div class=\"ecl-carousel__autoplay\">\n <button *ngIf=\"!isPlayingState()\" \n class=\"ecl-carousel__play\"\n (click)=\"onPlayClick()\">\n <ecl-icon \n icon=\"play\" \n size=\"l\" \n class=\"ecl-carousel__icon-default\"\n isInverted>\n </ecl-icon>\n <ecl-icon \n icon=\"play-filled\" \n size=\"l\" \n class=\"ecl-carousel__icon-active\"\n isInverted>\n </ecl-icon>\n <div class=\"ecl-u-sr-only\">{{ 'ecl.carousel.AUTOPLAY' | translate }}</div>\n </button>\n <button *ngIf=\"isPlayingState()\" \n class=\"ecl-carousel__pause\"\n (click)=\"onPauseClick()\">\n <ecl-icon \n icon=\"pause\" \n size=\"l\" \n class=\"ecl-carousel__icon-default\"\n isInverted>\n </ecl-icon>\n <ecl-icon \n icon=\"pause-filled\" \n size=\"l\" \n class=\"ecl-carousel__icon-active\"\n isInverted>\n </ecl-icon>\n <div class=\"ecl-u-sr-only\">{{ 'ecl.carousel.PAUSE' | translate }}</div>\n </button>\n </div>\n\n <div class=\"ecl-carousel__navigation\">\n <button \n *ngFor=\"let slide of slides; let i = index\" \n [attr.aria-current]=\"slide.isCurrent\"\n class=\"ecl-carousel__navigation-item\"\n (click)=\"onSlideControlClick(slide)\">\n <span class=\"ecl-u-sr-only\">{{ 'ecl.carousel.GO-TO-SLIDE' | translate }} {{ i + 1 }}</span>\n </button>\n </div>\n\n <button *ngIf=\"isMobileBreakpoint\"\n class=\"ecl-carousel__prev\" \n (click)=\"onPreviousSlideClick()\">\n <ecl-icon \n icon=\"corner-arrow\" \n size=\"m\" \n transform=\"rotate-270\" \n isInverted \n class=\"ecl-carousel__icon-default\">\n </ecl-icon>\n <span class=\"ecl-u-sr-only\">{{ 'ecl.carousel.PREV-SLIDES' | translate }}</span>\n </button>\n \n <div class=\"ecl-carousel__pagination\">\n <span class=\"ecl-carousel__current\">{{ getCurrentSlideIndex() + 1 }}</span>\n {{ 'ecl.common.OF' | translate }}\n <span class=\"ecl-carousel__max\">{{ slides.length }}</span>\n </div>\n\n <button *ngIf=\"isMobileBreakpoint\"\n class=\"ecl-carousel__next\" \n (click)=\"onNextSlideClick()\">\n <ecl-icon \n icon=\"corner-arrow\" \n size=\"m\" \n transform=\"rotate-90\" \n isInverted \n class=\"ecl-carousel__icon-default\">\n </ecl-icon>\n <div class=\"ecl-u-sr-only\">{{ 'ecl.carousel.NEXT-SLIDES' | translate }}</div>\n </button>\n </div>\n</div>", styles: [":host{display:block}.ecl-carousel__container{width:100%}.ecl-carousel__slides{transition-duration:.4s}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: EclIconComponent, selector: "ecl-icon", inputs: ["iconSet", "icon", "size", "color", "transform", "ariaLabelledby", "role", "isInverted", "ariaHidden", "focusable"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }] });
4106
4135
  __decorate([
4107
4136
  coerceBoolean
4108
4137
  ], EclCarouselComponent.prototype, "isAutoplay", void 0);
@@ -4114,7 +4143,7 @@ __decorate([
4114
4143
  ], EclCarouselComponent.prototype, "carouselContainerElement", void 0);
4115
4144
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: EclCarouselComponent, decorators: [{
4116
4145
  type: Component,
4117
- args: [{ selector: 'ecl-carousel', template: "<div #carouselContainer \n class=\"ecl-carousel__container\" \n [class.ecl-carousel-container--padded]=\"isPadded()\">\n <div class=\"ecl-carousel__slides\"\n [style.width.px]=\"getCarouselSlidesWidth()\" \n [style.left.px]=\"getCarouselSlidesOffset()\">\n <ng-content></ng-content>\n </div>\n\n <button *ngIf=\"hasControls() && !isMobileBreakpoint\"\n class=\"ecl-carousel__prev\" \n (click)=\"onPreviousSlideClick()\">\n <ecl-icon \n icon=\"corner-arrow\" \n size=\"m\" \n transform=\"rotate-270\" \n isInverted \n class=\"ecl-carousel__icon-default\">\n </ecl-icon>\n <span class=\"ecl-u-sr-only\">{{ 'ecl.carousel.PREV-SLIDES' | translate }}</span>\n </button>\n\n <button *ngIf=\"hasControls() && !isMobileBreakpoint\"\n class=\"ecl-carousel__next\" \n (click)=\"onNextSlideClick()\">\n <ecl-icon \n icon=\"corner-arrow\" \n size=\"m\" \n transform=\"rotate-90\" \n isInverted \n class=\"ecl-carousel__icon-default\">\n </ecl-icon>\n <div class=\"ecl-u-sr-only\">{{ 'ecl.carousel.NEXT-SLIDES' | translate }}</div>\n </button>\n</div>\n\n<div *ngIf=\"hasControls()\" \n class=\"ecl-carousel__controls\">\n <div class=\"ecl-container\">\n <div class=\"ecl-carousel__autoplay\">\n <button *ngIf=\"!isPlaying\" \n class=\"ecl-carousel__play\"\n (click)=\"onPlayClick()\">\n <ecl-icon \n icon=\"play\" \n size=\"l\" \n class=\"ecl-carousel__icon-default\"\n isInverted>\n </ecl-icon>\n <ecl-icon \n icon=\"play-filled\" \n size=\"l\" \n class=\"ecl-carousel__icon-active\"\n isInverted>\n </ecl-icon>\n <div class=\"ecl-u-sr-only\">{{ 'ecl.carousel.AUTOPLAY' | translate }}</div>\n </button>\n <button *ngIf=\"isPlaying\" \n class=\"ecl-carousel__pause\"\n (click)=\"onPauseClick()\">\n <ecl-icon \n icon=\"pause\" \n size=\"l\" \n class=\"ecl-carousel__icon-default\"\n isInverted>\n </ecl-icon>\n <ecl-icon \n icon=\"pause-filled\" \n size=\"l\" \n class=\"ecl-carousel__icon-active\"\n isInverted>\n </ecl-icon>\n <div class=\"ecl-u-sr-only\">{{ 'ecl.carousel.PAUSE' | translate }}</div>\n </button>\n </div>\n\n <div class=\"ecl-carousel__navigation\">\n <button \n *ngFor=\"let slide of slides; let i = index\" \n [attr.aria-current]=\"slide.isCurrent\"\n class=\"ecl-carousel__navigation-item\"\n (click)=\"onSlideControlClick(slide)\">\n <span class=\"ecl-u-sr-only\">{{ 'ecl.carousel.GO-TO-SLIDE' | translate }} {{ i + 1 }}</span>\n </button>\n </div>\n\n <button *ngIf=\"isMobileBreakpoint\"\n class=\"ecl-carousel__prev\" \n (click)=\"onPreviousSlideClick()\">\n <ecl-icon \n icon=\"corner-arrow\" \n size=\"m\" \n transform=\"rotate-270\" \n isInverted \n class=\"ecl-carousel__icon-default\">\n </ecl-icon>\n <span class=\"ecl-u-sr-only\">{{ 'ecl.carousel.PREV-SLIDES' | translate }}</span>\n </button>\n \n <div class=\"ecl-carousel__pagination\">\n <span class=\"ecl-carousel__current\">{{ getCurrentSlideIndex() + 1 }}</span>\n {{ 'ecl.common.OF' | translate }}\n <span class=\"ecl-carousel__max\">{{ slides.length }}</span>\n </div>\n\n <button *ngIf=\"isMobileBreakpoint\"\n class=\"ecl-carousel__next\" \n (click)=\"onNextSlideClick()\">\n <ecl-icon \n icon=\"corner-arrow\" \n size=\"m\" \n transform=\"rotate-90\" \n isInverted \n class=\"ecl-carousel__icon-default\">\n </ecl-icon>\n <div class=\"ecl-u-sr-only\">{{ 'ecl.carousel.NEXT-SLIDES' | translate }}</div>\n </button>\n </div>\n</div>", styles: [":host{display:block}.ecl-carousel__container{width:100%}.ecl-carousel__slides{transition-duration:.4s}\n"] }]
4146
+ args: [{ selector: 'ecl-carousel', template: "<div #carouselContainer \n class=\"ecl-carousel__container\" \n [class.ecl-carousel-container--padded]=\"isPadded()\">\n <div class=\"ecl-carousel__slides\"\n [style.width.px]=\"getCarouselSlidesWidth()\" \n [style.left.px]=\"getCarouselSlidesOffset()\"\n (mouseover)=\"onSlideHover()\"\n (mouseout)=\"onSlideHoverout()\">\n <ng-content></ng-content>\n </div>\n\n <button *ngIf=\"hasControls() && !isMobileBreakpoint\"\n class=\"ecl-carousel__prev\" \n (click)=\"onPreviousSlideClick()\">\n <ecl-icon \n icon=\"corner-arrow\" \n size=\"m\" \n transform=\"rotate-270\" \n isInverted \n class=\"ecl-carousel__icon-default\">\n </ecl-icon>\n <span class=\"ecl-u-sr-only\">{{ 'ecl.carousel.PREV-SLIDES' | translate }}</span>\n </button>\n\n <button *ngIf=\"hasControls() && !isMobileBreakpoint\"\n class=\"ecl-carousel__next\" \n (click)=\"onNextSlideClick()\">\n <ecl-icon \n icon=\"corner-arrow\" \n size=\"m\" \n transform=\"rotate-90\" \n isInverted \n class=\"ecl-carousel__icon-default\">\n </ecl-icon>\n <div class=\"ecl-u-sr-only\">{{ 'ecl.carousel.NEXT-SLIDES' | translate }}</div>\n </button>\n</div>\n\n<div *ngIf=\"hasControls()\" \n class=\"ecl-carousel__controls\">\n <div class=\"ecl-container\">\n <div class=\"ecl-carousel__autoplay\">\n <button *ngIf=\"!isPlayingState()\" \n class=\"ecl-carousel__play\"\n (click)=\"onPlayClick()\">\n <ecl-icon \n icon=\"play\" \n size=\"l\" \n class=\"ecl-carousel__icon-default\"\n isInverted>\n </ecl-icon>\n <ecl-icon \n icon=\"play-filled\" \n size=\"l\" \n class=\"ecl-carousel__icon-active\"\n isInverted>\n </ecl-icon>\n <div class=\"ecl-u-sr-only\">{{ 'ecl.carousel.AUTOPLAY' | translate }}</div>\n </button>\n <button *ngIf=\"isPlayingState()\" \n class=\"ecl-carousel__pause\"\n (click)=\"onPauseClick()\">\n <ecl-icon \n icon=\"pause\" \n size=\"l\" \n class=\"ecl-carousel__icon-default\"\n isInverted>\n </ecl-icon>\n <ecl-icon \n icon=\"pause-filled\" \n size=\"l\" \n class=\"ecl-carousel__icon-active\"\n isInverted>\n </ecl-icon>\n <div class=\"ecl-u-sr-only\">{{ 'ecl.carousel.PAUSE' | translate }}</div>\n </button>\n </div>\n\n <div class=\"ecl-carousel__navigation\">\n <button \n *ngFor=\"let slide of slides; let i = index\" \n [attr.aria-current]=\"slide.isCurrent\"\n class=\"ecl-carousel__navigation-item\"\n (click)=\"onSlideControlClick(slide)\">\n <span class=\"ecl-u-sr-only\">{{ 'ecl.carousel.GO-TO-SLIDE' | translate }} {{ i + 1 }}</span>\n </button>\n </div>\n\n <button *ngIf=\"isMobileBreakpoint\"\n class=\"ecl-carousel__prev\" \n (click)=\"onPreviousSlideClick()\">\n <ecl-icon \n icon=\"corner-arrow\" \n size=\"m\" \n transform=\"rotate-270\" \n isInverted \n class=\"ecl-carousel__icon-default\">\n </ecl-icon>\n <span class=\"ecl-u-sr-only\">{{ 'ecl.carousel.PREV-SLIDES' | translate }}</span>\n </button>\n \n <div class=\"ecl-carousel__pagination\">\n <span class=\"ecl-carousel__current\">{{ getCurrentSlideIndex() + 1 }}</span>\n {{ 'ecl.common.OF' | translate }}\n <span class=\"ecl-carousel__max\">{{ slides.length }}</span>\n </div>\n\n <button *ngIf=\"isMobileBreakpoint\"\n class=\"ecl-carousel__next\" \n (click)=\"onNextSlideClick()\">\n <ecl-icon \n icon=\"corner-arrow\" \n size=\"m\" \n transform=\"rotate-90\" \n isInverted \n class=\"ecl-carousel__icon-default\">\n </ecl-icon>\n <div class=\"ecl-u-sr-only\">{{ 'ecl.carousel.NEXT-SLIDES' | translate }}</div>\n </button>\n </div>\n</div>", styles: [":host{display:block}.ecl-carousel__container{width:100%}.ecl-carousel__slides{transition-duration:.4s}\n"] }]
4118
4147
  }], ctorParameters: function () { return [{ type: i0.Renderer2 }, { type: i1$2.BreakpointObserver }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { isAutoplay: [{
4119
4148
  type: Input
4120
4149
  }], playInterval: [{
@@ -8565,8 +8594,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImpor
8565
8594
 
8566
8595
  var KEY_CODE;
8567
8596
  (function (KEY_CODE) {
8568
- KEY_CODE[KEY_CODE["RIGHT_ARROW"] = 39] = "RIGHT_ARROW";
8569
- KEY_CODE[KEY_CODE["LEFT_ARROW"] = 37] = "LEFT_ARROW";
8597
+ KEY_CODE["ARROW_UP"] = "ArrowUp";
8598
+ KEY_CODE["ARROW_DOWN"] = "ArrowDown";
8599
+ KEY_CODE["ESCAPE"] = "Escape";
8600
+ KEY_CODE["ENTER"] = "Enter";
8601
+ KEY_CODE["TAB"] = "Tab";
8570
8602
  })(KEY_CODE || (KEY_CODE = {}));
8571
8603
  class EclMultiselectComponent extends ECLBaseDirective {
8572
8604
  constructor(ngControl, el, viewContainerRef, differs, translate) {
@@ -8591,6 +8623,7 @@ class EclMultiselectComponent extends ECLBaseDirective {
8591
8623
  if (this.ngControl) {
8592
8624
  this.ngControl.valueAccessor = this;
8593
8625
  }
8626
+ this.bindCallbacks();
8594
8627
  }
8595
8628
  set eclPlaceholder(value) {
8596
8629
  this._eclPlaceholder = value;
@@ -8617,7 +8650,6 @@ class EclMultiselectComponent extends ECLBaseDirective {
8617
8650
  this.hostParentEl = this.getHostParentElement(this.hostEl);
8618
8651
  this.hostWrapperEl = this.createHostWrapperContainer();
8619
8652
  this.selectIconContainerEl = this.createIconContainer();
8620
- this.eclIconComponentEl = this.createIconComponent();
8621
8653
  this.multiselectWrapper = this.createWrapperMultiselect();
8622
8654
  this.multiselectContainer = this.createSelectContainerMultiselect();
8623
8655
  if (this.hostParentEl != null) {
@@ -8630,6 +8662,7 @@ class EclMultiselectComponent extends ECLBaseDirective {
8630
8662
  ngDoCheck() {
8631
8663
  this.multiselectContainer.classList.toggle('ecl-select__container--disabled', this.disabled);
8632
8664
  this.multiselectContainer.classList.toggle('ecl-select__container--invalid', this.isInvalid);
8665
+ this.handleSelectAllDisableStatus();
8633
8666
  if (this.disabled) {
8634
8667
  this.multiSelectInput.disabled = true;
8635
8668
  }
@@ -8650,6 +8683,7 @@ class EclMultiselectComponent extends ECLBaseDirective {
8650
8683
  ngOnDestroy() {
8651
8684
  this.destroy$.next(true);
8652
8685
  this.destroy$.unsubscribe();
8686
+ this.removeAllListeners();
8653
8687
  }
8654
8688
  writeValue(value) {
8655
8689
  if (value) {
@@ -8668,25 +8702,12 @@ class EclMultiselectComponent extends ECLBaseDirective {
8668
8702
  this.propagateTouched = fn;
8669
8703
  }
8670
8704
  onEscapeKey(event) {
8671
- this.multiDropdown.style.display = 'none';
8705
+ this.closeMultiselectDropdown();
8672
8706
  }
8673
- // @HostListener('keyup.ArrowDown', ['$event']) onArrowDownKey(event: KeyboardEvent) {
8674
- // this.multiDropdown.style.display = 'block';
8675
- // }
8676
- // @HostListener('window:keyup', ['$event'])
8677
- // keyEvent(event: KeyboardEvent) {
8678
- // console.log(event);
8679
- // if (event.key === KEY_CODE.RIGHT_ARROW) {
8680
- // this.increment();
8681
- // }
8682
- // if (event.keyCode === KEY_CODE.LEFT_ARROW) {
8683
- // this.decrement();
8684
- // }
8685
- // }
8686
8707
  onKeyUp(ev) {
8687
8708
  const isClickInside = this.multiDropdown.contains(ev.target) || this.multiSelectInput.contains(ev.target);
8688
8709
  if (!isClickInside) {
8689
- this.multiDropdown.style.display = 'none';
8710
+ this.closeMultiselectDropdown();
8690
8711
  }
8691
8712
  }
8692
8713
  removeAllOptions() {
@@ -8714,7 +8735,7 @@ class EclMultiselectComponent extends ECLBaseDirective {
8714
8735
  this.hostParentEl.appendChild(this.multiselectWrapper);
8715
8736
  this.multiselectWrapper.appendChild(this.multiselectContainer);
8716
8737
  this.multiselectContainer.appendChild(this.selectIconContainerEl);
8717
- this.selectIconContainerEl.appendChild(this.eclIconComponentEl);
8738
+ this.selectIconContainerEl.appendChild(this.createIconComponent());
8718
8739
  }
8719
8740
  buildMultiselectDropdown(withOptions) {
8720
8741
  this.multiDropdown = this.createDropdownForMultiselect();
@@ -8760,12 +8781,10 @@ class EclMultiselectComponent extends ECLBaseDirective {
8760
8781
  if (this.hostEl.hasAttribute('formControlName')) {
8761
8782
  this.multiSelectInput.setAttribute('formControlName', this.hostEl.getAttribute('formControlName'));
8762
8783
  }
8763
- this.multiSelectInput.onclick = (e) => {
8764
- e.preventDefault();
8765
- this.multiDropdown.style.display = this.multiDropdown.style.display === 'none' ? 'block' : 'none';
8766
- };
8784
+ this.multiSelectInput.addEventListener('click', this.handleClickOnMainInput);
8767
8785
  this.multiSelectInput.classList.add('ecl-select');
8768
8786
  this.multiSelectInput.classList.add('ecl-select__multiple-toggle');
8787
+ this.multiSelectInput.addEventListener('keydown', this.handleKeydownOnMainInput);
8769
8788
  if (this.disabled) {
8770
8789
  this.multiSelectInput.disabled = true;
8771
8790
  }
@@ -8786,10 +8805,9 @@ class EclMultiselectComponent extends ECLBaseDirective {
8786
8805
  multiSearch.type = 'text';
8787
8806
  multiSearch.classList.add('ecl-text-input');
8788
8807
  multiSearch.placeholder = 'Search';
8789
- // Search elements. Elements that don't match the criteria are hidden
8790
- multiSearch.onkeyup = () => {
8791
- this.searchOptions(multiSearch.value);
8792
- };
8808
+ multiSearch.addEventListener('keydown', this.handleKeydownOnSearch);
8809
+ multiSearch.addEventListener('keyup', this.onSearchOptions);
8810
+ this.searchEl = multiSearch;
8793
8811
  return multiSearch;
8794
8812
  }
8795
8813
  createOptionWithCheckbox(el) {
@@ -8807,17 +8825,14 @@ class EclMultiselectComponent extends ECLBaseDirective {
8807
8825
  checkboxInput.disabled = true;
8808
8826
  }
8809
8827
  else {
8810
- checkboxInput.onclick = () => {
8811
- this.updateCurrentValue();
8812
- this.propagateTouched();
8813
- this.eclChange.emit(this.selectedValues);
8814
- };
8828
+ checkboxInput.addEventListener('click', this.handleClickOnOption);
8815
8829
  }
8816
8830
  if (el.selected || (this.selectedValues.indexOf(el.value) > -1)) {
8817
8831
  checkboxInput.checked = true;
8818
8832
  this.multiSelectInput.value = this.multiSelectInput.value === '' ? el.label :
8819
8833
  this.multiSelectInput.value + ',' + el.label;
8820
8834
  }
8835
+ checkboxInput.addEventListener('keydown', this.handleKeydownOnOption);
8821
8836
  checkboxDiv.appendChild(checkboxInput);
8822
8837
  const checkboxLabel = this.createCheckboxLabel(el.label, id);
8823
8838
  checkboxDiv.appendChild(checkboxLabel);
@@ -8842,8 +8857,8 @@ class EclMultiselectComponent extends ECLBaseDirective {
8842
8857
  }
8843
8858
  // Add/remove values from the select input
8844
8859
  updateCurrentValue() {
8845
- let selectedElementsArray = [];
8846
- let selectedElementsValuesArray = [];
8860
+ const selectedElementsArray = [];
8861
+ const selectedElementsValuesArray = [];
8847
8862
  this.checkboxSelectAll.checked = false;
8848
8863
  this.multiSelectOptions.forEach(el => {
8849
8864
  const input = el.childNodes[0];
@@ -8863,13 +8878,12 @@ class EclMultiselectComponent extends ECLBaseDirective {
8863
8878
  checkboxDiv.classList.add('ecl-checkbox');
8864
8879
  checkboxDiv.classList.add('ecl-select__multiple-all');
8865
8880
  this.checkboxSelectAll = this.createCheckboxInput('select-multiple-all' + idStr.substring(idStr.lastIndexOf('.') + 1), 'all');
8866
- this.checkboxSelectAll.onclick = () => {
8867
- this.propagateTouched();
8868
- this.selectAll();
8869
- };
8881
+ this.checkboxSelectAll.addEventListener('keydown', this.handleKeydownOnSelectAll);
8882
+ this.checkboxSelectAll.addEventListener('click', this.handleClickOnSelectAll);
8870
8883
  checkboxDiv.appendChild(this.checkboxSelectAll);
8871
8884
  this.checkboxLabel = this.createCheckboxLabel('Select all', 'select-multiple-all' + idStr.substring(idStr.lastIndexOf('.') + 1));
8872
8885
  checkboxDiv.appendChild(this.checkboxLabel);
8886
+ this.selectAllEll = checkboxDiv;
8873
8887
  return checkboxDiv;
8874
8888
  }
8875
8889
  createOptionsWrapper() {
@@ -8877,9 +8891,9 @@ class EclMultiselectComponent extends ECLBaseDirective {
8877
8891
  div.classList.add('ecl-select__multiple-options');
8878
8892
  return div;
8879
8893
  }
8880
- selectAll() {
8881
- let selectedElementsArray = [];
8882
- let selectedElementsValuesArray = [];
8894
+ onSelectAll() {
8895
+ const selectedElementsArray = [];
8896
+ const selectedElementsValuesArray = [];
8883
8897
  // Select all the elements, that are not disabled
8884
8898
  this.multiSelectOptions.filter(elem => elem.style.display !== 'none').forEach(el => {
8885
8899
  const input = el.childNodes[0];
@@ -8911,17 +8925,26 @@ class EclMultiselectComponent extends ECLBaseDirective {
8911
8925
  selectIconContainer.classList.add('ecl-select__icon');
8912
8926
  return selectIconContainer;
8913
8927
  }
8914
- searchOptions(keyword = '') {
8928
+ onSearchOptions(evt) {
8929
+ const keyword = evt.target.value;
8915
8930
  if (keyword === '') {
8916
8931
  this.multiSelectOptions.forEach(item => {
8917
8932
  item.style.display = 'flex';
8918
8933
  });
8919
8934
  }
8920
- this.multiSelectOptions.forEach((item, cnt) => {
8935
+ this.multiSelectOptions.forEach(item => {
8921
8936
  if (item.textContent.toLowerCase().indexOf(keyword.toLowerCase()) < 0) {
8922
8937
  item.style.display = 'none';
8923
8938
  }
8939
+ else {
8940
+ item.style.display = 'flex';
8941
+ }
8924
8942
  });
8943
+ this.handleSelectAllDisableStatus();
8944
+ }
8945
+ handleSelectAllDisableStatus() {
8946
+ this.checkboxSelectAll.disabled = this.getActiveOptions().length < 2;
8947
+ this.selectAllEll.classList.toggle('ecl-checkbox--disabled', this.checkboxSelectAll.disabled);
8925
8948
  }
8926
8949
  resetComponent() {
8927
8950
  this.multiSelectOptions.forEach(el => {
@@ -8939,10 +8962,209 @@ class EclMultiselectComponent extends ECLBaseDirective {
8939
8962
  .stream('ecl.multiselect.SELECT-ALL')
8940
8963
  .pipe(takeUntil(this.destroy$)).subscribe((translation) => {
8941
8964
  if (this.checkboxLabel) {
8942
- this.checkboxLabel.textContent = translation;
8965
+ this.checkboxLabel.lastElementChild.textContent = translation;
8966
+ }
8967
+ });
8968
+ }
8969
+ closeMultiselectDropdown() {
8970
+ this.multiDropdown.style.display = 'none';
8971
+ }
8972
+ openMultiselect() {
8973
+ this.multiDropdown.style.display = 'block';
8974
+ }
8975
+ getOptionIndexByIdFromActiveOptions(id) {
8976
+ return this.getActiveOptions().findIndex(option => option.firstElementChild.id === id);
8977
+ }
8978
+ handleClickOnMainInput(evt) {
8979
+ evt.preventDefault();
8980
+ this.toggleDropdown();
8981
+ }
8982
+ toggleDropdown() {
8983
+ this.multiDropdown.style.display = this.multiDropdown.style.display === 'none' ? 'block' : 'none';
8984
+ }
8985
+ handleKeydownOnMainInput(evt) {
8986
+ switch (evt.key) {
8987
+ case KEY_CODE.ARROW_DOWN: {
8988
+ this.onMainInputArrowDown(evt);
8989
+ break;
8990
+ }
8991
+ default: {
8992
+ break;
8993
+ }
8994
+ }
8995
+ }
8996
+ onMainInputArrowDown(evt) {
8997
+ evt.preventDefault();
8998
+ this.openMultiselect();
8999
+ this.searchEl.focus();
9000
+ }
9001
+ handleKeydownOnSearch(evt) {
9002
+ switch (evt.key) {
9003
+ case KEY_CODE.ARROW_DOWN: {
9004
+ this.onSearchArrowDown();
9005
+ break;
9006
+ }
9007
+ case KEY_CODE.ARROW_UP: {
9008
+ this.onSearchArrowUp(evt);
9009
+ break;
9010
+ }
9011
+ case KEY_CODE.ESCAPE: {
9012
+ this.closeMultiselectDropdown();
9013
+ break;
9014
+ }
9015
+ default: {
9016
+ break;
9017
+ }
9018
+ }
9019
+ }
9020
+ onSearchArrowDown() {
9021
+ const currentOptions = this.getActiveOptions();
9022
+ if (currentOptions.length > 1) {
9023
+ this.checkboxSelectAll.focus();
9024
+ }
9025
+ else {
9026
+ const firstOption = currentOptions[0].firstElementChild;
9027
+ firstOption.focus();
9028
+ }
9029
+ ;
9030
+ }
9031
+ onSearchArrowUp(evt) {
9032
+ evt.preventDefault();
9033
+ this.closeMultiselectDropdown();
9034
+ this.multiSelectInput.focus();
9035
+ }
9036
+ handleClickOnSelectAll() {
9037
+ this.propagateTouched();
9038
+ this.onSelectAll();
9039
+ }
9040
+ handleKeydownOnSelectAll(evt) {
9041
+ switch (evt.key) {
9042
+ case KEY_CODE.ARROW_DOWN: {
9043
+ this.onSelectAllArrowDown(evt);
9044
+ break;
9045
+ }
9046
+ case KEY_CODE.ARROW_UP: {
9047
+ this.onSelectAllArrowUp();
9048
+ break;
9049
+ }
9050
+ case KEY_CODE.ENTER: {
9051
+ this.checkboxSelectAll.click();
9052
+ break;
9053
+ }
9054
+ case KEY_CODE.ESCAPE: {
9055
+ this.closeMultiselectDropdown();
9056
+ break;
9057
+ }
9058
+ default: {
9059
+ break;
9060
+ }
9061
+ }
9062
+ }
9063
+ onSelectAllArrowDown(evt) {
9064
+ evt.preventDefault();
9065
+ const currentOptions = this.getActiveOptions();
9066
+ if (currentOptions.length > 0) {
9067
+ const nextSiblingCheckbox = currentOptions[0].firstElementChild;
9068
+ nextSiblingCheckbox.focus();
9069
+ }
9070
+ }
9071
+ onSelectAllArrowUp() {
9072
+ this.searchEl.focus();
9073
+ }
9074
+ handleClickOnOption(evt) {
9075
+ this.updateCurrentValue();
9076
+ this.propagateTouched();
9077
+ this.eclChange.emit(this.selectedValues);
9078
+ }
9079
+ handleKeydownOnOption(evt) {
9080
+ switch (evt.key) {
9081
+ case KEY_CODE.ARROW_DOWN:
9082
+ {
9083
+ this.onOptionArrowDown(evt);
9084
+ break;
9085
+ }
9086
+ ;
9087
+ case KEY_CODE.ARROW_UP: {
9088
+ this.onOptionArrowUp(evt);
9089
+ break;
9090
+ }
9091
+ case KEY_CODE.ESCAPE: {
9092
+ this.closeMultiselectDropdown();
9093
+ break;
9094
+ }
9095
+ case KEY_CODE.ENTER: {
9096
+ evt.target.click();
9097
+ break;
9098
+ }
9099
+ case KEY_CODE.TAB: {
9100
+ this.onOptionTab(evt);
9101
+ break;
8943
9102
  }
9103
+ default: {
9104
+ break;
9105
+ }
9106
+ }
9107
+ }
9108
+ onOptionArrowDown(evt) {
9109
+ evt.preventDefault();
9110
+ const index = this.getOptionIndexByIdFromActiveOptions(evt.target.id);
9111
+ const currentOptions = this.getActiveOptions();
9112
+ if (index !== currentOptions.length - 1) {
9113
+ const nextSiblingCheckbox = currentOptions[index + 1].firstElementChild;
9114
+ nextSiblingCheckbox.focus();
9115
+ }
9116
+ else {
9117
+ this.multiSelectInput.focus();
9118
+ }
9119
+ }
9120
+ onOptionArrowUp(evt) {
9121
+ evt.preventDefault();
9122
+ const index = this.getOptionIndexByIdFromActiveOptions(evt.target.id);
9123
+ if (index !== 0) {
9124
+ const prevSiblingCheckbox = this.getActiveOptions()[index - 1].firstElementChild;
9125
+ prevSiblingCheckbox.focus();
9126
+ }
9127
+ else if (this.checkboxSelectAll.disabled) {
9128
+ this.searchEl.focus();
9129
+ }
9130
+ else {
9131
+ this.checkboxSelectAll.focus();
9132
+ }
9133
+ }
9134
+ onOptionTab(evt) {
9135
+ const index = this.getOptionIndexByIdFromActiveOptions(evt.target.id);
9136
+ if (index === this.getActiveOptions().length - 1) {
9137
+ this.multiSelectInput.focus(); // Trap tab
9138
+ evt.preventDefault();
9139
+ }
9140
+ }
9141
+ getActiveOptions() {
9142
+ return this.multiSelectOptions.filter(item => item.style.display !== 'none' &&
9143
+ !item.classList.contains('ecl-checkbox--disabled'));
9144
+ }
9145
+ removeAllListeners() {
9146
+ this.multiSelectInput.removeEventListener('keydown', this.handleKeydownOnMainInput);
9147
+ this.multiSelectInput.removeEventListener('click', this.handleClickOnMainInput);
9148
+ this.searchEl.removeEventListener('keydown', this.handleKeydownOnSearch);
9149
+ this.searchEl.removeEventListener('keyup', this.onSearchOptions);
9150
+ this.checkboxSelectAll.removeEventListener('keydown', this.handleKeydownOnSelectAll);
9151
+ this.checkboxSelectAll.removeEventListener('click', this.handleClickOnSelectAll);
9152
+ this.multiSelectOptions.forEach(el => {
9153
+ const checboxEl = el.firstElementChild;
9154
+ checboxEl.removeEventListener('keydown', this.handleKeydownOnOption);
9155
+ checboxEl.removeEventListener('click', this.handleClickOnOption);
8944
9156
  });
8945
9157
  }
9158
+ bindCallbacks() {
9159
+ this.handleKeydownOnMainInput = this.handleKeydownOnMainInput.bind(this);
9160
+ this.handleKeydownOnSearch = this.handleKeydownOnSearch.bind(this);
9161
+ this.onSearchOptions = this.onSearchOptions.bind(this);
9162
+ this.handleKeydownOnSelectAll = this.handleKeydownOnSelectAll.bind(this);
9163
+ this.handleKeydownOnOption = this.handleKeydownOnOption.bind(this);
9164
+ this.handleClickOnMainInput = this.handleClickOnMainInput.bind(this);
9165
+ this.handleClickOnSelectAll = this.handleClickOnSelectAll.bind(this);
9166
+ this.handleClickOnOption = this.handleClickOnOption.bind(this);
9167
+ }
8946
9168
  }
8947
9169
  /** @nocollapse */ EclMultiselectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: EclMultiselectComponent, deps: [{ token: i1$1.NgControl, optional: true, self: true }, { token: i0.ElementRef }, { token: i0.ViewContainerRef }, { token: i0.IterableDiffers }, { token: i2.TranslateService }], target: i0.ɵɵFactoryTarget.Component });
8948
9170
  /** @nocollapse */ EclMultiselectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.0", type: EclMultiselectComponent, selector: "select[eclMultiselect]", inputs: { isInvalid: "isInvalid", eclPlaceholder: "eclPlaceholder", disabled: "disabled", eclSize: "eclSize" }, outputs: { eclChange: "eclChange" }, host: { listeners: { "document:keyup.escape": "onEscapeKey($event)", "document:click": "onKeyUp($event)" }, properties: { "attr.disabled": "this.disabled", "class": "this.cssClasses" } }, queries: [{ propertyName: "eclOptionItems", predicate: EclMultiselectOptionDirective }], usesInheritance: true, ngImport: i0, template: "<ng-content></ng-content>" });
@@ -10563,62 +10785,62 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImpor
10563
10785
  }]
10564
10786
  }] });
10565
10787
 
10566
- class EclRadioLabelComponent extends ECLBaseDirective {
10788
+ class EclRadioHelpComponent extends ECLBaseDirective {
10567
10789
  constructor() {
10568
10790
  super(...arguments);
10569
- this.isInvalid = false;
10570
10791
  this.isDisabled = false;
10571
10792
  }
10572
10793
  get cssClasses() {
10573
10794
  return [
10574
- super.getCssClasses('ecl-radio__label'),
10795
+ super.getCssClasses('ecl-radio__help'),
10575
10796
  ].join(' ').trim();
10576
10797
  }
10577
10798
  }
10578
- /** @nocollapse */ EclRadioLabelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: EclRadioLabelComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
10579
- /** @nocollapse */ EclRadioLabelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.0", type: EclRadioLabelComponent, selector: "[eclRadioLabel]", inputs: { isInvalid: "isInvalid", isDisabled: "isDisabled" }, host: { properties: { "class": "this.cssClasses" } }, usesInheritance: true, ngImport: i0, template: "<!--\n @TODO\n Uncomment markup below once eui is fixed\n Due to eui css spillover following markup has to be commented to avoid double radioes being drawn\n https://webgate.ec.europa.eu/CITnet/jira/browse/EUI-3459\n-->\n\n<span class=\"ecl-radio__box\"\n [class.ecl-radio__box--disabled]=\"isDisabled\"\n [class.ecl-radio__box--invalid]=\"isInvalid\">\n</span>\n\n<ng-content></ng-content>\n", styles: [".ecl-radio__label{margin-top:0;margin-bottom:0}.ecl-radio__help{margin-bottom:0}.ecl-radio__box:before{box-sizing:initial}\n"], encapsulation: i0.ViewEncapsulation.None });
10580
- __decorate([
10581
- coerceBoolean
10582
- ], EclRadioLabelComponent.prototype, "isInvalid", void 0);
10799
+ /** @nocollapse */ EclRadioHelpComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: EclRadioHelpComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
10800
+ /** @nocollapse */ EclRadioHelpComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.0", type: EclRadioHelpComponent, selector: "[eclRadioHelp]", inputs: { isDisabled: "isDisabled" }, host: { properties: { "class.ecl-radio__help--disabled": "this.isDisabled", "class": "this.cssClasses" } }, usesInheritance: true, ngImport: i0, template: "<ng-content></ng-content>\n" });
10583
10801
  __decorate([
10584
10802
  coerceBoolean
10585
- ], EclRadioLabelComponent.prototype, "isDisabled", void 0);
10586
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: EclRadioLabelComponent, decorators: [{
10803
+ ], EclRadioHelpComponent.prototype, "isDisabled", void 0);
10804
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: EclRadioHelpComponent, decorators: [{
10587
10805
  type: Component,
10588
- args: [{ selector: '[eclRadioLabel]', encapsulation: ViewEncapsulation.None, template: "<!--\n @TODO\n Uncomment markup below once eui is fixed\n Due to eui css spillover following markup has to be commented to avoid double radioes being drawn\n https://webgate.ec.europa.eu/CITnet/jira/browse/EUI-3459\n-->\n\n<span class=\"ecl-radio__box\"\n [class.ecl-radio__box--disabled]=\"isDisabled\"\n [class.ecl-radio__box--invalid]=\"isInvalid\">\n</span>\n\n<ng-content></ng-content>\n", styles: [".ecl-radio__label{margin-top:0;margin-bottom:0}.ecl-radio__help{margin-bottom:0}.ecl-radio__box:before{box-sizing:initial}\n"] }]
10589
- }], propDecorators: { isInvalid: [{
10590
- type: Input
10591
- }], isDisabled: [{
10806
+ args: [{ selector: '[eclRadioHelp]', template: "<ng-content></ng-content>\n" }]
10807
+ }], propDecorators: { isDisabled: [{
10592
10808
  type: Input
10809
+ }, {
10810
+ type: HostBinding,
10811
+ args: ['class.ecl-radio__help--disabled']
10593
10812
  }], cssClasses: [{
10594
10813
  type: HostBinding,
10595
10814
  args: ['class']
10596
10815
  }] } });
10597
10816
 
10598
- class EclRadioHelpComponent extends ECLBaseDirective {
10817
+ class EclRadioLabelComponent extends ECLBaseDirective {
10599
10818
  constructor() {
10600
10819
  super(...arguments);
10820
+ this.isInvalid = false;
10601
10821
  this.isDisabled = false;
10602
10822
  }
10603
10823
  get cssClasses() {
10604
10824
  return [
10605
- super.getCssClasses('ecl-radio__help'),
10825
+ super.getCssClasses('ecl-radio__label'),
10606
10826
  ].join(' ').trim();
10607
10827
  }
10608
10828
  }
10609
- /** @nocollapse */ EclRadioHelpComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: EclRadioHelpComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
10610
- /** @nocollapse */ EclRadioHelpComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.0", type: EclRadioHelpComponent, selector: "[eclRadioHelp]", inputs: { isDisabled: "isDisabled" }, host: { properties: { "class.ecl-radio__help--disabled": "this.isDisabled", "class": "this.cssClasses" } }, usesInheritance: true, ngImport: i0, template: "<ng-content></ng-content>\n" });
10829
+ /** @nocollapse */ EclRadioLabelComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: EclRadioLabelComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
10830
+ /** @nocollapse */ EclRadioLabelComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.0", type: EclRadioLabelComponent, selector: "[eclRadioLabel]", inputs: { isInvalid: "isInvalid", isDisabled: "isDisabled" }, host: { properties: { "class": "this.cssClasses" } }, usesInheritance: true, ngImport: i0, template: "<span class=\"ecl-radio__box\"\n [class.ecl-radio__box--disabled]=\"isDisabled\"\n [class.ecl-radio__box--invalid]=\"isInvalid\">\n</span>\n\n<ng-content></ng-content>\n", styles: [".ecl-radio__label{margin-top:0;margin-bottom:0}.ecl-radio__help{margin-bottom:0}.ecl-radio__box:before{box-sizing:initial}\n"], encapsulation: i0.ViewEncapsulation.None });
10611
10831
  __decorate([
10612
10832
  coerceBoolean
10613
- ], EclRadioHelpComponent.prototype, "isDisabled", void 0);
10614
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: EclRadioHelpComponent, decorators: [{
10833
+ ], EclRadioLabelComponent.prototype, "isInvalid", void 0);
10834
+ __decorate([
10835
+ coerceBoolean
10836
+ ], EclRadioLabelComponent.prototype, "isDisabled", void 0);
10837
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: EclRadioLabelComponent, decorators: [{
10615
10838
  type: Component,
10616
- args: [{ selector: '[eclRadioHelp]', template: "<ng-content></ng-content>\n" }]
10617
- }], propDecorators: { isDisabled: [{
10839
+ args: [{ selector: '[eclRadioLabel]', encapsulation: ViewEncapsulation.None, template: "<span class=\"ecl-radio__box\"\n [class.ecl-radio__box--disabled]=\"isDisabled\"\n [class.ecl-radio__box--invalid]=\"isInvalid\">\n</span>\n\n<ng-content></ng-content>\n", styles: [".ecl-radio__label{margin-top:0;margin-bottom:0}.ecl-radio__help{margin-bottom:0}.ecl-radio__box:before{box-sizing:initial}\n"] }]
10840
+ }], propDecorators: { isInvalid: [{
10841
+ type: Input
10842
+ }], isDisabled: [{
10618
10843
  type: Input
10619
- }, {
10620
- type: HostBinding,
10621
- args: ['class.ecl-radio__help--disabled']
10622
10844
  }], cssClasses: [{
10623
10845
  type: HostBinding,
10624
10846
  args: ['class']
@@ -10636,10 +10858,7 @@ class EclRadioDirective extends ECLBaseDirective {
10636
10858
  this.isBinary ? 'ecl-radio--binary' : '',
10637
10859
  ].join(' ').trim();
10638
10860
  }
10639
- ngAfterContentInit() {
10640
- this.updateChildElements();
10641
- }
10642
- ngOnChanges() {
10861
+ ngDoCheck() {
10643
10862
  this.updateChildElements();
10644
10863
  }
10645
10864
  updateChildElements() {
@@ -10653,7 +10872,7 @@ class EclRadioDirective extends ECLBaseDirective {
10653
10872
  }
10654
10873
  }
10655
10874
  /** @nocollapse */ EclRadioDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: EclRadioDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive });
10656
- /** @nocollapse */ EclRadioDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.0", type: EclRadioDirective, selector: "[eclRadio]", inputs: { isBinary: "isBinary", isDisabled: "isDisabled", isInvalid: "isInvalid" }, host: { properties: { "class.ecl-radio--disabled": "this.isDisabled", "class.ecl-radio--invalid": "this.isInvalid", "class": "this.cssClasses" } }, queries: [{ propertyName: "eclRadioLabelComponent", first: true, predicate: i0.forwardRef(function () { return EclRadioLabelComponent; }), descendants: true }, { propertyName: "eclRadioHelpComponent", first: true, predicate: i0.forwardRef(function () { return EclRadioHelpComponent; }), descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0 });
10875
+ /** @nocollapse */ EclRadioDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.0", type: EclRadioDirective, selector: "[eclRadio]", inputs: { isBinary: "isBinary", isDisabled: "isDisabled", isInvalid: "isInvalid" }, host: { properties: { "class.ecl-radio--disabled": "this.isDisabled", "class.ecl-radio--invalid": "this.isInvalid", "class": "this.cssClasses" } }, queries: [{ propertyName: "eclRadioLabelComponent", first: true, predicate: i0.forwardRef(function () { return EclRadioLabelComponent; }), descendants: true }, { propertyName: "eclRadioHelpComponent", first: true, predicate: i0.forwardRef(function () { return EclRadioHelpComponent; }), descendants: true }], usesInheritance: true, ngImport: i0 });
10657
10876
  __decorate([
10658
10877
  coerceBoolean
10659
10878
  ], EclRadioDirective.prototype, "isBinary", void 0);
@@ -10905,9 +11124,9 @@ class EclSelectDirective extends ECLBaseDirective {
10905
11124
  this.handleMarkup();
10906
11125
  }
10907
11126
  ngDoCheck() {
10908
- if (this.ngControl) {
10909
- this.hostWrapperEl.classList.toggle('ecl-select__container--disabled', this.ngControl.disabled || this.disabled);
10910
- }
11127
+ var _a, _b, _c;
11128
+ this.hostWrapperEl.classList.toggle('ecl-select__container--disabled', ((_a = this.ngControl) === null || _a === void 0 ? void 0 : _a.disabled) || this.disabled);
11129
+ this.hostWrapperEl.classList.toggle('ecl-select__container--invalid', ((_b = this.ngControl) === null || _b === void 0 ? void 0 : _b.touched) && ((_c = this.ngControl) === null || _c === void 0 ? void 0 : _c.invalid) || this.isInvalid);
10911
11130
  }
10912
11131
  handleMarkup() {
10913
11132
  if (this.hostParentEl != null) {