@fundamental-ngx/core 0.61.4 → 0.61.5

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 (31) hide show
  1. package/fesm2022/fundamental-ngx-core-breadcrumb.mjs +1 -1
  2. package/fesm2022/fundamental-ngx-core-breadcrumb.mjs.map +1 -1
  3. package/fesm2022/fundamental-ngx-core-carousel.mjs +7 -8
  4. package/fesm2022/fundamental-ngx-core-carousel.mjs.map +1 -1
  5. package/fesm2022/fundamental-ngx-core-form.mjs +10 -16
  6. package/fesm2022/fundamental-ngx-core-form.mjs.map +1 -1
  7. package/fesm2022/fundamental-ngx-core-icon.mjs +2 -2
  8. package/fesm2022/fundamental-ngx-core-icon.mjs.map +1 -1
  9. package/fesm2022/fundamental-ngx-core-inline-help.mjs +34 -15
  10. package/fesm2022/fundamental-ngx-core-inline-help.mjs.map +1 -1
  11. package/fesm2022/fundamental-ngx-core-menu.mjs +40 -28
  12. package/fesm2022/fundamental-ngx-core-menu.mjs.map +1 -1
  13. package/fesm2022/fundamental-ngx-core-multi-combobox.mjs +75 -31
  14. package/fesm2022/fundamental-ngx-core-multi-combobox.mjs.map +1 -1
  15. package/fesm2022/fundamental-ngx-core-popover.mjs +152 -16
  16. package/fesm2022/fundamental-ngx-core-popover.mjs.map +1 -1
  17. package/fesm2022/fundamental-ngx-core-product-switch.mjs +23 -27
  18. package/fesm2022/fundamental-ngx-core-product-switch.mjs.map +1 -1
  19. package/fesm2022/fundamental-ngx-core-shellbar.mjs +2 -2
  20. package/fesm2022/fundamental-ngx-core-shellbar.mjs.map +1 -1
  21. package/fesm2022/fundamental-ngx-core-tabs.mjs +19 -25
  22. package/fesm2022/fundamental-ngx-core-tabs.mjs.map +1 -1
  23. package/package.json +3 -3
  24. package/types/fundamental-ngx-core-carousel.d.ts +2 -3
  25. package/types/fundamental-ngx-core-form.d.ts +7 -10
  26. package/types/fundamental-ngx-core-inline-help.d.ts +20 -15
  27. package/types/fundamental-ngx-core-menu.d.ts +17 -9
  28. package/types/fundamental-ngx-core-multi-combobox.d.ts +18 -1
  29. package/types/fundamental-ngx-core-popover.d.ts +48 -3
  30. package/types/fundamental-ngx-core-product-switch.d.ts +20 -24
  31. package/types/fundamental-ngx-core-tabs.d.ts +5 -10
@@ -13,7 +13,7 @@ import * as i2 from '@fundamental-ngx/cdk/forms';
13
13
  import { isSelectItem, CvaControl, CvaDirective, isOptionItem, isSelectableOptionItem } from '@fundamental-ngx/cdk/forms';
14
14
  import { ListFocusItem, FD_LIST_COMPONENT, ListComponent, ListGroupHeaderDirective, ListTitleDirective, ListItemComponent, ListSecondaryDirective } from '@fundamental-ngx/core/list';
15
15
  import { ContentDensityObserver, contentDensityObserverProviders } from '@fundamental-ngx/core/content-density';
16
- import { Subscription, startWith, skip, timer, isObservable, Subject } from 'rxjs';
16
+ import { skip, timer, Subscription, isObservable, Subject } from 'rxjs';
17
17
  import { debounceTime } from 'rxjs/operators';
18
18
  import { PopoverComponent, PopoverControlComponent, PopoverBodyComponent } from '@fundamental-ngx/core/popover';
19
19
  import { shallowEqual } from 'fast-equals';
