@agorapulse/ui-components 21.0.1 → 21.0.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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Input, ViewEncapsulation, Component, input, inject, ElementRef, Renderer2, ViewContainerRef, effect, Directive, output, HostListener, ViewChild, ChangeDetectionStrategy, EventEmitter, Output, signal, TemplateRef, computed, viewChild, viewChildren, afterRenderEffect, NgModule } from '@angular/core';
2
+ import { Input, ViewEncapsulation, Component, input, inject, ElementRef, Renderer2, ViewContainerRef, effect, Directive, output, HostListener, ViewChild, ChangeDetectionStrategy, EventEmitter, Output, signal, computed, viewChild, viewChildren, afterRenderEffect, NgModule } from '@angular/core';
3
3
  import { NgSelectComponent, NgSelectModule } from '@ng-select/ng-select';
4
4
  import { BadgeComponent } from '@agorapulse/ui-components/badge';
5
5
  import { CheckboxComponent } from '@agorapulse/ui-components/checkbox';
@@ -7,8 +7,7 @@ import { TooltipDirective } from '@agorapulse/ui-components/tooltip';
7
7
  import { AvatarComponent } from '@agorapulse/ui-components/avatar';
8
8
  import { UI_COMPONENTS_SYMBOLS } from '@agorapulse/ui-components/providers';
9
9
  import { SymbolRegistry, apCheck, apPlus, SymbolComponent } from '@agorapulse/ui-symbol';
10
- import { Subscription, merge, BehaviorSubject, filter } from 'rxjs';
11
- import { LoaderComponent } from '@agorapulse/ui-animations';
10
+ import { Subscription, BehaviorSubject, filter } from 'rxjs';
12
11
  import { InputSearchComponent } from '@agorapulse/ui-components/input-search';
13
12
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
14
13
  import * as i1 from '@angular/forms';
@@ -36,7 +35,7 @@ class DropdownGroupItemComponent {
36
35
  return this.children.every((child) => child.disabled);
37
36
  }
