@fundamental-ngx/core 0.65.0-rc.8 → 0.65.0

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 (44) hide show
  1. package/fesm2022/fundamental-ngx-core-avatar-group.mjs +118 -39
  2. package/fesm2022/fundamental-ngx-core-avatar-group.mjs.map +1 -1
  3. package/fesm2022/fundamental-ngx-core-combobox.mjs +166 -22
  4. package/fesm2022/fundamental-ngx-core-combobox.mjs.map +1 -1
  5. package/fesm2022/fundamental-ngx-core-date-picker.mjs +1 -4
  6. package/fesm2022/fundamental-ngx-core-date-picker.mjs.map +1 -1
  7. package/fesm2022/fundamental-ngx-core-datetime-picker.mjs +21 -0
  8. package/fesm2022/fundamental-ngx-core-datetime-picker.mjs.map +1 -1
  9. package/fesm2022/fundamental-ngx-core-icon.mjs +2 -2
  10. package/fesm2022/fundamental-ngx-core-icon.mjs.map +1 -1
  11. package/fesm2022/fundamental-ngx-core-list.mjs +10 -6
  12. package/fesm2022/fundamental-ngx-core-list.mjs.map +1 -1
  13. package/fesm2022/fundamental-ngx-core-menu.mjs +63 -2
  14. package/fesm2022/fundamental-ngx-core-menu.mjs.map +1 -1
  15. package/fesm2022/fundamental-ngx-core-multi-combobox.mjs +21 -36
  16. package/fesm2022/fundamental-ngx-core-multi-combobox.mjs.map +1 -1
  17. package/fesm2022/fundamental-ngx-core-multi-input.mjs +1 -1
  18. package/fesm2022/fundamental-ngx-core-multi-input.mjs.map +1 -1
  19. package/fesm2022/fundamental-ngx-core-popover.mjs +22 -40
  20. package/fesm2022/fundamental-ngx-core-popover.mjs.map +1 -1
  21. package/fesm2022/fundamental-ngx-core-select.mjs +1 -1
  22. package/fesm2022/fundamental-ngx-core-select.mjs.map +1 -1
  23. package/fesm2022/fundamental-ngx-core-settings.mjs +113 -13
  24. package/fesm2022/fundamental-ngx-core-settings.mjs.map +1 -1
  25. package/fesm2022/fundamental-ngx-core-table.mjs +373 -499
  26. package/fesm2022/fundamental-ngx-core-table.mjs.map +1 -1
  27. package/fesm2022/fundamental-ngx-core-token.mjs +1 -1
  28. package/fesm2022/fundamental-ngx-core-token.mjs.map +1 -1
  29. package/fesm2022/fundamental-ngx-core-upload-collection.mjs +1 -1
  30. package/fesm2022/fundamental-ngx-core-upload-collection.mjs.map +1 -1
  31. package/fesm2022/fundamental-ngx-core-vertical-navigation.mjs +1 -1
  32. package/fesm2022/fundamental-ngx-core-vertical-navigation.mjs.map +1 -1
  33. package/package.json +3 -3
  34. package/schematics/package.json +1 -1
  35. package/types/fundamental-ngx-core-avatar-group.d.ts +52 -19
  36. package/types/fundamental-ngx-core-combobox.d.ts +44 -6
  37. package/types/fundamental-ngx-core-datetime-picker.d.ts +3 -1
  38. package/types/fundamental-ngx-core-list.d.ts +4 -1
  39. package/types/fundamental-ngx-core-menu.d.ts +8 -1
  40. package/types/fundamental-ngx-core-mobile-mode.d.ts +2 -0
  41. package/types/fundamental-ngx-core-multi-combobox.d.ts +1 -1
  42. package/types/fundamental-ngx-core-popover.d.ts +11 -16
  43. package/types/fundamental-ngx-core-settings.d.ts +57 -5
  44. package/types/fundamental-ngx-core-table.d.ts +133 -164
@@ -60,6 +60,11 @@ class ComboboxMobileComponent extends MobileModeBase {
60
60
  * List element, which will be rendered inside dialog.
61
61
  */
62
62
  this.childContent = null;
63
+ /** @hidden */
64
+ this._handlingDialogAction = false;
65
+ /** @hidden */
66
+ this._dismissedByAction = false;
67
+ this._component.setMobileModeConfig(this.mobileConfig);
63
68
  }
64
69
  /** @hidden */