@@ -294,10 +294,11 @@ class BaseMultiCombobox {
294
294
  this._rangeSelector = new RangeSelector();
295
295
  /**
296
296
  * Flag indicating whether the data source has changed.
297
- * Set to true when a new data source is assigned, triggering a refresh of suggestions.
297
+ * Guard flag: true while waiting for a new data source's first real data emission.
298
+ * Prevents the provider's initial empty emission from being treated as "no results."
298
299
  * @hidden
299
300
  */
300
- this._dataSourceChanged = false;
301
+ this._dataSourceChanged = true;
301
302
  /**
302
303
  * Signal reference to the popover component.
303
304
  * Used for controlling popover visibility and position.
@@ -548,41 +549,34 @@ class BaseMultiCombobox {
548
549
  * Prepares the data stream and subscribes to it.
549
550
  */
550
551
  _openDataStream(matchingStrategy) {
551
- const dataSourceProvider = this.dataSourceDirective.dataSourceProvider;
552
- if (!dataSourceProvider) {
552
+ if (!this.dataSourceDirective.dataSourceProvider) {
553
553
  throw new Error(`[dataSource] source did not match an array, Observable, or DataSource`);
554
554
  }
555
- dataSourceProvider.limitless = this.limitless();
556
- dataSourceProvider.dataProvider.setLookupKey(this.lookupKey());
557
- const matchingBy = {
558
- firstBy: this._displayFn
559
- };
560
- if (this.secondaryKey()) {
561
- matchingBy.secondaryBy = this._secondaryFn;
562
- }
563
- dataSourceProvider.dataProvider.setMatchingBy(matchingBy);
564
- dataSourceProvider.dataProvider.setMatchingStrategy(matchingStrategy);
555
+ this._matchingStrategy = matchingStrategy;
556
+ this._configureDataSourceProvider(matchingStrategy);
565
557
  // initial data fetch
566
- const map = new Map();
567
- map.set('query', '*');
568
- if (!this.limitless()) {
569
- map.set('limit', this._mapLimit);
570
- }
571
- else {
572
- dataSourceProvider.dataProvider['defaultLimit'] = Number.MAX_SAFE_INTEGER;
573
- }
574
- dataSourceProvider.match(map);
575
- this._dsSubscription = new Subscription();
576
- this._dsSubscription.add(this.dataSourceDirective.dataSourceProvider?.dataRequested.subscribe((value) => this.dataRequested.emit(value)));
577
- this._dsSubscription.add(this.dataSourceDirective.dataSourceProvider?.dataReceived.subscribe((value) => this.dataReceived.emit(value)));
578
- this.dataSourceDirective.dataSourceChanged
579
- .pipe(startWith(true), takeUntilDestroyed(this._destroyRef))
580
- .subscribe(() => {
558
+ this._fetchInitialData();
559
+ this._subscribeToDsEvents();
560
+ this.dataSourceDirective.dataSourceChanged.pipe(takeUntilDestroyed(this._destroyRef)).subscribe(() => {
581
561
  this._dataSourceChanged = true;
562
+ this._subscribeToDsEvents();
563
+ this._configureDataSourceProvider(this._matchingStrategy);
564
+ this._fetchInitialData();
582
565
  });
583
566
  this.dataSourceDirective.dataChanged$.pipe(skip(0), takeUntilDestroyed(this._destroyRef)).subscribe((data) => {
584
567
  if (data.length === 0) {
585
- this._processingEmptyData();
568
+ if (this._dataSourceChanged) {
569
+ // Data source transition: skip the invalid-entry handling (_processingEmptyData)
570
+ // because the new provider's BehaviorSubject starts with [] before match('*') populates it.
571
+ // But still clear stale suggestions and reset the flag.
572
+ this._dataSourceChanged = false;
573
+ this._suggestions.set([]);
574
+ this._flatSuggestions.set([]);
575
+ this._fullFlatSuggestions.set([]);
576
+ }
577
+ else {
578
+ this._processingEmptyData();
579
+ }
586
580
  return;
587
581
  }
588
582
  this._previousInputText = this.inputText();
@@ -642,6 +636,56 @@ class BaseMultiCombobox {
642
636
  this._timerSub$ = timer(this.invalidEntryDisplayTime()).subscribe(() => this._unsetInvalidEntry());
643
637
  this._cd.detectChanges();
644
638
  }
639
+ /**
640
+ * @hidden
641
+ * Configures the data source provider with matching settings.
642
+ */
643
+ _configureDataSourceProvider(matchingStrategy) {
644
+ const dataSourceProvider = this.dataSourceDirective.dataSourceProvider;
645
+ if (!dataSourceProvider) {
646
+ return;
647
+ }
648
+ dataSourceProvider.limitless = this.limitless();
649
+ dataSourceProvider.dataProvider.setLookupKey(this.lookupKey());
650
+ const matchingBy = {
651
+ firstBy: this._displayFn
652
+ };
653
+ if (this.secondaryKey()) {
654
+ matchingBy.secondaryBy = this._secondaryFn;
655
+ }
656
+ dataSourceProvider.dataProvider.setMatchingBy(matchingBy);
657
+ dataSourceProvider.dataProvider.setMatchingStrategy(matchingStrategy);
658
+ }
659
+ /**
660
+ * @hidden
661
+ * Triggers the initial data fetch on the current data source provider.
662
+ */
663
+ _fetchInitialData() {
664
+ const dataSourceProvider = this.dataSourceDirective.dataSourceProvider;
665
+ if (!dataSourceProvider) {
666
+ return;
667
+ }
668
+ const map = new Map();
669
+ map.set('query', '*');
670
+ if (!this.limitless()) {
671
+ map.set('limit', this._mapLimit);
672
+ }
673
+ else {
674
+ dataSourceProvider.dataProvider['defaultLimit'] = Number.MAX_SAFE_INTEGER;
675
+ }
676
+ dataSourceProvider.match(map);
677
+ }
678
+ /**
679
+ * @hidden
680
+ * Subscribes to dataRequested/dataReceived events from the current data source provider.
681
+ * Unsubscribes from previous provider's events first.
682
+ */
683
+ _subscribeToDsEvents() {
684
+ this._dsSubscription?.unsubscribe();
685
+ this._dsSubscription = new Subscription();
686
+ this._dsSubscription.add(this.dataSourceDirective.dataSourceProvider?.dataRequested.subscribe((value) => this.dataRequested.emit(value)));
687
+ this._dsSubscription.add(this.dataSourceDirective.dataSourceProvider?.dataReceived.subscribe((value) => this.dataReceived.emit(value)));
688
+ }
645
689
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: BaseMultiCombobox, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
646
690
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.1.0", type: BaseMultiCombobox, isStandalone: true, viewQueries: [{ propertyName: "popover", first: true, predicate: PopoverComponent, descendants: true, isSignal: true }], ngImport: i0 }); }
647
691
  }