@elderbyte/ngx-starter 21.4.1 → 21.4.3

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.
@@ -23573,62 +23573,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
23573
23573
  }] } });
23574
23574
 
23575
23575
  class ElderSelectOnTabDirective {
23576
- /***************************************************************************
23577
- * *
23578
- * Constructor *
23579
- * *
23580
- **************************************************************************/
23581
- constructor(autoTrigger, elderSelectBase) {
23582
- this.autoTrigger = autoTrigger;
23583
- this.elderSelectBase = elderSelectBase;
23576
+ constructor() {
23584
23577
  /***************************************************************************
23585
23578
  * *
23586
23579
  * Fields *
23587
23580
  * *
23588
23581
  **************************************************************************/
23589
23582
  this.logger = LoggerFactory.getLogger(this.constructor.name);
23583
+ this.autoTrigger = inject(MatAutocompleteTrigger);
23584
+ this.elderSelectBase = inject(ELDER_SELECT_BASE, {
23585
+ skipSelf: true,
23586
+ });
23590
23587
  this.destroy$ = new Subject$1();
23591
- /**
23592
- * Whether the autocomplete panel was open before the event
23593
- */
23588
+ this.controlValueAccessor = this.elderSelectBase;
23594
23589
  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;
23590
+ this.userInteracted = false;
23601
23591
  }
23602
23592
  /***************************************************************************
23603
23593
  * *
23604
23594
  * Event Listener *
23605
23595
  * *
23606
23596
  **************************************************************************/
23607
- onOptionSelect() {
23608
- this.userInput = true;
23597
+ handleVerticalArrowKeyPress() {
23598
+ this.userInteracted = true;
23609
23599
  }
23610
- onBlur() {
23600
+ handleTabKeyPress() {
23611
23601
  if (!this.panelOpen) {
23612
23602
  return;
23613
23603
  }
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
- const activeOption = this.autoTrigger.activeOption;
23627
- if (activeOption) {
23628
- const entity = activeOption.value;
23629
- this.writeEntity(entity);
23604
+ if (this.userInteracted || this.isRequiredAndEmpty()) {
23605
+ this.selectActiveOption();
23630
23606
  }
23631
- this.reset();
23632
23607
  }
23633
23608
  /***************************************************************************
23634
23609
  * *
@@ -23636,15 +23611,8 @@ class ElderSelectOnTabDirective {
23636
23611
  * *
23637
23612
  **************************************************************************/
23638
23613
  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));
23614
+ this.observePanelOpen();
23615
+ this.observeAutocompleteSelection();
23648
23616
  }
23649
23617
  ngOnDestroy() {
23650
23618
  this.destroy$.next();
@@ -23655,8 +23623,36 @@ class ElderSelectOnTabDirective {
23655
23623
  * Private methods *
23656
23624
  * *
23657
23625
  **************************************************************************/
23658
- reset() {
23659
- this.userInput = false;
23626
+ isRequiredAndEmpty() {
23627
+ return !this.controlValueAccessor.value && this.elderSelectBase.required;
23628
+ }
23629
+ resetInteractionState() {
23630
+ this.userInteracted = false;
23631
+ }
23632
+ observePanelOpen() {
23633
+ const autocomplete = this.autoTrigger.autocomplete;
23634
+ merge(autocomplete.opened.pipe(map(() => true)), autocomplete.closed.pipe(map(() => false)))
23635
+ .pipe(takeUntil(this.destroy$), delay(0))
23636
+ .subscribe((isOpen) => {
23637
+ this.panelOpen = isOpen;
23638
+ if (isOpen) {
23639
+ this.resetInteractionState();
23640
+ }
23641
+ });
23642
+ }
23643
+ observeAutocompleteSelection() {
23644
+ this.autoTrigger.optionSelections
23645
+ .pipe(
23646
+ // TODO https://github.com/angular/components/pull/14813
23647
+ takeUntil(this.destroy$), tap((opt) => this.logger.debug('[optionSelections] CHANGED ', opt)), map((opt) => opt.isUserInput))
23648
+ .subscribe((isUserInput) => (this.userInteracted = isUserInput));
23649
+ }
23650
+ selectActiveOption() {
23651
+ const activeOption = this.autoTrigger.activeOption;
23652
+ if (activeOption) {
23653
+ const entity = activeOption.value;
23654
+ this.writeEntity(entity);
23655
+ }
23660
23656
  }
23661
23657
  writeEntity(entity) {
23662
23658
  const value = this.entityToValue(entity);
@@ -23676,26 +23672,21 @@ class ElderSelectOnTabDirective {
23676
23672
  return entity;
23677
23673
  }
23678
23674
  }
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 }); }
23675
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ElderSelectOnTabDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
23676
+ 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
23677
  }
23682
23678
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: ElderSelectOnTabDirective, decorators: [{
23683
23679
  type: Directive,
23684
23680
  args: [{
23685
23681
  selector: '[elderSelectOnTab]',
23686
23682
  }]
23687
- }], ctorParameters: () => [{ type: i1$9.MatAutocompleteTrigger }, { type: ElderSelectBase, decorators: [{
23688
- type: SkipSelf
23689
- }, {
23690
- type: Inject,
23691
- args: [ELDER_SELECT_BASE]
23692
- }] }], propDecorators: { onOptionSelect: [{
23683
+ }], propDecorators: { handleVerticalArrowKeyPress: [{
23693
23684
  type: HostListener,
23694
23685
  args: ['keydown.arrowup']
23695
23686
  }, {
23696
23687
  type: HostListener,
23697
23688
  args: ['keydown.arrowdown']
23698
- }], onBlur: [{
23689
+ }], handleTabKeyPress: [{
23699
23690
  type: HostListener,
23700
23691
  args: ['keydown.tab']
23701
23692
  }] } });