38
37
  onGroupClick(event) {
39
- if (!this.select?.maxSelectedItems) {
38
+ if (!this.select?.maxSelectedItems()) {
40
39
  return; // Let ng-select handle it normally
41
40
  }
42
41
  event.stopPropagation();
@@ -50,7 +49,7 @@ class DropdownGroupItemComponent {
50
49
  }
51
50
  }
52
51
  else {
53
- const remaining = this.select.maxSelectedItems - this.select.itemsList.selectedItems.length;
52
+ const remaining = this.select.maxSelectedItems() - this.select.itemsList.selectedItems.length;
54
53
  const selectableChildren = this.children.filter((child) => !child.disabled && !child.selected);
55
54
  for (const child of selectableChildren.slice(0, remaining)) {
56
55
  this.select.select(child);
@@ -95,12 +94,12 @@ class SelectBaseDirective {
95
94
  symbolComponentRef;
96
95
  labelElement;
97
96
  constructor() {
98
- this.selectComponent.appendTo = 'body';
99
- this.selectComponent.searchable = false;
100
- this.selectComponent.clearable = false;
101
- this.selectComponent.markFirst = false;
102
- this.selectComponent.selectableGroupAsModel = false;
103
- this.selectComponent.tabIndex = 0;
97
+ this.selectComponent.appendTo.set('body');
98
+ this.selectComponent.searchable.set(false);
99
+ this.selectComponent.clearable.set(false);
100
+ this.selectComponent.markFirst.set(false);
101
+ this.selectComponent.selectableGroupAsModel.set(false);
102
+ this.selectComponent.tabIndex.set(0);
104
103
  this.symbolRegistry.registerSymbols([apCheck, apPlus]);
105
104
  this.symbolRegistry.withSymbols(...(inject(UI_COMPONENTS_SYMBOLS, { optional: true })?.flat() ?? []));
106
105
  // Handle symbolId changes
@@ -121,10 +120,10 @@ class SelectBaseDirective {
121
120
  });
122
121
  }
123
122
  ngAfterViewInit() {
124
- if (!this.selectComponent.optionTemplate) {
123
+ if (!this.selectComponent.optionTemplate()) {
125
124
  throw new Error('optionTemplate is required for apSelect');
126
125
  }
127
- if (this.selectComponent.groupBy && !this.selectComponent.optgroupTemplate) {
126
+ if (this.selectComponent.groupBy() && !this.selectComponent.optgroupTemplate()) {
128
127
  throw new Error('optgroupTemplate is required for apSelect');
129
128
  }
130
129
  }
@@ -177,14 +176,17 @@ class SelectMultipleDirective {
177
176
  valueContainer = null;
178
177
  subs = new Subscription();
179
178
  constructor() {
180
- this.selectComponent.multiple = true;
181
- this.selectComponent.closeOnSelect = false;
182
- this.selectComponent.searchable = true; // small hack to not closed the dropdown panel when clear an item in value container
183
- this.subs.add(merge(this.selectComponent.addEvent, this.selectComponent.removeEvent, this.selectComponent.clearEvent).subscribe(() => this.updateMaxItemsDisabledState()));
179
+ this.selectComponent.multiple.set(true);
180
+ this.selectComponent.closeOnSelect.set(false);
181
+ this.selectComponent.searchable.set(true); // small hack to not closed the dropdown panel when clear an item in value container
182
+ const updateMaxItemsDisabledState = () => this.updateMaxItemsDisabledState();
183
+ this.subs.add(this.selectComponent.addEvent.subscribe(updateMaxItemsDisabledState));
184
+ this.subs.add(this.selectComponent.removeEvent.subscribe(updateMaxItemsDisabledState));
185
+ this.subs.add(this.selectComponent.clearEvent.subscribe(updateMaxItemsDisabledState));
184
186
  this.subs.add(this.selectComponent.openEvent.subscribe(() => this.pinSelectedAtTop()));
185
187
  }
186
188
  ngAfterViewInit() {
187
- if (!this.selectComponent.multiLabelTemplate) {
189
+ if (!this.selectComponent.multiLabelTemplate()) {
188
190
  throw new Error('multiLabelTemplate is required for apSelectMultiple');
189
191
  }
190
192
  // Add click handler to toggle dropdown when clicking on the select container
@@ -208,7 +210,7 @@ class SelectMultipleDirective {
208
210
  }
209
211
  event.preventDefault();
210
212
  event.stopPropagation();
211
- if (this.selectComponent.isOpen) {
213
+ if (this.selectComponent.isOpen()) {
212
214
  this.selectComponent.close();
213
215
  }
214
216
  else {
@@ -217,7 +219,7 @@ class SelectMultipleDirective {
217
219
  };
218
220
  // `.ap-option-pinned` persists for the panel's lifetime — deselecting keeps the option pinned until reopen.
219
221
  pinSelectedAtTop() {
220
- if (!this.pinnedItemsEnabled() || this.selectComponent.groupBy)
222
+ if (!this.pinnedItemsEnabled() || this.selectComponent.groupBy())
221
223
  return;
222
224
  queueMicrotask(() => {
223
225
  const panel = document.getElementById(this.selectComponent.dropdownId);
@@ -231,7 +233,7 @@ class SelectMultipleDirective {
231
233
  });
232
234
  }
233
235
  updateMaxItemsDisabledState() {
234
- const max = this.selectComponent.maxSelectedItems;
236
+ const max = this.selectComponent.maxSelectedItems();
235
237
  if (!max) {
236
238
  return;
237
239
  }
@@ -546,15 +548,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
546
548
  args: ['click', ['$event']]
547
549
  }] } });
548
550
 
551
+ /** Search input for an ng-select dropdown — place inside its `ng-header-tmp`. */
549
552
  class DropdownSearchFormComponent {
550
553
  searchPlaceholder = '';
551
554
  createNewEnabled = false;
552
555
  createText = 'Create';
553
556
  select;
554
557
  inputSearch;
555
- notFoundTpl;
556
- loadingTpl;
557
- createNewTpl;
558
558
  createNew = new EventEmitter();
559
559
  searchTermSignal = signal('', ...(ngDevMode ? [{ debugName: "searchTermSignal" }] : /* istanbul ignore next */ []));
560
560
  searchTerm$ = new BehaviorSubject('');
@@ -575,12 +575,6 @@ class DropdownSearchFormComponent {
575
575
  this.inputSearch.focusInput();
576
576
  this.registerKeyboardSubmit();
577
577
  }, 100);
578
- this.select.notFoundTemplate = this.notFoundTpl;
579
- this.select.loadingTextTemplate = this.loadingTpl;
580
- // validate the current row on keypress
581
- if (this.createNewEnabled) {
582
- this.select.footerTemplate = this.createNewTpl;
583
- }
584
578
  }
585
579
  /**
586
580
  * Register the keyboard submit event allowing to press enter to select the first item found.
@@ -603,11 +597,11 @@ class DropdownSearchFormComponent {
603
597
  this.createNew.emit(this.searchTermSignal());
604
598
  }
605
599
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: DropdownSearchFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
606
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: DropdownSearchFormComponent, isStandalone: true, selector: "ap-dropdown-search-form", inputs: { searchPlaceholder: "searchPlaceholder", createNewEnabled: "createNewEnabled", createText: "createText", select: "select" }, outputs: { createNew: "createNew" }, viewQueries: [{ propertyName: "inputSearch", first: true, predicate: InputSearchComponent, descendants: true }, { propertyName: "notFoundTpl", first: true, predicate: ["notFoundTpl"], descendants: true, read: TemplateRef }, { propertyName: "loadingTpl", first: true, predicate: ["loadingTpl"], descendants: true, read: TemplateRef }, { propertyName: "createNewTpl", first: true, predicate: ["createNewTpl"], descendants: true, read: TemplateRef }], ngImport: i0, template: "<ap-input-search\n class=\"dropdown-search-input\"\n [ngModel]=\"searchTermSignal()\"\n [placeholder]=\"searchPlaceholder\"\n (ngModelChange)=\"searchTerm$.next($event)\" />\n\n<ng-template #notFoundTpl>\n <div class=\"option not-found\">\n <span>{{ select.notFoundText ? select.notFoundText : 'Not found text' }}</span>\n </div>\n</ng-template>\n\n<ng-template #loadingTpl>\n <div class=\"loading-state\">\n <ap-loader diameter=\"30\" />\n <span>\n {{ select.loadingText ? select.loadingText : 'Loading Items' }}\n </span>\n </div>\n</ng-template>\n\n<ng-template\n #createNewTpl\n let-searchTerm=\"searchTerm\">\n <button\n class=\"create-new\"\n type=\"button\"\n (click)=\"onCreateNew()\">\n <ap-symbol\n symbolId=\"plus\"\n size=\"sm\" />\n <span>\n {{ createText }}\n @if (searchTerm) {\n {{ '&quot;' + searchTerm + '&quot;' }}\n }\n </span>\n </button>\n</ng-template>\n", styles: ["ap-dropdown-search-form .dropdown-search-input .ap-input-group{width:100%}ap-dropdown-search-form .dropdown-search-input .ap-input-group input{width:100%}ap-dropdown-search-form .dropdown-search-input .ap-input-group input:placeholder-shown{text-overflow:ellipsis}\n"], dependencies: [{ kind: "component", type: SymbolComponent, selector: "ap-symbol", inputs: ["symbolId", "color", "size"], outputs: ["sizeChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: LoaderComponent, selector: "ap-loader", inputs: ["color", "diameter"] }, { kind: "component", type: InputSearchComponent, selector: "ap-input-search", inputs: ["id", "placeholder", "clearable"], outputs: ["focus", "blur", "keyup"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
600
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: DropdownSearchFormComponent, isStandalone: true, selector: "ap-dropdown-search-form", inputs: { searchPlaceholder: "searchPlaceholder", createNewEnabled: "createNewEnabled", createText: "createText", select: "select" }, outputs: { createNew: "createNew" }, viewQueries: [{ propertyName: "inputSearch", first: true, predicate: InputSearchComponent, descendants: true }], ngImport: i0, template: "<ap-input-search\n class=\"dropdown-search-input\"\n [ngModel]=\"searchTermSignal()\"\n [placeholder]=\"searchPlaceholder\"\n (ngModelChange)=\"searchTerm$.next($event)\" />\n\n@if (createNewEnabled) {\n <button\n class=\"create-new\"\n type=\"button\"\n (click)=\"onCreateNew()\">\n <ap-symbol\n symbolId=\"plus\"\n size=\"sm\" />\n <span>\n {{ createText }}\n @if (searchTermSignal()) {\n {{ '&quot;' + searchTermSignal() + '&quot;' }}\n }\n </span>\n </button>\n}\n", styles: ["ap-dropdown-search-form .dropdown-search-input .ap-input-group{width:100%}ap-dropdown-search-form .dropdown-search-input .ap-input-group input{width:100%}ap-dropdown-search-form .dropdown-search-input .ap-input-group input:placeholder-shown{text-overflow:ellipsis}\n"], dependencies: [{ kind: "component", type: SymbolComponent, selector: "ap-symbol", inputs: ["symbolId", "color", "size"], outputs: ["sizeChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: InputSearchComponent, selector: "ap-input-search", inputs: ["id", "placeholder", "clearable"], outputs: ["focus", "blur", "keyup"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
607
601
  }
608
602
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: DropdownSearchFormComponent, decorators: [{
609
603
  type: Component,
610
- args: [{ selector: 'ap-dropdown-search-form', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [SymbolComponent, FormsModule, LoaderComponent, InputSearchComponent], template: "<ap-input-search\n class=\"dropdown-search-input\"\n [ngModel]=\"searchTermSignal()\"\n [placeholder]=\"searchPlaceholder\"\n (ngModelChange)=\"searchTerm$.next($event)\" />\n\n<ng-template #notFoundTpl>\n <div class=\"option not-found\">\n <span>{{ select.notFoundText ? select.notFoundText : 'Not found text' }}</span>\n </div>\n</ng-template>\n\n<ng-template #loadingTpl>\n <div class=\"loading-state\">\n <ap-loader diameter=\"30\" />\n <span>\n {{ select.loadingText ? select.loadingText : 'Loading Items' }}\n </span>\n </div>\n</ng-template>\n\n<ng-template\n #createNewTpl\n let-searchTerm=\"searchTerm\">\n <button\n class=\"create-new\"\n type=\"button\"\n (click)=\"onCreateNew()\">\n <ap-symbol\n symbolId=\"plus\"\n size=\"sm\" />\n <span>\n {{ createText }}\n @if (searchTerm) {\n {{ '&quot;' + searchTerm + '&quot;' }}\n }\n </span>\n </button>\n</ng-template>\n", styles: ["ap-dropdown-search-form .dropdown-search-input .ap-input-group{width:100%}ap-dropdown-search-form .dropdown-search-input .ap-input-group input{width:100%}ap-dropdown-search-form .dropdown-search-input .ap-input-group input:placeholder-shown{text-overflow:ellipsis}\n"] }]
604
+ args: [{ selector: 'ap-dropdown-search-form', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [SymbolComponent, FormsModule, InputSearchComponent], template: "<ap-input-search\n class=\"dropdown-search-input\"\n [ngModel]=\"searchTermSignal()\"\n [placeholder]=\"searchPlaceholder\"\n (ngModelChange)=\"searchTerm$.next($event)\" />\n\n@if (createNewEnabled) {\n <button\n class=\"create-new\"\n type=\"button\"\n (click)=\"onCreateNew()\">\n <ap-symbol\n symbolId=\"plus\"\n size=\"sm\" />\n <span>\n {{ createText }}\n @if (searchTermSignal()) {\n {{ '&quot;' + searchTermSignal() + '&quot;' }}\n }\n </span>\n </button>\n}\n", styles: ["ap-dropdown-search-form .dropdown-search-input .ap-input-group{width:100%}ap-dropdown-search-form .dropdown-search-input .ap-input-group input{width:100%}ap-dropdown-search-form .dropdown-search-input .ap-input-group input:placeholder-shown{text-overflow:ellipsis}\n"] }]
611
605
  }], ctorParameters: () => [], propDecorators: { searchPlaceholder: [{
612
606
  type: Input
613
607
  }], createNewEnabled: [{
@@ -622,15 +616,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
622
616
  }], inputSearch: [{
623
617
  type: ViewChild,
624
618
  args: [InputSearchComponent]
625
- }], notFoundTpl: [{
626
- type: ViewChild,
627
- args: ['notFoundTpl', { read: TemplateRef }]
628
- }], loadingTpl: [{
629
- type: ViewChild,
630
- args: ['loadingTpl', { read: TemplateRef }]
631
- }], createNewTpl: [{
632
- type: ViewChild,
633
- args: ['createNewTpl', { read: TemplateRef }]
634
619
  }], createNew: [{
635
620
  type: Output
636
621
  }] } });
@@ -713,11 +698,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
713
698
  class SelectSingleDirective {
714
699
  selectComponent = inject(NgSelectComponent);
715
700
  constructor() {
716
- this.selectComponent.multiple = false;
717
- this.selectComponent.closeOnSelect = true;
701
+ this.selectComponent.multiple.set(false);
702
+ this.selectComponent.closeOnSelect.set(true);
718
703
  }
719
704
  ngAfterViewInit() {
720
- if (!this.selectComponent.labelTemplate) {
705
+ if (!this.selectComponent.labelTemplate()) {
721
706
  throw new Error('labelTemplate is required for apSelectSingle');
722
707
  }
723
708
  }