65
70
  ngOnInit() {
@@ -67,22 +72,29 @@ class ComboboxMobileComponent extends MobileModeBase {
67
72
  }
68
73
  /** @hidden */
69
74
  handleDismiss() {
70
- this.dialogRef.dismiss();
71
- this._component.dialogDismiss(this._selectedBackup);
75
+ this._handlingDialogAction = true;
76
+ this._component.dialogDismiss();
77
+ this._dismissedByAction = true;
78
+ this._dismissDialog();
79
+ this._handlingDialogAction = false;
72
80
  }
73
81
  /** @hidden */
74
82
  handleApprove() {
75
- this.dialogRef.close();
83
+ this._handlingDialogAction = true;
76
84
  this._component.dialogApprove();
85
+ this._closeDialog();
86
+ this._handlingDialogAction = false;
77
87
  }
78
88
  /** @hidden */
79
89
  _toggleDialog(open) {
80
90
  if (open) {
81
- this._selectedBackup = this._component.getValue();
82
91
  if (!this._dialogService.hasOpenDialogs()) {
83
92
  this._open();
84
93
  }
85
94
  }
95
+ else if (!this._handlingDialogAction) {
96
+ this._closeDialog();
97
+ }
86
98
  }
87
99
  /** @hidden */
88
100
  _listenOnMultiInputOpenChange() {
@@ -92,8 +104,10 @@ class ComboboxMobileComponent extends MobileModeBase {
92
104
  }
93
105
  /** @hidden */
94
106
  _open() {
107
+ this._dismissedByAction = false;
95
108
  this.dialogRef = this._dialogService.open(this.dialogTemplate, {
96
109
  mobile: true,
110
+ focusTrapped: true,
97
111
  ...this.dialogConfig,
98
112
  backdropClickCloseable: false,
99
113
  container: this._elementRef.nativeElement,
@@ -101,15 +115,31 @@ class ComboboxMobileComponent extends MobileModeBase {
101
115
  });
102
116
  this._focusInputElementOnceOpened();
103
117
  const refSub = this.dialogRef.afterClosed.subscribe({
104
- error: (type) => {
105
- if (type === 'escape') {
106
- this._component.dialogDismiss(this._selectedBackup);
107
- refSub.unsubscribe();
118
+ error: () => {
119
+ if (this.dialogRef.status() === 'dismissed' && !this._dismissedByAction) {
120
+ this._component.dialogDismiss();
108
121
  }
122
+ refSub.unsubscribe();
109
123
  }
110
124
  });
111
125
  }
112
126
  /** @hidden */
127
+ _closeDialog() {
128
+ if (this._canCloseDialog()) {
129
+ this.dialogRef.close();
130
+ }
131
+ }
132
+ /** @hidden */
133
+ _dismissDialog() {
134
+ if (this._canCloseDialog()) {
135
+ this.dialogRef.dismiss();
136
+ }
137
+ }
138
+ /** @hidden */
139
+ _canCloseDialog() {
140
+ return (this.dialogRef?.isOpen() || this.dialogRef?.status() === 'pending') && !this.dialogRef.isClosed();
141
+ }
142
+ /** @hidden */
113
143
  _focusInputElementOnceOpened() {
114
144
  this.dialogRef.afterLoaded
115
145
  .pipe(observeOn(asyncScheduler), // making the listener async
@@ -127,7 +157,7 @@ class ComboboxMobileComponent extends MobileModeBase {
127
157
  });
128
158
  }
129
159
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ComboboxMobileComponent, deps: [{ token: COMBOBOX_COMPONENT }], target: i0.ɵɵFactoryTarget.Component }); }
130
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: ComboboxMobileComponent, isStandalone: true, selector: "fd-combobox-mobile", viewQueries: [{ propertyName: "dialogTemplate", first: true, predicate: ["dialogTemplate"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<ng-template [fdDialogTemplate] let-dialog let-dialogConfig=\"dialogConfig\" #dialogTemplate>\n <fd-dialog [dialogConfig]=\"dialogConfig\" [dialogRef]=\"dialog\">\n <fd-dialog-header>\n @if (mobileConfig.title) {\n <h1 fd-title>{{ mobileConfig.title }}</h1>\n }\n @if (mobileConfig.hasCloseButton) {\n <button title=\"Close\" fd-dialog-close-button [mobile]=\"true\" (click)=\"handleDismiss()\"></button>\n }\n <ng-template fdkTemplate=\"subheader\">\n <div fd-bar-middle>\n <fd-bar-element [fullWidth]=\"true\">\n <ng-template [ngTemplateOutlet]=\"childContent?.controlTemplate || null\"></ng-template>\n </fd-bar-element>\n </div>\n </ng-template>\n </fd-dialog-header>\n <fd-dialog-body>\n <ng-template [ngTemplateOutlet]=\"childContent?.listTemplate || null\"></ng-template>\n </fd-dialog-body>\n <fd-dialog-footer>\n @if (mobileConfig.approveButtonText) {\n <fd-button-bar fdType=\"emphasized\" [label]=\"mobileConfig.approveButtonText!\" (click)=\"handleApprove()\">\n </fd-button-bar>\n }\n @if (mobileConfig.cancelButtonText) {\n <fd-button-bar fdkInitialFocus [label]=\"mobileConfig.cancelButtonText!\" (click)=\"handleDismiss()\">\n </fd-button-bar>\n }\n </fd-dialog-footer>\n </fd-dialog>\n</ng-template>\n", dependencies: [{ kind: "directive", type: TemplateDirective, selector: "[fdkTemplate]", inputs: ["fdkTemplate"] }, { kind: "directive", type: BarMiddleDirective, selector: "[fd-bar-middle]", inputs: ["stackContentsVertically"] }, { kind: "directive", type: BarElementDirective, selector: "fd-bar-element", inputs: ["fullWidth"] }, { kind: "component", type: ButtonBarComponent, selector: "fd-button-bar", inputs: ["fullWidth", "fdType", "title", "ariaLabelledby", "id"] }, { kind: "component", type: DialogHeaderComponent, selector: "fd-dialog-header", inputs: ["inShellbar"] }, { kind: "component", type: DialogCloseButtonComponent, selector: "[fd-dialog-close-button]", inputs: ["mobile", "title", "ariaLabel"] }, { kind: "component", type: DialogComponent, selector: "fd-dialog", inputs: ["class", "dialogRef", "dialogConfig"] }, { kind: "component", type: DialogBodyComponent, selector: "fd-dialog-body", inputs: ["disablePaddings"] }, { kind: "component", type: DialogFooterComponent, selector: "fd-dialog-footer" }, { kind: "component", type: TitleComponent, selector: "[fd-title], [fdTitle]", inputs: ["twoLineClamp", "headerSize", "wrap"], exportAs: ["fd-title"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: InitialFocusDirective, selector: "[fdkInitialFocus]", inputs: ["fdkInitialFocus", "enabled", "focusLastElement"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
160
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: ComboboxMobileComponent, isStandalone: true, selector: "fd-combobox-mobile", viewQueries: [{ propertyName: "dialogTemplate", first: true, predicate: ["dialogTemplate"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<ng-template [fdDialogTemplate] let-dialog let-dialogConfig=\"dialogConfig\" #dialogTemplate>\n <fd-dialog [dialogConfig]=\"dialogConfig\" [dialogRef]=\"dialog\">\n <fd-dialog-header>\n @if (mobileConfig.title) {\n <h1 fd-title>{{ mobileConfig.title }}</h1>\n }\n @if (mobileConfig.hasCloseButton) {\n <button title=\"Close\" fd-dialog-close-button [mobile]=\"true\" (click)=\"handleDismiss()\"></button>\n }\n <ng-template fdkTemplate=\"subheader\">\n <div fd-bar-middle>\n <fd-bar-element [fullWidth]=\"true\">\n <ng-template [ngTemplateOutlet]=\"childContent?.controlTemplate || null\"></ng-template>\n </fd-bar-element>\n </div>\n </ng-template>\n </fd-dialog-header>\n <fd-dialog-body>\n @if (mobileConfig.instruction) {\n <p data-dialog-instruction>{{ mobileConfig.instruction }}</p>\n }\n <ng-template [ngTemplateOutlet]=\"childContent?.listTemplate || null\"></ng-template>\n </fd-dialog-body>\n <fd-dialog-footer>\n @if (_component.hasMobileApproveAction()) {\n <fd-button-bar fdType=\"emphasized\" [label]=\"mobileConfig.approveButtonText!\" (click)=\"handleApprove()\">\n </fd-button-bar>\n }\n @if (mobileConfig.cancelButtonText) {\n <fd-button-bar fdkInitialFocus [label]=\"mobileConfig.cancelButtonText!\" (click)=\"handleDismiss()\">\n </fd-button-bar>\n }\n </fd-dialog-footer>\n </fd-dialog>\n</ng-template>\n", dependencies: [{ kind: "directive", type: TemplateDirective, selector: "[fdkTemplate]", inputs: ["fdkTemplate"] }, { kind: "directive", type: BarMiddleDirective, selector: "[fd-bar-middle]", inputs: ["stackContentsVertically"] }, { kind: "directive", type: BarElementDirective, selector: "fd-bar-element", inputs: ["fullWidth"] }, { kind: "component", type: ButtonBarComponent, selector: "fd-button-bar", inputs: ["fullWidth", "fdType", "title", "ariaLabelledby", "id"] }, { kind: "component", type: DialogHeaderComponent, selector: "fd-dialog-header", inputs: ["inShellbar"] }, { kind: "component", type: DialogCloseButtonComponent, selector: "[fd-dialog-close-button]", inputs: ["mobile", "title", "ariaLabel"] }, { kind: "component", type: DialogComponent, selector: "fd-dialog", inputs: ["class", "dialogRef", "dialogConfig"] }, { kind: "component", type: DialogBodyComponent, selector: "fd-dialog-body", inputs: ["disablePaddings"] }, { kind: "component", type: DialogFooterComponent, selector: "fd-dialog-footer" }, { kind: "component", type: TitleComponent, selector: "[fd-title], [fdTitle]", inputs: ["twoLineClamp", "headerSize", "wrap"], exportAs: ["fd-title"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: InitialFocusDirective, selector: "[fdkInitialFocus]", inputs: ["fdkInitialFocus", "enabled", "focusLastElement"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
131
161
  }
132
162
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ComboboxMobileComponent, decorators: [{
133
163
  type: Component,
@@ -146,7 +176,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
146
176
  TemplateDirective,
147
177
  NgTemplateOutlet,
148
178
  InitialFocusDirective
149
- ], template: "<ng-template [fdDialogTemplate] let-dialog let-dialogConfig=\"dialogConfig\" #dialogTemplate>\n <fd-dialog [dialogConfig]=\"dialogConfig\" [dialogRef]=\"dialog\">\n <fd-dialog-header>\n @if (mobileConfig.title) {\n <h1 fd-title>{{ mobileConfig.title }}</h1>\n }\n @if (mobileConfig.hasCloseButton) {\n <button title=\"Close\" fd-dialog-close-button [mobile]=\"true\" (click)=\"handleDismiss()\"></button>\n }\n <ng-template fdkTemplate=\"subheader\">\n <div fd-bar-middle>\n <fd-bar-element [fullWidth]=\"true\">\n <ng-template [ngTemplateOutlet]=\"childContent?.controlTemplate || null\"></ng-template>\n </fd-bar-element>\n </div>\n </ng-template>\n </fd-dialog-header>\n <fd-dialog-body>\n <ng-template [ngTemplateOutlet]=\"childContent?.listTemplate || null\"></ng-template>\n </fd-dialog-body>\n <fd-dialog-footer>\n @if (mobileConfig.approveButtonText) {\n <fd-button-bar fdType=\"emphasized\" [label]=\"mobileConfig.approveButtonText!\" (click)=\"handleApprove()\">\n </fd-button-bar>\n }\n @if (mobileConfig.cancelButtonText) {\n <fd-button-bar fdkInitialFocus [label]=\"mobileConfig.cancelButtonText!\" (click)=\"handleDismiss()\">\n </fd-button-bar>\n }\n </fd-dialog-footer>\n </fd-dialog>\n</ng-template>\n" }]
179
+ ], template: "<ng-template [fdDialogTemplate] let-dialog let-dialogConfig=\"dialogConfig\" #dialogTemplate>\n <fd-dialog [dialogConfig]=\"dialogConfig\" [dialogRef]=\"dialog\">\n <fd-dialog-header>\n @if (mobileConfig.title) {\n <h1 fd-title>{{ mobileConfig.title }}</h1>\n }\n @if (mobileConfig.hasCloseButton) {\n <button title=\"Close\" fd-dialog-close-button [mobile]=\"true\" (click)=\"handleDismiss()\"></button>\n }\n <ng-template fdkTemplate=\"subheader\">\n <div fd-bar-middle>\n <fd-bar-element [fullWidth]=\"true\">\n <ng-template [ngTemplateOutlet]=\"childContent?.controlTemplate || null\"></ng-template>\n </fd-bar-element>\n </div>\n </ng-template>\n </fd-dialog-header>\n <fd-dialog-body>\n @if (mobileConfig.instruction) {\n <p data-dialog-instruction>{{ mobileConfig.instruction }}</p>\n }\n <ng-template [ngTemplateOutlet]=\"childContent?.listTemplate || null\"></ng-template>\n </fd-dialog-body>\n <fd-dialog-footer>\n @if (_component.hasMobileApproveAction()) {\n <fd-button-bar fdType=\"emphasized\" [label]=\"mobileConfig.approveButtonText!\" (click)=\"handleApprove()\">\n </fd-button-bar>\n }\n @if (mobileConfig.cancelButtonText) {\n <fd-button-bar fdkInitialFocus [label]=\"mobileConfig.cancelButtonText!\" (click)=\"handleDismiss()\">\n </fd-button-bar>\n }\n </fd-dialog-footer>\n </fd-dialog>\n</ng-template>\n" }]
150
180
  }], ctorParameters: () => [{ type: undefined, decorators: [{
151
181
  type: Inject,
152
182
  args: [COMBOBOX_COMPONENT]
@@ -355,7 +385,7 @@ class ComboboxComponent {
355
385
  fromEvent(document, 'mousedown')
356
386
  .pipe(takeUntilDestroyed(this._destroyRef))
357
387
  .subscribe((event) => {
358
- if (!this.closeOnOutsideClick) {
388
+ if (this.mobile || !this.closeOnOutsideClick) {
359
389
  return;
360
390
  }
361
391
  const target = event.target;
@@ -469,15 +499,35 @@ class ComboboxComponent {
469
499
  this.itemClicked.emit({ item: value, index });
470
500
  }
471
501
  }
472
- /** Handle dialog dismissing, closes popover and sets backup data. */
502
+ /**
503
+ * @hidden
504
+ * Receives the resolved mobile configuration from the mobile wrapper.
505
+ */
506
+ setMobileModeConfig(config) {
507
+ this._mobileModeConfig = config;
508
+ }
509
+ /**
510
+ * @hidden
511
+ * Whether the resolved mobile configuration provides a usable Approve action.
512
+ */
513
+ hasMobileApproveAction() {
514
+ return !!this._mobileModeConfig?.approveButtonText?.trim();
515
+ }
516
+ /** Handle dialog dismissing, restoring an unconfirmed mobile selection when needed. */
473
517
  dialogDismiss(term) {
474
- this.inputText = this.displayFn(term);
475
- this.setValue(term);
476
- this._lastConfirmedValue = term;
518
+ if (this._isMobileConfirmationMode()) {
519
+ this._restoreMobileConfirmationSnapshot();
520
+ }
521
+ else if (term !== undefined) {
522
+ this.inputText = this.displayFn(term);
523
+ this.setValue(term);
524
+ this._lastConfirmedValue = term;
525
+ }
477
526
  this.isOpenChangeHandle(false);
478
527
  }
479
528
  /** Handle dialog approval, closes popover and propagates data changes. */
480
529
  dialogApprove() {
530
+ this._confirmMobileSelection();
481
531
  this._propagateChange();
482
532
  this.isOpenChangeHandle(false);
483
533
  }
@@ -534,6 +584,9 @@ class ComboboxComponent {
534
584
  this.searchInputElement.nativeElement.value = this.inputTextValue;
535
585
  }
536
586
  this._lastConfirmedValue = valueToDisplay;
587
+ if (this.open && this._isMobileConfirmationMode()) {
588
+ this._captureMobileConfirmationSnapshot();
589
+ }
537
590
  this._cdRef.markForCheck();
538
591
  }
539
592
  /** @hidden */
@@ -578,6 +631,9 @@ class ComboboxComponent {
578
631
  if (this.mobile && !this.open) {
579
632
  this._resetDisplayedValues();
580
633
  }
634
+ if (isOpen && !this.open && this._isMobileConfirmationMode()) {
635
+ this._captureMobileConfirmationSnapshot();
636
+ }
581
637
  if (this.open !== isOpen) {
582
638
  this.open = isOpen;
583
639
  this.openChange.emit(isOpen);
@@ -603,6 +659,10 @@ class ComboboxComponent {
603
659
  /** Method that handles complete event from auto complete directive, setting the new value, and closing popover */
604
660
  handleAutoComplete(event) {
605
661
  if (this.inputText !== event.term) {
662
+ const matchingValues = this._getOptionObjectByDisplayedValue(event.term);
663
+ if (matchingValues.length === 1) {
664
+ this._lastConfirmedValue = matchingValues[0];
665
+ }
606
666
  this.inputText = event.term;
607
667
  this.handleSearchTermChange();
608
668
  }
@@ -634,6 +694,30 @@ class ComboboxComponent {
634
694
  }
635
695
  /** @hidden */
636
696
  _close() {
697
+ const completedValue = this.tabOutStrategy === 'closeAndSelect' ? this._getCompletedAutocompleteValue() : undefined;
698
+ if (completedValue !== undefined) {
699
+ if (completedValue !== this._lastConfirmedValue) {
700
+ this._commitCompletedAutocompleteValue(completedValue);
701
+ }
702
+ if (this.open) {
703
+ this.isOpenChangeHandle(false);
704
+ }
705
+ this.searchInputElement.nativeElement.focus();
706
+ return;
707
+ }
708
+ if (this.tabOutStrategy === 'closeAndSelect' && !this.communicateByObject) {
709
+ this.searchInputElement.nativeElement.value = this.inputText;
710
+ this.isOpenChangeHandle(false);
711
+ this.searchInputElement.nativeElement.focus();
712
+ return;
713
+ }
714
+ // When autoComplete is disabled, the user is in free-text mode.
715
+ // Typed text is intentional and must not be reverted on close.
716
+ if (!this.autoComplete) {
717
+ this._lastConfirmedValue = this.inputText;
718
+ this.isOpenChangeHandle(false);
719
+ return;
720
+ }
637
721
  const revertText = this._lastConfirmedValue != null ? this.displayFn(this._lastConfirmedValue) : '';
638
722
  this.inputText = revertText;
639
723
  this.searchInputElement.nativeElement.value = revertText;
@@ -664,6 +748,26 @@ class ComboboxComponent {
664
748
  const expected = this._lastConfirmedValue != null ? this.displayFn(this._lastConfirmedValue) : '';
665
749
  return this.inputText !== expected;
666
750
  }
751
+ /** @hidden */
752
+ _getCompletedAutocompleteValue() {
753
+ const nativeInput = this.searchInputElement.nativeElement;
754
+ const nativeValue = nativeInput.value;
755
+ const hasSelectedSuffix = nativeValue !== this.inputText &&
756
+ nativeInput.selectionStart === this.inputText.length &&
757
+ nativeInput.selectionEnd === nativeValue.length;
758
+ if (nativeValue !== this.inputText && !hasSelectedSuffix) {
759
+ return;
760
+ }
761
+ const matchingValues = this._getOptionObjectByDisplayedValue(nativeValue);
762
+ return matchingValues.length === 1 ? matchingValues[0] : undefined;
763
+ }
764
+ /** @hidden */
765
+ _commitCompletedAutocompleteValue(value) {
766
+ this._lastConfirmedValue = value;
767
+ this.setValue(value);
768
+ this.inputText = this.displayFn(value);
769
+ this.searchInputElement.nativeElement.value = this.inputText;
770
+ }
667
771
  /** Method that picks other value moved from current one by offset, called only when combobox is closed */
668
772
  _chooseOtherItem(offset) {
669
773
  const activeValue = this._getOptionObjectByDisplayedValue(this.inputTextValue)[0];
@@ -708,19 +812,23 @@ class ComboboxComponent {
708
812
  }
709
813
  /** @hidden */
710
814
  _handleClickActions(term, shouldClosePopover = true) {
711
- if (this.closeOnSelect && shouldClosePopover) {
712
- this.isOpenChangeHandle(false);
815
+ const confirmationMode = this._isMobileConfirmationMode();
816
+ if (!confirmationMode) {
817
+ this._lastConfirmedValue = term;
713
818
  }
714
- this._lastConfirmedValue = term;
715
819
  if (this.fillOnSelect) {
716
820
  this.setValue(term);
717
- this.inputText = this.displayFn(term);
718
- this.searchInputElement.nativeElement.value = this.inputText;
821
+ const displayText = this.displayFn(term);
822
+ this.searchInputElement.nativeElement.value = displayText;
823
+ this.inputText = displayText;
719
824
  this._cdRef.detectChanges();
720
- if (this.mobile) {
825
+ if (this.mobile && !confirmationMode) {
721
826
  this._propagateChange();
722
827
  }
723
828
  }
829
+ if (!confirmationMode && this.closeOnSelect && shouldClosePopover) {
830
+ this.isOpenChangeHandle(false);
831
+ }
724
832
  if (shouldClosePopover) {
725
833
  this.handleSearchTermChange();
726
834
  }
@@ -730,6 +838,42 @@ class ComboboxComponent {
730
838
  return this.dropdownValues.filter((value) => this.displayFn(value) === displayValue);
731
839
  }
732
840
  /** @hidden */
841
+ _isMobileConfirmationMode() {
842
+ return this.mobile && this.hasMobileApproveAction();
843
+ }
844
+ /** @hidden */
845
+ _captureMobileConfirmationSnapshot() {
846
+ this._mobileConfirmationSnapshot = {
847
+ inputText: this.inputTextValue,
848
+ nativeInputValue: this.searchInputElement?.nativeElement.value ?? this.inputTextValue,
849
+ value: this._value,
850
+ lastConfirmedValue: this._lastConfirmedValue
851
+ };
852
+ }
853
+ /** @hidden */
854
+ _restoreMobileConfirmationSnapshot() {
855
+ const snapshot = this._mobileConfirmationSnapshot;
856
+ if (!snapshot) {
857
+ return;
858
+ }
859
+ this.inputText = snapshot.inputText;
860
+ this._value = snapshot.value;
861
+ this._lastConfirmedValue = snapshot.lastConfirmedValue;
862
+ if (this.searchInputElement?.nativeElement) {
863
+ this.searchInputElement.nativeElement.value = snapshot.nativeInputValue;
864
+ }
865
+ this._cdRef.markForCheck();
866
+ }
867
+ /** @hidden */
868
+ _confirmMobileSelection() {
869
+ if (!this._isMobileConfirmationMode()) {
870
+ return;
871
+ }
872
+ const selectedValues = this._getOptionObjectByDisplayedValue(this.inputText);
873
+ this._lastConfirmedValue =
874
+ this.communicateByObject && selectedValues.length === 1 ? selectedValues[0] : this.inputText;
875
+ }
876
+ /** @hidden */
733
877
  _refreshDisplayedValues() {
734
878
  if (this.inputText) {
735
879
  this.displayedValues = this.filterFn(this.dropdownValues, this.inputText);
@@ -820,7 +964,7 @@ class ComboboxComponent {
820
964
  provide: FD_COMBOBOX_COMPONENT,
821
965
  useExisting: ComboboxComponent
822
966
  }
823
- ], queries: [{ propertyName: "_comboboxItemRenderer", first: true, predicate: ComboboxItemDirective, descendants: true }, { propertyName: "listMessages", predicate: FD_LIST_MESSAGE_DIRECTIVE }], viewQueries: [{ propertyName: "listComponent", first: true, predicate: ListComponent, descendants: true }, { propertyName: "searchInputElement", first: true, predicate: ["searchInputElement"], descendants: true }, { propertyName: "popoverComponent", first: true, predicate: PopoverComponent, descendants: true }, { propertyName: "inputGroup", first: true, predicate: InputGroupComponent, descendants: true }, { propertyName: "controlTemplate", first: true, predicate: ["controlTemplate"], descendants: true }, { propertyName: "listTemplate", first: true, predicate: ["listTemplate"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<ng-template [ngTemplateOutlet]=\"mobile ? mobileTemplate : desktopTemplate\"></ng-template>\n<ng-template #desktopTemplate>\n <fd-popover\n additionalBodyClass=\"fd-popover-custom-list\"\n [class.fd-combobox-full-width]=\"isSearch || showClearButton\"\n [isOpen]=\"open && displayedValues && displayedValues.length > 0\"\n (isOpenChange)=\"isOpenChangeHandle($event)\"\n [fillControlMode]=\"fillControlMode\"\n [scrollStrategy]=\"_repositionScrollStrategy\"\n [focusTrapped]=\"true\"\n [focusAutoCapture]=\"false\"\n [triggers]=\"triggers\"\n [disabled]=\"disabled || readOnly\"\n [maxWidth]=\"!mobile && noDropDownMaxWidth ? null : dropDownMaxWidthPx\"\n [style.width]=\"width && '100%'\"\n [closeOnOutsideClick]=\"closeOnOutsideClick\"\n >\n <fd-popover-control>\n <ng-template [ngTemplateOutlet]=\"controlTemplate\"></ng-template>\n </fd-popover-control>\n <fd-popover-body [hidden]=\"!displayedValues.length\">\n <ng-template [ngTemplateOutlet]=\"listTemplate\"></ng-template>\n <ng-content></ng-content>\n </fd-popover-body>\n </fd-popover>\n</ng-template>\n<ng-template let-term=\"term\" #itemSource>\n @if (!_customRenderer) {\n <span\n fd-list-title\n fdTruncatedTitle\n [innerHTML]=\"term | displayFnPipe: displayFn | highlight: inputText : highlighting && filterHighlight\"\n >\n </span>\n } @else {\n <ng-template\n [ngTemplateOutlet]=\"_customRenderer\"\n [ngTemplateOutletContext]=\"{ $implicit: term, inputText: inputText }\"\n ></ng-template>\n }\n</ng-template>\n<ng-template #mobileTemplate>\n <ng-template [ngTemplateOutlet]=\"controlTemplate\"></ng-template>\n</ng-template>\n<ng-template #controlTemplate>\n <fd-input-group\n [button]=\"showDropdownButton\"\n [glyph]=\"showDropdownButton ? glyphValue : null\"\n [glyphFont]=\"isSearch ? _defaultFontFamily : glyphFont\"\n [state]=\"state\"\n [buttonFocusable]=\"buttonFocusable\"\n [disabled]=\"disabled\"\n [readonly]=\"readOnly\"\n [isControl]=\"true\"\n [isExpanded]=\"!mobile && open && displayedValues.length > 0\"\n [showFocus]=\"!clearInputBtnFocused\"\n [glyphAriaLabel]=\"ariaLabel || ('platformMultiCombobox.inputGlyphAriaLabel' | fdTranslate)()\"\n [iconTitle]=\"title || ('platformMultiCombobox.inputGlyphAriaLabel' | fdTranslate)()\"\n (addOnButtonClicked)=\"onPrimaryButtonClick()\"\n (click)=\"mobile && isOpenChangeHandle(true)\"\n >\n <input\n #searchInputElement\n fdkAutoComplete\n fd-input-group-input\n type=\"text\"\n role=\"combobox\"\n autocomplete=\"off\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-labelledby]=\"ariaLabelledBy\"\n [attr.aria-describedby]=\"comboboxId + '-list-results'\"\n [attr.aria-autocomplete]=\"autoComplete && !mobile ? 'list' : null\"\n [attr.aria-haspopup]=\"autoComplete && !mobile\"\n [attr.aria-expanded]=\"!mobile && open && displayedValues.length\"\n [attr.aria-required]=\"required\"\n [attr.tabindex]=\"readOnly || disabled ? -1 : null\"\n [enable]=\"autoComplete && !mobile\"\n [displayFn]=\"displayFn\"\n [options]=\"dropdownValues\"\n [inputText]=\"inputText\"\n [disabled]=\"disabled\"\n [readonly]=\"readOnly\"\n [attr.aria-readonly]=\"readOnly\"\n [placeholder]=\"placeholder\"\n [id]=\"inputId\"\n [(ngModel)]=\"inputText\"\n (onComplete)=\"handleAutoComplete($event)\"\n (keydown)=\"onInputKeydownHandler($event)\"\n (paste)=\"onInputKeydownHandler('fromPaste')\"\n (ngModelChange)=\"handleSearchTermChange()\"\n (blur)=\"handleBlur()\"\n />\n @if ((isSearch || showClearButton) && inputText && inputText.length > 0) {\n <span\n class=\"fd-input-group__addon fd-input-group__addon--button\"\n [class.fd-shellbar__input-group-addon]=\"inShellbar\"\n >\n <button\n fd-button\n class=\"fd-input-group__button\"\n type=\"button\"\n [fdType]=\"inShellbar ? 'standard' : 'transparent'\"\n [title]=\"_clearButtonTitle()\"\n [class.fd-shellbar__button]=\"inShellbar\"\n [attr.tabindex]=\"clearButtonFocusable ? 0 : -1\"\n (focus)=\"clearInputBtnFocus()\"\n (blur)=\"clearInputBtnBlur()\"\n (click)=\"_handleClearSearchTerm()\"\n >\n <fd-icon glyph=\"decline\"></fd-icon>\n </button>\n </span>\n }\n </fd-input-group>\n <div [id]=\"comboboxId + '-list-results'\" class=\"fd-combobox-count-list-results\">\n {{ displayedValues.length || 0 }} result list items\n </div>\n</ng-template>\n<ng-template #listTemplate>\n @if (groupFn) {\n <div\n class=\"fd-combobox-custom-list\"\n [style.maxHeight]=\"!mobile && maxHeight\"\n (keydown.tab)=\"_close()\"\n (keydown.shift.tab)=\"_close()\"\n >\n <ng-content></ng-content>\n @for (group of displayedValues | listGroupPipe: groupFn; track group.key; let groupIndex = $index) {\n <label class=\"fd-list__group-header\" [id]=\"comboboxId + '-group-header-' + groupIndex\">\n <span fd-list-title>{{ group.key }}</span>\n </label>\n <ul\n fd-list\n [dropdownMode]=\"true\"\n [id]=\"comboboxId + '-result-' + groupIndex\"\n role=\"listbox\"\n [attr.aria-labelledby]=\"comboboxId + '-group-header-' + groupIndex\"\n [hasMessage]=\"listMessages && listMessages.length > 0\"\n [byline]=\"byline\"\n [tabindex]=\"groupIndex === 0 ? 0 : -1\"\n (focusEscapeList)=\"handleListFocusEscape($event)\"\n >\n @for (term of group.value; track $index; let index = $index) {\n <li\n fd-list-item\n ariaRole=\"option\"\n [attr.aria-placeholder]=\"group.key\"\n [attr.aria-setsize]=\"group.value.length\"\n [attr.aria-posinset]=\"index + 1\"\n class=\"fd-combobox-list-item\"\n [selected]=\"isSelected(term)\"\n [value]=\"term\"\n (keydown)=\"onItemKeyDownHandler($event, term)\"\n (mousedown)=\"_itemMousedown = true\"\n (click)=\"onMenuClickHandler(term)\"\n (focus)=\"onItemFocused(term)\"\n >\n <ng-template\n [ngTemplateOutlet]=\"itemSource\"\n [ngTemplateOutletContext]=\"{ term: term }\"\n ></ng-template>\n </li>\n }\n </ul>\n }\n </div>\n } @else {\n <ul\n fd-list\n class=\"fd-combobox-custom-list\"\n [dropdownMode]=\"true\"\n [id]=\"comboboxId + '-result'\"\n role=\"listbox\"\n [attr.aria-labelledby]=\"comboboxId + '-search'\"\n [style.maxHeight]=\"!mobile && maxHeight\"\n [hasMessage]=\"listMessages && listMessages.length > 0\"\n [byline]=\"byline\"\n [tabindex]=\"0\"\n (keydown.tab)=\"_close()\"\n (keydown.shift.tab)=\"_close()\"\n (focusEscapeList)=\"handleListFocusEscape($event)\"\n >\n <ng-content></ng-content>\n @for (term of displayedValues; track $index) {\n <li\n fd-list-item\n ariaRole=\"option\"\n [tabindex]=\"0\"\n class=\"fd-combobox-list-item\"\n [selected]=\"isSelected(term)\"\n (keydown)=\"onItemKeyDownHandler($event, term)\"\n (mousedown)=\"_itemMousedown = true\"\n (click)=\"onMenuClickHandler(term)\"\n [value]=\"term\"\n (focus)=\"onItemFocused(term)\"\n >\n <ng-template\n [ngTemplateOutlet]=\"itemSource\"\n [ngTemplateOutletContext]=\"{ term: term }\"\n ></ng-template>\n </li>\n }\n </ul>\n }\n</ng-template>\n", styles: [".fd-combobox-custom-class,.fd-combobox-custom-class .fd-combobox-shellbar-custom{display:inline-block}.fd-combobox-custom-list.fd-list--dropdown .fd-list__item.fd-list__group-header{border-bottom:var(--sapList_BorderWidth) solid var(--sapList_GroupHeaderBorderColor)}.fd-list__item.fd-combobox-list-item{cursor:pointer}.fd-combobox-full-width{width:100%}.fd-combobox-count-list-results{position:absolute;opacity:0;z-index:-1}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: PopoverComponent, selector: "fd-popover", inputs: ["config", "title", "trigger", "id", "mobile", "mobileConfig", "preventSpaceKeyScroll", "placement", "maxWidth", "fillControlMode", "closeOnOutsideClick", "closeOnEscapeKey", "disabled", "triggers", "focusTrapped", "focusAutoCapture", "restoreFocusOnClose", "noArrow", "disableScrollbar", "appendTo", "placementContainer", "scrollStrategy", "cdkPositions", "applyOverlay", "additionalBodyClass", "additionalTriggerClass", "closeOnNavigation", "fixedPosition", "resizable", "bodyAriaLabel", "bodyRole", "bodyAriaLabelledBy", "isOpen"], outputs: ["triggerChange", "isOpenChange", "beforeOpen"] }, { kind: "component", type: PopoverControlComponent, selector: "fd-popover-control, [fdPopoverControl]" }, { kind: "component", type: PopoverBodyComponent, selector: "fd-popover-body", inputs: ["minWidth", "maxWidth", "minHeight", "maxHeight", "ariaModal"], outputs: ["onClose"] }, { kind: "component", type: ListComponent, selector: "[fd-list], [fdList]", inputs: ["dropdownMode", "multiInputMode", "mobileMode", "hasMessage", "noBorder", "navigationIndicator", "selection", "keyboardSupport", "byline", "subline", "theme", "unreadIndicator", "role", "settingsList", "settingsListFooter", "searchResultsList"], outputs: ["focusEscapeList"] }, { kind: "component", type: ListItemComponent, selector: "[fdListItem] ,[fd-list-item]", inputs: ["selected", "noData", "action", "interactive", "growing", "counter", "counterRole", "counterAriaLabel", "active", "unread", "byline", "ariaRole", "id", "preventClick", "settingsListTpl", "suggestion"], outputs: ["keyDown"], exportAs: ["fdListItem"] }, { kind: "directive", type: ListTitleDirective, selector: "[fd-list-title], [fdListTitle]", inputs: ["wrap", "truncate", "scope"] }, { kind: "component", type: InputGroupComponent, selector: "fd-input-group", inputs: ["placement", "required", "inline", "addOnText", "buttonFocusable", "type", "glyph", "glyphFont", "button", "isControl", "showFocus", "isExpanded", "glyphAriaLabel", "addonButtonAriaHidden", "iconTitle", "ariaLabelledBy", "ariaLabel"], outputs: ["addOnButtonClicked", "search"] }, { kind: "directive", type: InputGroupInputDirective, selector: "[fdInputGroupInput], [fd-input-group-input]", inputs: ["class"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: AutoCompleteDirective, selector: "[fdkAutoComplete]", inputs: ["options", "inputText", "enable", "displayFn", "matcher"], outputs: ["onComplete"] }, { kind: "component", type: ButtonComponent, selector: "button[fd-button], a[fd-button], span[fd-button]", inputs: ["id"], exportAs: ["fd-button"] }, { kind: "component", type: IconComponent, selector: "fd-icon", inputs: ["glyph", "font", "color", "background", "size", "class", "ariaLabel", "ariaHidden"], outputs: ["ariaHiddenChange"] }, { kind: "ngmodule", type: ContentDensityModule }, { kind: "directive", type: TruncatedTitleDirective, selector: "[fdkTruncatedTitle], [fdTruncatedTitle], [fd-truncate-title]" }, { kind: "pipe", type: DisplayFnPipe, name: "displayFnPipe" }, { kind: "pipe", type: SearchHighlightPipe, name: "highlight" }, { kind: "pipe", type: FdTranslatePipe, name: "fdTranslate" }, { kind: "pipe", type: ListGroupPipe, name: "listGroupPipe" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
967
+ ], queries: [{ propertyName: "_comboboxItemRenderer", first: true, predicate: ComboboxItemDirective, descendants: true }, { propertyName: "listMessages", predicate: FD_LIST_MESSAGE_DIRECTIVE }], viewQueries: [{ propertyName: "listComponent", first: true, predicate: ListComponent, descendants: true }, { propertyName: "searchInputElement", first: true, predicate: ["searchInputElement"], descendants: true }, { propertyName: "popoverComponent", first: true, predicate: PopoverComponent, descendants: true }, { propertyName: "inputGroup", first: true, predicate: InputGroupComponent, descendants: true }, { propertyName: "controlTemplate", first: true, predicate: ["controlTemplate"], descendants: true }, { propertyName: "listTemplate", first: true, predicate: ["listTemplate"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<ng-template [ngTemplateOutlet]=\"mobile ? mobileTemplate : desktopTemplate\"></ng-template>\n<ng-template #desktopTemplate>\n <fd-popover\n additionalBodyClass=\"fd-popover-custom-list\"\n [class.fd-combobox-full-width]=\"isSearch || showClearButton\"\n [isOpen]=\"open && displayedValues && displayedValues.length > 0\"\n (isOpenChange)=\"isOpenChangeHandle($event)\"\n [fillControlMode]=\"fillControlMode\"\n [scrollStrategy]=\"_repositionScrollStrategy\"\n [focusTrapped]=\"true\"\n [focusAutoCapture]=\"false\"\n [triggers]=\"triggers\"\n [disabled]=\"disabled || readOnly\"\n [maxWidth]=\"!mobile && noDropDownMaxWidth ? null : dropDownMaxWidthPx\"\n [style.width]=\"width && '100%'\"\n [closeOnOutsideClick]=\"closeOnOutsideClick\"\n >\n <fd-popover-control>\n <ng-template [ngTemplateOutlet]=\"controlTemplate\"></ng-template>\n </fd-popover-control>\n <fd-popover-body [hidden]=\"!displayedValues.length\">\n <ng-template [ngTemplateOutlet]=\"listTemplate\"></ng-template>\n <ng-content></ng-content>\n </fd-popover-body>\n </fd-popover>\n</ng-template>\n<ng-template let-term=\"term\" #itemSource>\n @if (!_customRenderer) {\n <span\n fd-list-title\n fdTruncatedTitle\n [innerHTML]=\"term | displayFnPipe: displayFn | highlight: inputText : highlighting && filterHighlight\"\n >\n </span>\n } @else {\n <ng-template\n [ngTemplateOutlet]=\"_customRenderer\"\n [ngTemplateOutletContext]=\"{ $implicit: term, inputText: inputText }\"\n ></ng-template>\n }\n</ng-template>\n<ng-template #mobileTemplate>\n <ng-template [ngTemplateOutlet]=\"controlTemplate\"></ng-template>\n</ng-template>\n<ng-template #controlTemplate>\n <fd-input-group\n [button]=\"showDropdownButton\"\n [glyph]=\"showDropdownButton ? glyphValue : null\"\n [glyphFont]=\"isSearch ? _defaultFontFamily : glyphFont\"\n [state]=\"state\"\n [buttonFocusable]=\"buttonFocusable\"\n [disabled]=\"disabled\"\n [readonly]=\"readOnly\"\n [isControl]=\"true\"\n [isExpanded]=\"!mobile && open && displayedValues.length > 0\"\n [showFocus]=\"!clearInputBtnFocused\"\n [glyphAriaLabel]=\"ariaLabel || ('platformMultiCombobox.inputGlyphAriaLabel' | fdTranslate)()\"\n [iconTitle]=\"title || ('platformMultiCombobox.inputGlyphAriaLabel' | fdTranslate)()\"\n (addOnButtonClicked)=\"onPrimaryButtonClick()\"\n (click)=\"mobile && isOpenChangeHandle(true)\"\n >\n <input\n #searchInputElement\n fdkAutoComplete\n fd-input-group-input\n type=\"text\"\n role=\"combobox\"\n autocomplete=\"off\"\n [attr.aria-label]=\"ariaLabel\"\n [attr.aria-labelledby]=\"ariaLabelledBy\"\n [attr.aria-describedby]=\"comboboxId + '-list-results'\"\n [attr.aria-autocomplete]=\"autoComplete && !mobile ? 'list' : null\"\n [attr.aria-haspopup]=\"autoComplete && !mobile\"\n [attr.aria-expanded]=\"!mobile && open && displayedValues.length\"\n [attr.aria-required]=\"required\"\n [attr.tabindex]=\"readOnly || disabled ? -1 : null\"\n [enable]=\"autoComplete && !mobile\"\n [displayFn]=\"displayFn\"\n [options]=\"dropdownValues\"\n [inputText]=\"inputText\"\n [disabled]=\"disabled\"\n [readonly]=\"readOnly\"\n [attr.aria-readonly]=\"readOnly\"\n [placeholder]=\"placeholder\"\n [id]=\"inputId\"\n [(ngModel)]=\"inputText\"\n (onComplete)=\"handleAutoComplete($event)\"\n (keydown)=\"onInputKeydownHandler($event)\"\n (paste)=\"onInputKeydownHandler('fromPaste')\"\n (ngModelChange)=\"handleSearchTermChange()\"\n (blur)=\"handleBlur()\"\n />\n @if ((isSearch || showClearButton) && inputText && inputText.length > 0) {\n <span\n class=\"fd-input-group__addon fd-input-group__addon--button\"\n [class.fd-shellbar__input-group-addon]=\"inShellbar\"\n >\n <button\n fd-button\n class=\"fd-input-group__button\"\n type=\"button\"\n [fdType]=\"inShellbar ? 'standard' : 'transparent'\"\n [title]=\"_clearButtonTitle()\"\n [class.fd-shellbar__button]=\"inShellbar\"\n [attr.tabindex]=\"clearButtonFocusable ? 0 : -1\"\n (focus)=\"clearInputBtnFocus()\"\n (blur)=\"clearInputBtnBlur()\"\n (click)=\"_handleClearSearchTerm()\"\n >\n <fd-icon glyph=\"decline\"></fd-icon>\n </button>\n </span>\n }\n </fd-input-group>\n <div [id]=\"comboboxId + '-list-results'\" class=\"fd-combobox-count-list-results\">\n {{ displayedValues.length || 0 }} result list items\n </div>\n</ng-template>\n<ng-template #listTemplate>\n @if (groupFn) {\n <div\n class=\"fd-combobox-custom-list\"\n [style.maxHeight]=\"!mobile && maxHeight\"\n (keydown.tab)=\"_close()\"\n (keydown.shift.tab)=\"_close()\"\n >\n <ng-content></ng-content>\n @for (group of displayedValues | listGroupPipe: groupFn; track group.key; let groupIndex = $index) {\n <label class=\"fd-list__group-header\" [id]=\"comboboxId + '-group-header-' + groupIndex\">\n <span fd-list-title>{{ group.key }}</span>\n </label>\n <ul\n fd-list\n [dropdownMode]=\"true\"\n [id]=\"comboboxId + '-result-' + groupIndex\"\n role=\"listbox\"\n [attr.aria-labelledby]=\"comboboxId + '-group-header-' + groupIndex\"\n [hasMessage]=\"listMessages && listMessages.length > 0\"\n [byline]=\"byline\"\n [tabindex]=\"groupIndex === 0 ? 0 : -1\"\n (focusEscapeList)=\"handleListFocusEscape($event)\"\n >\n @for (term of group.value; track $index; let index = $index) {\n <li\n fd-list-item\n ariaRole=\"option\"\n [attr.aria-placeholder]=\"group.key\"\n [attr.aria-setsize]=\"group.value.length\"\n [attr.aria-posinset]=\"index + 1\"\n class=\"fd-combobox-list-item\"\n [selected]=\"isSelected(term)\"\n [value]=\"term\"\n (keydown)=\"onItemKeyDownHandler($event, term)\"\n (mousedown)=\"_itemMousedown = true\"\n (click)=\"onMenuClickHandler(term)\"\n (focus)=\"onItemFocused(term)\"\n >\n <ng-template\n [ngTemplateOutlet]=\"itemSource\"\n [ngTemplateOutletContext]=\"{ term: term }\"\n ></ng-template>\n </li>\n }\n </ul>\n }\n </div>\n } @else {\n <ul\n fd-list\n class=\"fd-combobox-custom-list\"\n [dropdownMode]=\"true\"\n [id]=\"comboboxId + '-result'\"\n role=\"listbox\"\n [attr.aria-labelledby]=\"comboboxId + '-search'\"\n [style.maxHeight]=\"!mobile && maxHeight\"\n [hasMessage]=\"listMessages && listMessages.length > 0\"\n [byline]=\"byline\"\n [tabindex]=\"0\"\n (keydown.tab)=\"_close()\"\n (keydown.shift.tab)=\"_close()\"\n (focusEscapeList)=\"handleListFocusEscape($event)\"\n >\n <ng-content></ng-content>\n @for (term of displayedValues; track $index) {\n <li\n fd-list-item\n ariaRole=\"option\"\n [tabindex]=\"0\"\n class=\"fd-combobox-list-item\"\n [selected]=\"isSelected(term)\"\n (keydown)=\"onItemKeyDownHandler($event, term)\"\n (mousedown)=\"_itemMousedown = true\"\n (click)=\"onMenuClickHandler(term)\"\n [value]=\"term\"\n (focus)=\"onItemFocused(term)\"\n >\n <ng-template\n [ngTemplateOutlet]=\"itemSource\"\n [ngTemplateOutletContext]=\"{ term: term }\"\n ></ng-template>\n </li>\n }\n </ul>\n }\n</ng-template>\n", styles: [".fd-combobox-custom-class,.fd-combobox-custom-class .fd-combobox-shellbar-custom{display:inline-block}.fd-combobox-custom-list.fd-list--dropdown .fd-list__item.fd-list__group-header{border-bottom:var(--sapList_BorderWidth) solid var(--sapList_GroupHeaderBorderColor)}.fd-list__item.fd-combobox-list-item{cursor:pointer}.fd-combobox-full-width{width:100%}.fd-combobox-count-list-results{position:absolute;opacity:0;z-index:-1}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: PopoverComponent, selector: "fd-popover", inputs: ["config", "title", "trigger", "id", "mobile", "mobileConfig", "preventSpaceKeyScroll", "placement", "maxWidth", "fillControlMode", "closeOnOutsideClick", "closeOnEscapeKey", "disabled", "triggers", "focusTrapped", "focusAutoCapture", "restoreFocusOnClose", "noArrow", "disableScrollbar", "appendTo", "placementContainer", "scrollStrategy", "cdkPositions", "applyOverlay", "additionalBodyClass", "additionalTriggerClass", "closeOnNavigation", "fixedPosition", "resizable", "bodyAriaLabel", "bodyRole", "bodyAriaLabelledBy", "isOpen"], outputs: ["triggerChange", "isOpenChange", "beforeOpen"] }, { kind: "component", type: PopoverControlComponent, selector: "fd-popover-control, [fdPopoverControl]" }, { kind: "component", type: PopoverBodyComponent, selector: "fd-popover-body", inputs: ["minWidth", "maxWidth", "minHeight", "maxHeight", "ariaModal"], outputs: ["onClose"] }, { kind: "component", type: ListComponent, selector: "[fd-list], [fdList]", inputs: ["dropdownMode", "multiInputMode", "mobileMode", "hasMessage", "noBorder", "navigationIndicator", "selection", "keyboardSupport", "byline", "subline", "theme", "unreadIndicator", "role", "settingsList", "settingsListFooter", "notification", "searchResultsList"], outputs: ["focusEscapeList"] }, { kind: "component", type: ListItemComponent, selector: "[fdListItem] ,[fd-list-item]", inputs: ["selected", "noData", "action", "interactive", "growing", "counter", "counterRole", "counterAriaLabel", "active", "unread", "byline", "ariaRole", "id", "preventClick", "settingsListTpl", "suggestion"], outputs: ["keyDown"], exportAs: ["fdListItem"] }, { kind: "directive", type: ListTitleDirective, selector: "[fd-list-title], [fdListTitle]", inputs: ["wrap", "truncate", "scope"] }, { kind: "component", type: InputGroupComponent, selector: "fd-input-group", inputs: ["placement", "required", "inline", "addOnText", "buttonFocusable", "type", "glyph", "glyphFont", "button", "isControl", "showFocus", "isExpanded", "glyphAriaLabel", "addonButtonAriaHidden", "iconTitle", "ariaLabelledBy", "ariaLabel"], outputs: ["addOnButtonClicked", "search"] }, { kind: "directive", type: InputGroupInputDirective, selector: "[fdInputGroupInput], [fd-input-group-input]", inputs: ["class"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: AutoCompleteDirective, selector: "[fdkAutoComplete]", inputs: ["options", "inputText", "enable", "displayFn", "matcher"], outputs: ["onComplete"] }, { kind: "component", type: ButtonComponent, selector: "button[fd-button], a[fd-button], span[fd-button]", inputs: ["id"], exportAs: ["fd-button"] }, { kind: "component", type: IconComponent, selector: "fd-icon", inputs: ["glyph", "font", "color", "background", "size", "class", "ariaLabel", "ariaHidden"], outputs: ["ariaHiddenChange"] }, { kind: "ngmodule", type: ContentDensityModule }, { kind: "directive", type: TruncatedTitleDirective, selector: "[fdkTruncatedTitle], [fdTruncatedTitle], [fd-truncate-title]" }, { kind: "pipe", type: DisplayFnPipe, name: "displayFnPipe" }, { kind: "pipe", type: SearchHighlightPipe, name: "highlight" }, { kind: "pipe", type: FdTranslatePipe, name: "fdTranslate" }, { kind: "pipe", type: ListGroupPipe, name: "listGroupPipe" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
824
968
  }
825
969
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ComboboxComponent, decorators: [{
826
970
  type: Component,