@elderbyte/ngx-starter 21.4.2 → 21.5.0-beta.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.
@@ -23572,63 +23572,52 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
23572
23572
  args: ['elderAutocomplete']
23573
23573
  }] } });
23574
23574
 
23575
+ var InteractionState;
23576
+ (function (InteractionState) {
23577
+ InteractionState["PRISTINE"] = "PRISTINE";
23578
+ InteractionState["INTERACTED"] = "INTERACTED";
23579
+ })(InteractionState || (InteractionState = {}));
23575
23580
  class ElderSelectOnTabDirective {
23576
- /***************************************************************************
23577
- * *
23578
- * Constructor *
23579
- * *
23580
- **************************************************************************/
23581
- constructor(autoTrigger, elderSelectBase) {
23582
- this.autoTrigger = autoTrigger;
23583
- this.elderSelectBase = elderSelectBase;
23581
+ constructor() {
23584
23582
  /***************************************************************************
23585
23583
  * *
23586
- * Fields *
23584
+ * Fields *
23587
23585
  * *
23588
23586
  **************************************************************************/
23589
23587
  this.logger = LoggerFactory.getLogger(this.constructor.name);
23588
+ this.autoTrigger = inject(MatAutocompleteTrigger);
23589
+ this.elderSelectBase = inject(ELDER_SELECT_BASE, {
23590
+ skipSelf: true,
23591
+ });
23592
+ this.controlValueAccessor = this.elderSelectBase;
23590
23593
  this.destroy$ = new Subject$1();
23591
- /**
23592
- * Whether the autocomplete panel was open before the event
23593
- */
23594
- this.panelOpen = false;
23595
- /**
23596
- * Whether the user selected an option.
23597
- * (We want to ignore selections if there is already a selection present and the user tabs away)
23598
- */
23599
- this.userInput = false;
23600
- this.controlValueAccessor = elderSelectBase;
23594
+ /***************************************************************************
23595
+ * *
23596
+ * State *
23597
+ * *
23598
+ **************************************************************************/
23599
+ this.isPanelOpen = false;
23600
+ this.userInteractionState = InteractionState.PRISTINE;
23601
+ this.valueSnapshot = null;
23601
23602
  }
23602
23603
  /***************************************************************************
23603
23604
  * *
23604
23605
  * Event Listener *
23605
23606
  * *
23606
23607
  **************************************************************************/
23607
- onOptionSelect() {
23608
- this.userInput = true;
23608
+ handleVerticalArrowKeyPress() {
23609
+ this.userInteractionState = InteractionState.INTERACTED;
23609
23610
  }
23610
- onBlur() {
23611
- if (!this.panelOpen) {
23611
+ handleTabKeyPress() {
23612
+ if (!this.isPanelOpen || this.shouldSkipTabSelection()) {
23612
23613
  return;
23613
23614
  }
23614
- if (!this.userInput) {
23615
- // The user did not select anything in the auto-complete
23616
- if (this.controlValueAccessor.value) {
23617
- this.logger.warn('Discarding TAB since the user did probably not intend to change the value! userInput:', this.userInput);
23618
- return;
23619
- }
23620
- if (!this.elderSelectBase.required) {
23621
- // The user did not select any option and no current value is present.
23622
- // Since the input is NOT marked as required, we assume the user did not want to select a value
23623
- return;
23624
- }
23625
- }
23626
23615
  const activeOption = this.autoTrigger.activeOption;
23627
23616
  if (activeOption) {
23628
23617
  const entity = activeOption.value;
23629
23618
  this.writeEntity(entity);
23630
23619
  }
23631
- this.reset();
23620
+ this.userInteractionState = InteractionState.PRISTINE;
23632
23621
  }
23633
23622
  /***************************************************************************
23634
23623
  * *
@@ -23636,15 +23625,25 @@ class ElderSelectOnTabDirective {
23636
23625
  * *
23637
23626
  **************************************************************************/
23638
23627
  ngAfterViewInit() {
23639
- const autocomplete = this.autoTrigger.autocomplete;
23640
- merge(autocomplete.opened.pipe(map(() => true)), autocomplete.closed.pipe(map(() => false)))
23641
- .pipe(takeUntil(this.destroy$), delay(0))
23642
- .subscribe((value) => (this.panelOpen = value));
23643
- this.autoTrigger.optionSelections
23644
- .pipe(
23645
- // TODO https://github.com/angular/components/pull/14813
23646
- takeUntil(this.destroy$), tap((opt) => this.logger.debug('[optionSelections] CHANGED ', opt)), map((opt) => opt.isUserInput))
23647
- .subscribe((isUserInput) => (this.userInput = isUserInput));
23628
+ const panelOpenAsync$ = this.buildPanelOpenAsyncObservable();
23629
+ panelOpenAsync$.subscribe((isOpen) => {
23630
+ this.isPanelOpen = isOpen;
23631
+ if (isOpen) {
23632
+ // Snapshot the value at panel-open time so Tab can compare against it.
23633
+ this.valueSnapshot = this.controlValueAccessor.value;
23634
+ // Reset userInput so any selection from a previous panel session is not carried over.
23635
+ this.userInteractionState = InteractionState.PRISTINE;
23636
+ }
23637
+ });
23638
+ const optionSelectionFromUserInput$ = this.buildOptionSelectionFromUserInputObservable();
23639
+ optionSelectionFromUserInput$.subscribe((isUserInput) => {
23640
+ if (isUserInput) {
23641
+ this.userInteractionState = InteractionState.INTERACTED;
23642
+ }
23643
+ else {
23644
+ this.userInteractionState = InteractionState.PRISTINE;
23645
+ }
23646
+ });
23648
23647
  }
23649
23648
  ngOnDestroy() {
23650
23649
  this.destroy$.next();
@@ -23655,8 +23654,35 @@ class ElderSelectOnTabDirective {
23655
23654
  * Private methods *
23656
23655
  * *
23657
23656
  **************************************************************************/
23658
- reset() {
23659
- this.userInput = false;
23657
+ isValueSnapShotNotEmpty() {
23658
+ return this.valueSnapshot !== null && this.valueSnapshot !== undefined;
23659
+ }
23660
+ buildPanelOpenAsyncObservable() {
23661
+ const autocomplete = this.autoTrigger.autocomplete;
23662
+ const panelOpen$ = merge(autocomplete.opened.pipe(map(() => true)), autocomplete.closed.pipe(map(() => false)));
23663
+ const panelOpenAsync$ = panelOpen$.pipe(takeUntil(this.destroy$), delay(0));
23664
+ return panelOpenAsync$;
23665
+ }
23666
+ buildOptionSelectionFromUserInputObservable() {
23667
+ return this.autoTrigger.optionSelections.pipe(takeUntil(this.destroy$), map((opt) => opt.isUserInput));
23668
+ }
23669
+ shouldSkipTabSelection() {
23670
+ if (this.userInteractionState === InteractionState.INTERACTED) {
23671
+ return false;
23672
+ }
23673
+ const isOptionalField = !this.elderSelectBase.required;
23674
+ const hasValueToPreserve = this.isValueSnapShotNotEmpty();
23675
+ if (isOptionalField) {
23676
+ // Since the input is NOT marked as required, we assume the user did not want to select a value
23677
+ this.logger.warn('Skipping TAB selection since the input is NOT marked as required');
23678
+ return true;
23679
+ }
23680
+ if (hasValueToPreserve) {
23681
+ // User has already selected a value
23682
+ this.logger.warn('Discarding TAB since the user did probably not intend to change the value! userInput:', this.userInteractionState);
23683
+ return true;
23684
+ }
23685
+ return false;
23660
23686
  }
23661
23687
  writeEntity(entity) {
23662
23688
  const value = this.entityToValue(entity);
@@ -23676,26 +23702,21 @@ class ElderSelectOnTabDirective {
23676
23702
  return entity;
23677
23703
  }
23678
23704
  }
23679
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ElderSelectOnTabDirective, deps: [{ token: i1$9.MatAutocompleteTrigger }, { token: ELDER_SELECT_BASE, skipSelf: true }], target: i0.ɵɵFactoryTarget.Directive }); }
23680
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.2", type: ElderSelectOnTabDirective, isStandalone: true, selector: "[elderSelectOnTab]", host: { listeners: { "keydown.arrowup": "onOptionSelect()", "keydown.arrowdown": "onOptionSelect()", "keydown.tab": "onBlur()" } }, ngImport: i0 }); }
23705
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ElderSelectOnTabDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
23706
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.2", type: ElderSelectOnTabDirective, isStandalone: true, selector: "[elderSelectOnTab]", host: { listeners: { "keydown.arrowup": "handleVerticalArrowKeyPress()", "keydown.arrowdown": "handleVerticalArrowKeyPress()", "keydown.tab": "handleTabKeyPress()" } }, ngImport: i0 }); }
23681
23707
  }
23682
23708
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ElderSelectOnTabDirective, decorators: [{
23683
23709
  type: Directive,
23684
23710
  args: [{
23685
23711
  selector: '[elderSelectOnTab]',
23686
23712
  }]
23687
- }], ctorParameters: () => [{ type: i1$9.MatAutocompleteTrigger }, { type: ElderSelectBase, decorators: [{
23688
- type: SkipSelf
23689
- }, {
23690
- type: Inject,
23691
- args: [ELDER_SELECT_BASE]
23692
- }] }], propDecorators: { onOptionSelect: [{
23713
+ }], propDecorators: { handleVerticalArrowKeyPress: [{
23693
23714
  type: HostListener,
23694
23715
  args: ['keydown.arrowup']
23695
23716
  }, {
23696
23717
  type: HostListener,
23697
23718
  args: ['keydown.arrowdown']
23698
- }], onBlur: [{
23719
+ }], handleTabKeyPress: [{
23699
23720
  type: HostListener,
23700
23721
  args: ['keydown.tab']
23701
23722
  }] } });