@@ -37971,8 +37962,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImpor
37971
37962
  args: ['class']
37972
37963
  }] } });
37973
37964
 
37974
- const DEFAULT_MIN_WIDTH = 5;
37975
- const DEFAULT_MAX_WIDTH = 95;
37965
+ const DEFAULT_MIN_WIDTH = '5%';
37966
+ const DEFAULT_MAX_WIDTH = '95%';
37976
37967
  const DEFAULT_HANDLE_POSITION = 'end';
37977
37968
 
37978
37969
  class ElderResizeBehaviorDirective {
@@ -38001,7 +37992,7 @@ class ElderResizeBehaviorDirective {
38001
37992
  this.isInComputedWidthMode = signal(false, ...(ngDevMode ? [{ debugName: "isInComputedWidthMode" }] : []));
38002
37993
  this.widthInPercent = signal(null, ...(ngDevMode ? [{ debugName: "widthInPercent" }] : []));
38003
37994
  this._isDragging = signal(false, ...(ngDevMode ? [{ debugName: "_isDragging" }] : []));
38004
- this.containerWidth = 0;
37995
+ this.containerWidth = signal(0, ...(ngDevMode ? [{ debugName: "containerWidth" }] : []));
38005
37996
  this.dragStartMousePosX = 0;
38006
37997
  this.dragStartPaneWidthInPercent = 0;
38007
37998
  /***************************************************************************
@@ -38015,7 +38006,12 @@ class ElderResizeBehaviorDirective {
38015
38006
  if (width === null) {
38016
38007
  return null;
38017
38008
  }
38018
- return Math.max(this.minWidth(), Math.min(this.maxWidth(), width));
38009
+ const containerW = this.containerWidth();
38010
+ const minParsed = this.parseWidthConstraint(this.minWidth());
38011
+ const maxParsed = this.parseWidthConstraint(this.maxWidth());
38012
+ const minPercent = this.toPercent(minParsed, containerW);
38013
+ const maxPercent = this.toPercent(maxParsed, containerW);
38014
+ return Math.max(minPercent, Math.min(maxPercent, width));
38019
38015
  }, ...(ngDevMode ? [{ debugName: "constrainedWidth" }] : []));
38020
38016
  /***************************************************************************
38021
38017
  * *
@@ -38067,6 +38063,23 @@ class ElderResizeBehaviorDirective {
38067
38063
  * Private methods *
38068
38064
  * *
38069
38065
  **************************************************************************/
38066
+ parseWidthConstraint(input) {
38067
+ const trimmed = String(input).trim().toLowerCase();
38068
+ const floatValue = parseFloat(trimmed);
38069
+ const isValidEnding = trimmed.endsWith('px') || trimmed.endsWith('%');
38070
+ if (Number.isNaN(floatValue) || !isValidEnding) {
38071
+ this.logger.error(`Invalid width constraint: ${input}`);
38072
+ return { value: 0, unit: 'percent' };
38073
+ }
38074
+ return { value: floatValue, unit: trimmed.endsWith('px') ? 'px' : 'percent' };
38075
+ }
38076
+ toPercent(parsed, containerWidth) {
38077
+ if (parsed.unit === 'percent')
38078
+ return parsed.value;
38079
+ if (containerWidth <= 0)
38080
+ return parsed.value <= 0 ? 0 : 100;
38081
+ return (parsed.value / containerWidth) * 100;
38082
+ }
38070
38083
  removeExternalWidthStyles() {
38071
38084
  const stylesToRemove = [
38072
38085
  'flex',
@@ -38106,24 +38119,23 @@ class ElderResizeBehaviorDirective {
38106
38119
  }
38107
38120
  setWidthInPercentFromElementWidth() {
38108
38121
  this.updateContainerWidth();
38109
- if (this.containerWidth === 0) {
38122
+ if (this.containerWidth() === 0) {
38110
38123
  this.logger.error('Container width is 0. Can not calculate percent.');
38111
38124
  return;
38112
38125
  }
38113
38126
  // Calculate the current element width as a percentage of container width
38114
38127
  const paneWidth = this.elementRef.nativeElement.offsetWidth;
38115
- const percentage = (paneWidth / this.containerWidth) * 100;
38128
+ const percentage = (paneWidth / this.containerWidth()) * 100;
38116
38129
  this.widthInPercent.set(percentage);
38117
38130
  }
38118
38131
  updateContainerWidth() {
38119
38132
  const containerElement = this.elementRef.nativeElement.parentElement;
38120
38133
  if (!containerElement) {
38121
38134
  this.logger.error('Container element not found for percentage calculation');
38122
- return null;
38135
+ return;
38123
38136
  }
38124
38137
  // Use clientWidth which excludes borders and scrollbars, then subtract padding
38125
- this.containerWidth = containerElement.clientWidth - this.getContainerPadding();
38126
- return this.containerWidth;
38138
+ this.containerWidth.set(containerElement.clientWidth - this.getContainerPadding());
38127
38139
  }
38128
38140
  getContainerPadding() {
38129
38141
  const containerElement = this.elementRef.nativeElement.parentElement;
@@ -38134,14 +38146,14 @@ class ElderResizeBehaviorDirective {
38134
38146
  parseFloat(window.getComputedStyle(containerElement).paddingRight));
38135
38147
  }
38136
38148
  calcWidthInPercent(event, position) {
38137
- if (this.containerWidth === 0 ||
38149
+ if (this.containerWidth() === 0 ||
38138
38150
  this.dragStartPaneWidthInPercent === null ||
38139
38151
  isNaN(this.dragStartPaneWidthInPercent)) {
38140
38152
  return undefined;
38141
38153
  }
38142
38154
  const deltaX = event.clientX - this.dragStartMousePosX;
38143
38155
  // Convert pixel delta to percentage delta
38144
- let delta = (deltaX / this.containerWidth) * 100;
38156
+ let delta = (deltaX / this.containerWidth()) * 100;
38145
38157
  // Invert delta for left-side handles
38146
38158
  if (position === 'start') {
38147
38159
  delta = -delta;