ecabs-components 1.1.81 → 1.1.83

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.
@@ -952,7 +952,8 @@ class EcabsDigitsOnlyDirective {
952
952
  let result = input.replace(new RegExp(`[^${allowed.join('')}]`, 'g'), '');
953
953
  if (this.allowHyphen) {
954
954
  const isNegative = result.startsWith(this.minus);
955
- result = (isNegative ? this.minus : '') + result.split(this.minus).join('');
955
+ result =
956
+ (isNegative ? this.minus : '') + result.split(this.minus).join('');
956
957
  }
957
958
  if (this.decimal) {
958
959
  result = this.keepFirstSeparator(result, separator);
@@ -973,7 +974,10 @@ class EcabsDigitsOnlyDirective {
973
974
  if (firstHyphen !== -1) {
974
975
  body =
975
976
  body.slice(0, firstHyphen + 1) +
976
- body.slice(firstHyphen + 1).split(this.minus).join('');
977
+ body
978
+ .slice(firstHyphen + 1)
979
+ .split(this.minus)
980
+ .join('');
977
981
  }
978
982
  if (this.decimal) {
979
983
  body = body
@@ -990,7 +994,10 @@ class EcabsDigitsOnlyDirective {
990
994
  return value;
991
995
  }
992
996
  return (value.slice(0, firstSeparator + 1) +
993
- value.slice(firstSeparator + 1).split(separator).join(''));
997
+ value
998
+ .slice(firstSeparator + 1)
999
+ .split(separator)
1000
+ .join(''));
994
1001
  }
995
1002
  applyMaxLength(result) {
996
1003
  const maxLength = this.inputElement.maxLength;
@@ -1040,7 +1047,7 @@ class EcabsDigitsOnlyDirective {
1040
1047
  return /\d/.test(before);
1041
1048
  }
1042
1049
  isPartialRange(value) {
1043
- return !!this.allowRange && !!this.rangeRegex && this.rangeRegex.test(value);
1050
+ return (!!this.allowRange && !!this.rangeRegex && this.rangeRegex.test(value));
1044
1051
  }
1045
1052
  isPartialNegative(value) {
1046
1053
  if (!this.allowHyphen || !value.startsWith(this.minus)) {
@@ -1210,10 +1217,8 @@ class EcabsInputComponent extends EcabsElementBaseComponent {
1210
1217
  this.updateDisabledState();
1211
1218
  this.trackAutoResize();
1212
1219
  }
1213
- onChange = () => {
1214
- };
1215
- onTouch = () => {
1216
- };
1220
+ onChange = () => { };
1221
+ onTouch = () => { };
1217
1222
  writeValue(value) {
1218
1223
  this.value = value;
1219
1224
  this.trackAutoResize();
@@ -8185,7 +8190,7 @@ class EcabsPlaceAutocompleteV2Component extends EcabsElementBaseComponent {
8185
8190
  matCustomInput;
8186
8191
  showDeleteItem = false;
8187
8192
  set waypointsHistory(value) {
8188
- this.waypointsHistory$.next((value ?? []).filter((suggestion) => !!suggestion?.place_id));
8193
+ this.waypointsHistory$.next((value ?? []).filter((suggestion) => !!suggestion?.place_id || !!this.toPlaceFallback(suggestion)));
8189
8194
  }
8190
8195
  showSuffix = false;
8191
8196
  countryCode = 'MT';
@@ -8245,10 +8250,10 @@ class EcabsPlaceAutocompleteV2Component extends EcabsElementBaseComponent {
8245
8250
  place_name: query,
8246
8251
  });
8247
8252
  });
8248
- const googleSuggestions$ = combineLatest([
8249
- this.isFocused$,
8250
- this.value$.pipe(debounceTime(this.debounceMs), distinctUntilChanged()),
8251
- ]).pipe(switchMap(([isFocused, value]) => this.autocompleteService && isFocused && value
8253
+ // Keyed on value$ alone so blur/refocus cannot re-fire a billable
8254
+ // prediction request for an unchanged query; focus is read imperatively at
8255
+ // request time so programmatic writeValue never triggers a request either.
8256
+ const googleSuggestions$ = this.value$.pipe(debounceTime(this.debounceMs), distinctUntilChanged(), switchMap((value) => this.autocompleteService && value && this.isFocused$.value
8252
8257
  ? this.getPlacesResults(value)
8253
8258
  : of(this.emptySuggestions)), startWith(this.emptySuggestions));
8254
8259
  this.waypointSuggestions$ = combineLatest([
@@ -8266,10 +8271,8 @@ class EcabsPlaceAutocompleteV2Component extends EcabsElementBaseComponent {
8266
8271
  this.selectedIndex = cappedSuggestions?.length ? 0 : -1;
8267
8272
  }));
8268
8273
  }
8269
- onChange = () => {
8270
- };
8271
- onTouch = () => {
8272
- };
8274
+ onChange = () => { };
8275
+ onTouch = () => { };
8273
8276
  getPlacesResults(query) {
8274
8277
  return new Observable((observer) => {
8275
8278
  this.autocompleteService.getPlacePredictions({
@@ -8309,13 +8312,55 @@ class EcabsPlaceAutocompleteV2Component extends EcabsElementBaseComponent {
8309
8312
  return;
8310
8313
  }
8311
8314
  const { additional_info, place_id } = suggestion ?? {};
8312
- if (!place_id) {
8315
+ if (place_id) {
8316
+ this.isResolvingPlace = true;
8317
+ this.value = additional_info;
8318
+ this.isFocused$.next(false);
8319
+ this.resolveByPlaceId(place_id, additional_info);
8313
8320
  return;
8314
8321
  }
8315
- this.isResolvingPlace = true;
8316
- this.value = additional_info;
8317
- this.isFocused$.next(false);
8318
- this.resolveByPlaceId(place_id, additional_info);
8322
+ const fallbackPlace = this.toPlaceFallback(suggestion);
8323
+ if (fallbackPlace) {
8324
+ console.warn('Waypoint history fallback used: no place_id on suggestion', {
8325
+ suggestion_id: suggestion?.suggestion_id,
8326
+ geo_key: suggestion?.geo_key,
8327
+ });
8328
+ this.value = additional_info;
8329
+ this.isFocused$.next(false);
8330
+ this.placeResult.emit({ place: fallbackPlace, text: additional_info });
8331
+ // Fallback selection can happen before the Google Maps script loads, and
8332
+ // a fresh session token needs the google global.
8333
+ if (this.autocompleteService) {
8334
+ this.resetSessionToken();
8335
+ }
8336
+ }
8337
+ }
8338
+ toLatLng(suggestion) {
8339
+ const { location } = suggestion ?? {};
8340
+ return {
8341
+ lat: Number(location?.latitude ?? location?.lat),
8342
+ lng: Number(location?.longitude ?? location?.lng),
8343
+ };
8344
+ }
8345
+ toPlaceFallback(suggestion) {
8346
+ const { additional_info, locality } = suggestion ?? {};
8347
+ const { lat, lng } = this.toLatLng(suggestion);
8348
+ if (Number.isNaN(lat) ||
8349
+ Number.isNaN(lng) ||
8350
+ !additional_info ||
8351
+ !locality) {
8352
+ return null;
8353
+ }
8354
+ return {
8355
+ // Duck-typed LatLng: history can arrive from the store before the Google
8356
+ // Maps script loads, so this must not touch the google global.
8357
+ geometry: {
8358
+ location: { lat: () => lat, lng: () => lng },
8359
+ },
8360
+ address_components: [
8361
+ { types: ['locality'], long_name: locality, short_name: locality },
8362
+ ],
8363
+ };
8319
8364
  }
8320
8365
  resolveByPlaceId(placeId, text) {
8321
8366
  this.placesService.getDetails({
@@ -8411,7 +8456,7 @@ class EcabsPlaceAutocompleteV2Component extends EcabsElementBaseComponent {
8411
8456
  useExisting: EcabsPlaceAutocompleteV2Component,
8412
8457
  multi: true,
8413
8458
  },
8414
- ], viewQueries: [{ propertyName: "matCustomInput", first: true, predicate: ["matCustomAutocompleteInput"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<ecabs-element-wrapper [data]=\"getData()\">\n <div class=\"autocomplete-ui w-full\">\n <section class=\"form-field__input--wrapper w-full\">\n <input #matCustomAutocompleteInput\n cdkOverlayOrigin\n #trigger=\"cdkOverlayOrigin\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [(ngModel)]=\"value\"\n [id]=\"name\"\n class=\"form-field__input w-full\"\n autocorrect=\"off\"\n autocapitalize=\"off\"\n spellcheck=\"off\"\n (focus)=\"onFocus()\"\n (keydown)=\"onKeyDown($event)\"\n (ngModelChange)=\"onUserInput($event)\"\n (blur)=\"onBlur()\"\n />\n <div *ngIf=\"showSuffix\"\n class=\"form-field__input--suffix\">\n <mat-icon *ngIf=\"showDeleteItem\"\n class=\"suffix cursor-pointer delete-button\"\n (keydown.enter)=\"delete()\"\n (click)=\"delete()\">\n delete\n </mat-icon>\n <mat-icon *ngIf=\"!showDeleteItem && value\"\n class=\"suffix cursor-pointer\"\n (keydown.enter)=\"clear()\"\n (click)=\"clear()\">\n close\n </mat-icon>\n </div>\n </section>\n <!-- Custom dropdown -->\n <ng-template cdkConnectedOverlay\n [cdkConnectedOverlayWidth]=\"trigger.elementRef.nativeElement.offsetWidth\"\n [cdkConnectedOverlayFlexibleDimensions]=\"false\"\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"isFocused$ | async\">\n <ul class=\"autocomplete-ui__container\">\n <li *ngFor=\"let suggestion of waypointSuggestions$ | async; let i = index; trackBy: trackBySuggestion\"\n class=\"autocomplete-ui--item flex items-center justify-between hover:bg-gray-100\"\n [class.active]=\"i === selectedIndex\"\n (mousedown)=\"onSelectSuggestion(suggestion)\">\n <ng-container *ngIf=\"!suggestion?.prediction_term; else purePlaceResultTpl\">\n <div class=\"w-full truncate\">\n {{ suggestion?.additional_info }}\n </div>\n <mat-icon svgIcon=\"ph-regular:clock-counter\"\n class=\"w-5 h-5 text-xl text-gray-400 hover:!text-gray-400\">\n </mat-icon>\n </ng-container>\n\n <ng-template #purePlaceResultTpl>\n <ul class=\"w-full flex items-center gap-x-1 leading-0 overflow-hidden whitespace-nowrap\">\n <li>\n {{ suggestion?.prediction_term?.[0]?.value }}\n </li>\n <li *ngIf=\"suggestion?.prediction_term?.[1]?.value\"\n class=\"text-xs text-gray-600 truncate\">\n {{ suggestion?.prediction_term?.[1]?.value | separatorAppend: suggestion?.prediction_term?.[2]?.value }}\n </li>\n <li *ngIf=\"suggestion?.prediction_term?.[2]?.value\"\n class=\"text-xs text-gray-600 font-semibold truncate\">\n {{ suggestion?.prediction_term?.[2]?.value }}\n </li>\n </ul>\n </ng-template>\n </li>\n </ul>\n </ng-template>\n </div>\n</ecabs-element-wrapper>\n", styles: [":root{--mat-standard-button-toggle-shape: calc-rem(8px);--mat-option-label-text-color: var(--color-gray-900);--mat-option-focus-state-layer-color: var(--color-gray-100);--mat-option-hover-state-layer-color: var(--color-gray-50);--mat-divider-color: var(--color-gray-100);--mat-select-placeholder-text-color: var(--color-gray-400)}mat-form-field{margin-bottom:0!important}.delete-button{color:var(--color-error)}\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: EcabsElementWrapperComponent, selector: "ecabs-element-wrapper", inputs: ["data", "showCloseIcon", "focusedFlag", "showPassword", "control"], outputs: ["showHidePassword", "clear", "increase", "decrease"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i5.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "directive", type: i5.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: SeparatorAppendPipe, name: "separatorAppend" }] });
8459
+ ], viewQueries: [{ propertyName: "matCustomInput", first: true, predicate: ["matCustomAutocompleteInput"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<ecabs-element-wrapper [data]=\"getData()\">\r\n <div class=\"autocomplete-ui w-full\">\r\n <section class=\"form-field__input--wrapper w-full\">\r\n <input #matCustomAutocompleteInput\r\n cdkOverlayOrigin\r\n #trigger=\"cdkOverlayOrigin\"\r\n [placeholder]=\"placeholder\"\r\n [disabled]=\"disabled\"\r\n [(ngModel)]=\"value\"\r\n [id]=\"name\"\r\n class=\"form-field__input w-full\"\r\n autocomplete=\"off\"\r\n autocorrect=\"off\"\r\n autocapitalize=\"off\"\r\n spellcheck=\"off\"\r\n (focus)=\"onFocus()\"\r\n (keydown)=\"onKeyDown($event)\"\r\n (ngModelChange)=\"onUserInput($event)\"\r\n (blur)=\"onBlur()\"\r\n />\r\n <div *ngIf=\"showSuffix\"\r\n class=\"form-field__input--suffix\">\r\n <mat-icon *ngIf=\"showDeleteItem\"\r\n class=\"suffix cursor-pointer delete-button\"\r\n (keydown.enter)=\"delete()\"\r\n (click)=\"delete()\">\r\n delete\r\n </mat-icon>\r\n <mat-icon *ngIf=\"!showDeleteItem && value\"\r\n class=\"suffix cursor-pointer\"\r\n (keydown.enter)=\"clear()\"\r\n (click)=\"clear()\">\r\n close\r\n </mat-icon>\r\n </div>\r\n </section>\r\n <!-- Custom dropdown -->\r\n <ng-template cdkConnectedOverlay\r\n [cdkConnectedOverlayWidth]=\"trigger.elementRef.nativeElement.offsetWidth\"\r\n [cdkConnectedOverlayFlexibleDimensions]=\"false\"\r\n [cdkConnectedOverlayOrigin]=\"trigger\"\r\n [cdkConnectedOverlayOpen]=\"isFocused$ | async\">\r\n <ul class=\"autocomplete-ui__container\">\r\n <li *ngFor=\"let suggestion of waypointSuggestions$ | async; let i = index; trackBy: trackBySuggestion\"\r\n class=\"autocomplete-ui--item flex items-center justify-between hover:bg-gray-100\"\r\n [class.active]=\"i === selectedIndex\"\r\n (mousedown)=\"onSelectSuggestion(suggestion)\">\r\n <ng-container *ngIf=\"!suggestion?.prediction_term; else purePlaceResultTpl\">\r\n <div class=\"w-full truncate\">\r\n {{ suggestion?.additional_info }}\r\n </div>\r\n <mat-icon svgIcon=\"ph-regular:clock-counter\"\r\n class=\"w-5 h-5 text-xl text-gray-400 hover:!text-gray-400\">\r\n </mat-icon>\r\n </ng-container>\r\n\r\n <ng-template #purePlaceResultTpl>\r\n <ul class=\"w-full flex items-center gap-x-1 leading-0 overflow-hidden whitespace-nowrap\">\r\n <li>\r\n {{ suggestion?.prediction_term?.[0]?.value }}\r\n </li>\r\n <li *ngIf=\"suggestion?.prediction_term?.[1]?.value\"\r\n class=\"text-xs text-gray-600 truncate\">\r\n {{ suggestion?.prediction_term?.[1]?.value | separatorAppend: suggestion?.prediction_term?.[2]?.value }}\r\n </li>\r\n <li *ngIf=\"suggestion?.prediction_term?.[2]?.value\"\r\n class=\"text-xs text-gray-600 font-semibold truncate\">\r\n {{ suggestion?.prediction_term?.[2]?.value }}\r\n </li>\r\n </ul>\r\n </ng-template>\r\n </li>\r\n </ul>\r\n </ng-template>\r\n </div>\r\n</ecabs-element-wrapper>\r\n", styles: [":root{--mat-standard-button-toggle-shape: calc-rem(8px);--mat-option-label-text-color: var(--color-gray-900);--mat-option-focus-state-layer-color: var(--color-gray-100);--mat-option-hover-state-layer-color: var(--color-gray-50);--mat-divider-color: var(--color-gray-100);--mat-select-placeholder-text-color: var(--color-gray-400)}mat-form-field{margin-bottom:0!important}.delete-button{color:var(--color-error)}\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: EcabsElementWrapperComponent, selector: "ecabs-element-wrapper", inputs: ["data", "showCloseIcon", "focusedFlag", "showPassword", "control"], outputs: ["showHidePassword", "clear", "increase", "decrease"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i5.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "directive", type: i5.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "pipe", type: SeparatorAppendPipe, name: "separatorAppend" }] });
8415
8460
  }
8416
8461
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: EcabsPlaceAutocompleteV2Component, decorators: [{
8417
8462
  type: Component,
@@ -8421,7 +8466,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
8421
8466
  useExisting: EcabsPlaceAutocompleteV2Component,
8422
8467
  multi: true,
8423
8468
  },
8424
- ], template: "<ecabs-element-wrapper [data]=\"getData()\">\n <div class=\"autocomplete-ui w-full\">\n <section class=\"form-field__input--wrapper w-full\">\n <input #matCustomAutocompleteInput\n cdkOverlayOrigin\n #trigger=\"cdkOverlayOrigin\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [(ngModel)]=\"value\"\n [id]=\"name\"\n class=\"form-field__input w-full\"\n autocorrect=\"off\"\n autocapitalize=\"off\"\n spellcheck=\"off\"\n (focus)=\"onFocus()\"\n (keydown)=\"onKeyDown($event)\"\n (ngModelChange)=\"onUserInput($event)\"\n (blur)=\"onBlur()\"\n />\n <div *ngIf=\"showSuffix\"\n class=\"form-field__input--suffix\">\n <mat-icon *ngIf=\"showDeleteItem\"\n class=\"suffix cursor-pointer delete-button\"\n (keydown.enter)=\"delete()\"\n (click)=\"delete()\">\n delete\n </mat-icon>\n <mat-icon *ngIf=\"!showDeleteItem && value\"\n class=\"suffix cursor-pointer\"\n (keydown.enter)=\"clear()\"\n (click)=\"clear()\">\n close\n </mat-icon>\n </div>\n </section>\n <!-- Custom dropdown -->\n <ng-template cdkConnectedOverlay\n [cdkConnectedOverlayWidth]=\"trigger.elementRef.nativeElement.offsetWidth\"\n [cdkConnectedOverlayFlexibleDimensions]=\"false\"\n [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"isFocused$ | async\">\n <ul class=\"autocomplete-ui__container\">\n <li *ngFor=\"let suggestion of waypointSuggestions$ | async; let i = index; trackBy: trackBySuggestion\"\n class=\"autocomplete-ui--item flex items-center justify-between hover:bg-gray-100\"\n [class.active]=\"i === selectedIndex\"\n (mousedown)=\"onSelectSuggestion(suggestion)\">\n <ng-container *ngIf=\"!suggestion?.prediction_term; else purePlaceResultTpl\">\n <div class=\"w-full truncate\">\n {{ suggestion?.additional_info }}\n </div>\n <mat-icon svgIcon=\"ph-regular:clock-counter\"\n class=\"w-5 h-5 text-xl text-gray-400 hover:!text-gray-400\">\n </mat-icon>\n </ng-container>\n\n <ng-template #purePlaceResultTpl>\n <ul class=\"w-full flex items-center gap-x-1 leading-0 overflow-hidden whitespace-nowrap\">\n <li>\n {{ suggestion?.prediction_term?.[0]?.value }}\n </li>\n <li *ngIf=\"suggestion?.prediction_term?.[1]?.value\"\n class=\"text-xs text-gray-600 truncate\">\n {{ suggestion?.prediction_term?.[1]?.value | separatorAppend: suggestion?.prediction_term?.[2]?.value }}\n </li>\n <li *ngIf=\"suggestion?.prediction_term?.[2]?.value\"\n class=\"text-xs text-gray-600 font-semibold truncate\">\n {{ suggestion?.prediction_term?.[2]?.value }}\n </li>\n </ul>\n </ng-template>\n </li>\n </ul>\n </ng-template>\n </div>\n</ecabs-element-wrapper>\n", styles: [":root{--mat-standard-button-toggle-shape: calc-rem(8px);--mat-option-label-text-color: var(--color-gray-900);--mat-option-focus-state-layer-color: var(--color-gray-100);--mat-option-hover-state-layer-color: var(--color-gray-50);--mat-divider-color: var(--color-gray-100);--mat-select-placeholder-text-color: var(--color-gray-400)}mat-form-field{margin-bottom:0!important}.delete-button{color:var(--color-error)}\n"] }]
8469
+ ], template: "<ecabs-element-wrapper [data]=\"getData()\">\r\n <div class=\"autocomplete-ui w-full\">\r\n <section class=\"form-field__input--wrapper w-full\">\r\n <input #matCustomAutocompleteInput\r\n cdkOverlayOrigin\r\n #trigger=\"cdkOverlayOrigin\"\r\n [placeholder]=\"placeholder\"\r\n [disabled]=\"disabled\"\r\n [(ngModel)]=\"value\"\r\n [id]=\"name\"\r\n class=\"form-field__input w-full\"\r\n autocomplete=\"off\"\r\n autocorrect=\"off\"\r\n autocapitalize=\"off\"\r\n spellcheck=\"off\"\r\n (focus)=\"onFocus()\"\r\n (keydown)=\"onKeyDown($event)\"\r\n (ngModelChange)=\"onUserInput($event)\"\r\n (blur)=\"onBlur()\"\r\n />\r\n <div *ngIf=\"showSuffix\"\r\n class=\"form-field__input--suffix\">\r\n <mat-icon *ngIf=\"showDeleteItem\"\r\n class=\"suffix cursor-pointer delete-button\"\r\n (keydown.enter)=\"delete()\"\r\n (click)=\"delete()\">\r\n delete\r\n </mat-icon>\r\n <mat-icon *ngIf=\"!showDeleteItem && value\"\r\n class=\"suffix cursor-pointer\"\r\n (keydown.enter)=\"clear()\"\r\n (click)=\"clear()\">\r\n close\r\n </mat-icon>\r\n </div>\r\n </section>\r\n <!-- Custom dropdown -->\r\n <ng-template cdkConnectedOverlay\r\n [cdkConnectedOverlayWidth]=\"trigger.elementRef.nativeElement.offsetWidth\"\r\n [cdkConnectedOverlayFlexibleDimensions]=\"false\"\r\n [cdkConnectedOverlayOrigin]=\"trigger\"\r\n [cdkConnectedOverlayOpen]=\"isFocused$ | async\">\r\n <ul class=\"autocomplete-ui__container\">\r\n <li *ngFor=\"let suggestion of waypointSuggestions$ | async; let i = index; trackBy: trackBySuggestion\"\r\n class=\"autocomplete-ui--item flex items-center justify-between hover:bg-gray-100\"\r\n [class.active]=\"i === selectedIndex\"\r\n (mousedown)=\"onSelectSuggestion(suggestion)\">\r\n <ng-container *ngIf=\"!suggestion?.prediction_term; else purePlaceResultTpl\">\r\n <div class=\"w-full truncate\">\r\n {{ suggestion?.additional_info }}\r\n </div>\r\n <mat-icon svgIcon=\"ph-regular:clock-counter\"\r\n class=\"w-5 h-5 text-xl text-gray-400 hover:!text-gray-400\">\r\n </mat-icon>\r\n </ng-container>\r\n\r\n <ng-template #purePlaceResultTpl>\r\n <ul class=\"w-full flex items-center gap-x-1 leading-0 overflow-hidden whitespace-nowrap\">\r\n <li>\r\n {{ suggestion?.prediction_term?.[0]?.value }}\r\n </li>\r\n <li *ngIf=\"suggestion?.prediction_term?.[1]?.value\"\r\n class=\"text-xs text-gray-600 truncate\">\r\n {{ suggestion?.prediction_term?.[1]?.value | separatorAppend: suggestion?.prediction_term?.[2]?.value }}\r\n </li>\r\n <li *ngIf=\"suggestion?.prediction_term?.[2]?.value\"\r\n class=\"text-xs text-gray-600 font-semibold truncate\">\r\n {{ suggestion?.prediction_term?.[2]?.value }}\r\n </li>\r\n </ul>\r\n </ng-template>\r\n </li>\r\n </ul>\r\n </ng-template>\r\n </div>\r\n</ecabs-element-wrapper>\r\n", styles: [":root{--mat-standard-button-toggle-shape: calc-rem(8px);--mat-option-label-text-color: var(--color-gray-900);--mat-option-focus-state-layer-color: var(--color-gray-100);--mat-option-hover-state-layer-color: var(--color-gray-50);--mat-divider-color: var(--color-gray-100);--mat-select-placeholder-text-color: var(--color-gray-400)}mat-form-field{margin-bottom:0!important}.delete-button{color:var(--color-error)}\n"] }]
8425
8470
  }], ctorParameters: function () { return []; }, propDecorators: { matCustomInput: [{
8426
8471
  type: ViewChild,
8427
8472
  args: ['matCustomAutocompleteInput', { static: false }]