@agorapulse/ui-components 22.1.7 → 22.2.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 (61) hide show
  1. package/agorapulse-ui-components-22.2.0.tgz +0 -0
  2. package/fesm2022/agorapulse-ui-components-action-dropdown.mjs +29 -61
  3. package/fesm2022/agorapulse-ui-components-action-dropdown.mjs.map +1 -1
  4. package/fesm2022/agorapulse-ui-components-autocomplete.mjs +1 -1
  5. package/fesm2022/agorapulse-ui-components-autocomplete.mjs.map +1 -1
  6. package/fesm2022/agorapulse-ui-components-button.mjs +8 -4
  7. package/fesm2022/agorapulse-ui-components-button.mjs.map +1 -1
  8. package/fesm2022/agorapulse-ui-components-checkbox.mjs +16 -4
  9. package/fesm2022/agorapulse-ui-components-checkbox.mjs.map +1 -1
  10. package/fesm2022/agorapulse-ui-components-datepicker.mjs +655 -219
  11. package/fesm2022/agorapulse-ui-components-datepicker.mjs.map +1 -1
  12. package/fesm2022/agorapulse-ui-components-directives.mjs +172 -2
  13. package/fesm2022/agorapulse-ui-components-directives.mjs.map +1 -1
  14. package/fesm2022/agorapulse-ui-components-dropdown-base.mjs +69 -2
  15. package/fesm2022/agorapulse-ui-components-dropdown-base.mjs.map +1 -1
  16. package/fesm2022/agorapulse-ui-components-dropdown-panel.mjs +47 -3
  17. package/fesm2022/agorapulse-ui-components-dropdown-panel.mjs.map +1 -1
  18. package/fesm2022/agorapulse-ui-components-filter-dropdown.mjs +39 -13
  19. package/fesm2022/agorapulse-ui-components-filter-dropdown.mjs.map +1 -1
  20. package/fesm2022/agorapulse-ui-components-input-group.mjs +6 -4
  21. package/fesm2022/agorapulse-ui-components-input-group.mjs.map +1 -1
  22. package/fesm2022/agorapulse-ui-components-input-search.mjs +10 -4
  23. package/fesm2022/agorapulse-ui-components-input-search.mjs.map +1 -1
  24. package/fesm2022/agorapulse-ui-components-labels-selector.mjs +1 -1
  25. package/fesm2022/agorapulse-ui-components-labels-selector.mjs.map +1 -1
  26. package/fesm2022/agorapulse-ui-components-legacy-select.mjs +1 -1
  27. package/fesm2022/agorapulse-ui-components-legacy-select.mjs.map +1 -1
  28. package/fesm2022/agorapulse-ui-components-nav-selector.mjs +3 -3
  29. package/fesm2022/agorapulse-ui-components-nav-selector.mjs.map +1 -1
  30. package/fesm2022/agorapulse-ui-components-neo-datepicker.mjs +2 -2
  31. package/fesm2022/agorapulse-ui-components-neo-datepicker.mjs.map +1 -1
  32. package/fesm2022/agorapulse-ui-components-phone-number-input.mjs +1 -1
  33. package/fesm2022/agorapulse-ui-components-phone-number-input.mjs.map +1 -1
  34. package/fesm2022/agorapulse-ui-components-popover.mjs +7 -0
  35. package/fesm2022/agorapulse-ui-components-popover.mjs.map +1 -1
  36. package/fesm2022/agorapulse-ui-components-select.mjs +18 -44
  37. package/fesm2022/agorapulse-ui-components-select.mjs.map +1 -1
  38. package/fesm2022/agorapulse-ui-components-selection-dropdown.mjs +160 -16
  39. package/fesm2022/agorapulse-ui-components-selection-dropdown.mjs.map +1 -1
  40. package/fesm2022/agorapulse-ui-components.mjs +2 -4
  41. package/fesm2022/agorapulse-ui-components.mjs.map +1 -1
  42. package/package.json +2 -6
  43. package/types/agorapulse-ui-components-action-dropdown.d.ts +6 -4
  44. package/types/agorapulse-ui-components-button.d.ts +4 -2
  45. package/types/agorapulse-ui-components-checkbox.d.ts +7 -1
  46. package/types/agorapulse-ui-components-datepicker.d.ts +313 -88
  47. package/types/agorapulse-ui-components-directives.d.ts +85 -2
  48. package/types/agorapulse-ui-components-dropdown-base.d.ts +40 -1
  49. package/types/agorapulse-ui-components-dropdown-panel.d.ts +16 -1
  50. package/types/agorapulse-ui-components-filter-dropdown.d.ts +3 -1
  51. package/types/agorapulse-ui-components-input-group.d.ts +3 -1
  52. package/types/agorapulse-ui-components-input-search.d.ts +5 -1
  53. package/types/agorapulse-ui-components-neo-datepicker.d.ts +2 -2
  54. package/types/agorapulse-ui-components-popover.d.ts +7 -0
  55. package/types/agorapulse-ui-components-select.d.ts +7 -5
  56. package/types/agorapulse-ui-components-selection-dropdown.d.ts +68 -5
  57. package/types/agorapulse-ui-components.d.ts +2 -5
  58. package/agorapulse-ui-components-22.1.7.tgz +0 -0
  59. package/fesm2022/agorapulse-ui-components-date-range-picker.mjs +0 -163
  60. package/fesm2022/agorapulse-ui-components-date-range-picker.mjs.map +0 -1
  61. package/types/agorapulse-ui-components-date-range-picker.d.ts +0 -75
@@ -1,6 +1,8 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, ElementRef, input, HostListener, Directive, viewChild, contentChild, output, model, computed, effect, untracked, linkedSignal, signal, ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { inject, ElementRef, input, HostListener, Directive, viewChild, viewChildren, signal, Injector, computed, contentChild, output, model, effect, untracked, linkedSignal, ChangeDetectionStrategy, Component } from '@angular/core';
3
3
  import { CheckboxComponent } from '@agorapulse/ui-components/checkbox';
4
+ import { ActiveDescendantKeyManager, FocusKeyManager } from '@angular/cdk/a11y';
5
+ import { DropdownOptionDirective } from '@agorapulse/ui-components/dropdown-base';
4
6
  import { DropdownPanelComponent, DropdownContentDirective } from '@agorapulse/ui-components/dropdown-panel';
5
7
  import { InputSearchComponent } from '@agorapulse/ui-components/input-search';
6
8
  import { UI_COMPONENTS_SYMBOLS } from '@agorapulse/ui-components/providers';
@@ -65,11 +67,34 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
65
67
  args: ['keydown', ['$event']]
66
68
  }] } });
67
69
 
70
+ /** The only keys a search field hands to the list: Home and End belong to the caret, not the options. */
71
+ const NAVIGATION_FROM_SEARCH = new Set(['ArrowUp', 'ArrowDown']);
68
72
  /** A dropdown of options on any trigger. `multiple` = checkbox rows with search; `single` = rows, closes on pick. */
69
73
  class SelectionDropdownComponent {
74
+ static nextId = 0;
70
75
  symbolRegistry = inject(SymbolRegistry);
71
76
  panel = viewChild(DropdownPanelComponent, /* @ts-ignore */
72
77
  ...(ngDevMode ? [{ debugName: "panel" }] : /* istanbul ignore next */ []));
78
+ options = viewChildren(DropdownOptionDirective, /* @ts-ignore */
79
+ ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
80
+ /** Mirrors the key manager's active index, so the roving tabindex can be bound. */
81
+ activeIndex = signal(-1, /* @ts-ignore */
82
+ ...(ngDevMode ? [{ debugName: "activeIndex" }] : /* istanbul ignore next */ []));
83
+ injector = inject(Injector);
84
+ /** Names the dialog. Falls back to the visible title, then to a generic label rather than none. */
85
+ ariaLabel = input(/* @ts-ignore */
86
+ ...(ngDevMode ? [undefined, { debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
87
+ /** Names the listbox holding what is already selected. */
88
+ selectedSectionText = input('Selected', /* @ts-ignore */
89
+ ...(ngDevMode ? [{ debugName: "selectedSectionText" }] : /* istanbul ignore next */ []));
90
+ /** Names a listbox of ungrouped options when the dropdown has no title. */
91
+ optionsSectionText = input('Options', /* @ts-ignore */
92
+ ...(ngDevMode ? [{ debugName: "optionsSectionText" }] : /* istanbul ignore next */ []));
93
+ panelLabel = computed(() => this.ariaLabel() ?? this.title() ?? 'Selection', /* @ts-ignore */
94
+ ...(ngDevMode ? [{ debugName: "panelLabel" }] : /* istanbul ignore next */ []));
95
+ listboxId = `ap-selection-dropdown-list-${SelectionDropdownComponent.nextId++}`;
96
+ keyManager = null;
97
+ primed = false;
73
98
  trigger = contentChild('trigger', /* @ts-ignore */
74
99
  ...(ngDevMode ? [{ debugName: "trigger" }] : /* istanbul ignore next */ []));
75
100
  /** ID for the header button */
@@ -108,6 +133,9 @@ class SelectionDropdownComponent {
108
133
  /** Text to display when no search results are found */
109
134
  noSearchResultsText = input('No results found', /* @ts-ignore */
110
135
  ...(ngDevMode ? [{ debugName: "noSearchResultsText" }] : /* istanbul ignore next */ []));
136
+ /** Announced once a search settles. `{count}` is replaced by how many options matched. */
137
+ searchResultsText = input('{count} results', /* @ts-ignore */
138
+ ...(ngDevMode ? [{ debugName: "searchResultsText" }] : /* istanbul ignore next */ []));
111
139
  /** Whether to show a backdrop that closes the dropdown when clicked */
112
140
  showBackdrop = input(true, /* @ts-ignore */
113
141
  ...(ngDevMode ? [{ debugName: "showBackdrop" }] : /* istanbul ignore next */ []));
@@ -152,6 +180,18 @@ class SelectionDropdownComponent {
152
180
  });
153
181
  }, /* @ts-ignore */
154
182
  ...(ngDevMode ? [{ debugName: "focusInput" }] : /* istanbul ignore next */ []));
183
+ /** Single-select opens on its first option; multi does not, since marking one the user never chose announces a selection. */
184
+ primeOptions = effect(() => {
185
+ const open = this.isOpen();
186
+ const options = this.options();
187
+ untracked(() => {
188
+ if (open && options.length > 0 && !this.primed && this.isSingleSelect()) {
189
+ this.primed = true;
190
+ this.activeManager().setFirstItemActive();
191
+ }
192
+ });
193
+ }, /* @ts-ignore */
194
+ ...(ngDevMode ? [{ debugName: "primeOptions" }] : /* istanbul ignore next */ []));
155
195
  isSingleSelect = computed(() => this.selectionMode() === 'single', /* @ts-ignore */
156
196
  ...(ngDevMode ? [{ debugName: "isSingleSelect" }] : /* istanbul ignore next */ []));
157
197
  /** Always true in `multiple` mode, leaving that layout untouched; only `single` collapses the header. */
@@ -165,6 +205,9 @@ class SelectionDropdownComponent {
165
205
  ...(ngDevMode ? [{ debugName: "internalItems" }] : /* istanbul ignore next */ []));
166
206
  filteredItems = signal([], /* @ts-ignore */
167
207
  ...(ngDevMode ? [{ debugName: "filteredItems" }] : /* istanbul ignore next */ []));
208
+ /** What the live region holds. Empty outside a search: the list is on screen, unchanged. */
209
+ resultsAnnouncement = signal('', /* @ts-ignore */
210
+ ...(ngDevMode ? [{ debugName: "resultsAnnouncement" }] : /* istanbul ignore next */ []));
168
211
  initiallySelectedItems = signal([], /* @ts-ignore */
169
212
  ...(ngDevMode ? [{ debugName: "initiallySelectedItems" }] : /* istanbul ignore next */ []));
170
213
  // Computed properties for template usage
@@ -207,6 +250,28 @@ class SelectionDropdownComponent {
207
250
  return entries;
208
251
  }, /* @ts-ignore */
209
252
  ...(ngDevMode ? [{ debugName: "displayEntries" }] : /* istanbul ignore next */ []));
253
+ /**
254
+ * A listbox owns only options, so a group's checkbox cannot sit inside one: each group gets its own
255
+ * listbox, and the ungrouped items between two groups are collected into one rather than one each.
256
+ */
257
+ displayRuns = computed(() => {
258
+ const runs = [];
259
+ for (const entry of this.displayEntries()) {
260
+ if (entry.kind === 'group') {
261
+ runs.push(entry);
262
+ continue;
263
+ }
264
+ const last = runs[runs.length - 1];
265
+ if (last?.kind === 'items') {
266
+ last.items.push(entry.item);
267
+ }
268
+ else {
269
+ runs.push({ kind: 'items', items: [entry.item] });
270
+ }
271
+ }
272
+ return runs;
273
+ }, /* @ts-ignore */
274
+ ...(ngDevMode ? [{ debugName: "displayRuns" }] : /* istanbul ignore next */ []));
210
275
  // Computed maps for template usage
211
276
  groupSelectionStates = computed(() => {
212
277
  const states = {};
@@ -243,6 +308,7 @@ class SelectionDropdownComponent {
243
308
  this.searchTermSubject.pipe(debounceTime(100), distinctUntilChanged(), takeUntil(this.destroy$)).subscribe(term => {
244
309
  const items = this.internalItems();
245
310
  this.updateFilteredItems(term?.toLowerCase() ?? '', items);
311
+ this.announceResults(term);
246
312
  });
247
313
  // Feed the debounced filter pipeline from the search term signal, so the list re-filters
248
314
  // both on user typing and on an external set (a consumer resetting searchTerm to '').
@@ -274,6 +340,8 @@ class SelectionDropdownComponent {
274
340
  this.panel()?.close();
275
341
  }
276
342
  onPanelClosed() {
343
+ this.primed = false;
344
+ this.activeIndex.set(-1);
277
345
  this.initiallySelectedItems.set([]);
278
346
  this.closed.emit();
279
347
  }
@@ -322,24 +390,87 @@ class SelectionDropdownComponent {
322
390
  onFooterButtonClick() {
323
391
  this.footerButtonClick.emit();
324
392
  }
325
- /** Handles footer button keyboard events */
326
- onFooterButtonKeydown(event) {
327
- if (event.key === 'Enter' || event.key === ' ') {
328
- event.preventDefault();
329
- this.footerButtonClick.emit();
393
+ /**
394
+ * A search field keeps focus, so the list is marked rather than focused and the field says which
395
+ * option through `aria-activedescendant`. Without a field, focus is the only affordance there is,
396
+ * and the type-ahead is free — it is only a rival to a field that does the same job.
397
+ */
398
+ activeManager() {
399
+ if (!this.keyManager) {
400
+ this.keyManager = this.searchVisible()
401
+ ? new ActiveDescendantKeyManager(this.options, this.injector).withWrap()
402
+ : new FocusKeyManager(this.options, this.injector).withWrap().withHomeAndEnd().withTypeAhead();
403
+ this.keyManager.change.subscribe(index => this.activeIndex.set(index));
404
+ // No close on `tabOut`: the rest of the dialog must stay reachable. The manager does not
405
+ // preventDefault on Tab, so leaving it alone is enough.
406
+ }
407
+ return this.keyManager;
408
+ }
409
+ /** `@for` gives a per-loop index, and the options span several listboxes, so identity decides. */
410
+ runKey(run) {
411
+ return run.kind === 'items' ? `items:${run.items[0]?.htmlId ?? ''}` : `group:${run.label}`;
412
+ }
413
+ /** With a search field the list is no tab stop at all: the field owns it and reaches it by arrow. */
414
+ optionTabIndex(carriesIt) {
415
+ return carriesIt && !this.searchVisible() ? 0 : -1;
416
+ }
417
+ /**
418
+ * Roving tabindex across every listbox at once: the options are a single tab stop. Before any
419
+ * arrow key the first option carries it, or nothing in the list could be tabbed to.
420
+ */
421
+ tabbableOption(item) {
422
+ const options = this.options();
423
+ const active = this.activeIndex();
424
+ const carrier = active >= 0 ? options[active] : options[0];
425
+ return carrier?.id === this.optionId(item);
426
+ }
427
+ /** The option the search field names as active, or nothing until an arrow key marks one. */
428
+ activeDescendantId = computed(() => {
429
+ const active = this.activeIndex();
430
+ return active >= 0 ? (this.options()[active]?.id ?? null) : null;
431
+ }, /* @ts-ignore */
432
+ ...(ngDevMode ? [{ debugName: "activeDescendantId" }] : /* istanbul ignore next */ []));
433
+ /** An option needs an id of its own: the consumer's htmlId is not unique across a page. */
434
+ optionId(item) {
435
+ return `${this.listboxId}-${item.htmlId}`;
436
+ }
437
+ /**
438
+ * The manager owns the arrows and Home/End. An option is a button, so it activates itself.
439
+ *
440
+ * Keys from the search field arrive here by bubbling, so only navigation crosses over: anything
441
+ * else is the text being typed, and the manager would answer it instead of the field.
442
+ */
443
+ onOptionsKeyDown(event) {
444
+ if (this.searchVisible()) {
445
+ // Only the field drives the list, because only the field says which option is active.
446
+ // Driven from the clear button or a group checkbox, the arrows would move a marker no
447
+ // key could then commit, and no screen reader would hear.
448
+ if (!this.fromSearchField(event)) {
449
+ return;
450
+ }
451
+ if (event.key === 'Enter') {
452
+ // The marked option has no focus of its own to answer with.
453
+ this.activeManager().activeItem?.activate();
454
+ event.preventDefault();
455
+ return;
456
+ }
457
+ if (!NAVIGATION_FROM_SEARCH.has(event.key)) {
458
+ return;
459
+ }
330
460
  }
461
+ this.activeManager().onKeydown(event);
462
+ }
463
+ /** Leaving the field ends its hold on the list: a marker nothing can commit only misleads. */
464
+ onSearchBlur() {
465
+ this.activeManager().setActiveItem(-1);
466
+ }
467
+ fromSearchField(event) {
468
+ return event.target === this.inputSearchComponent()?.inputElement().nativeElement;
331
469
  }
332
470
  /** Handles header button clicks */
333
471
  onHeaderButtonClick() {
334
472
  this.headerButtonClick.emit();
335
473
  }
336
- /** Handles header button keyboard events */
337
- onHeaderButtonKeydown(event) {
338
- if (event.key === 'Enter' || event.key === ' ') {
339
- event.preventDefault();
340
- this.headerButtonClick.emit();
341
- }
342
- }
343
474
  /** Handles search input changes from the rendered field. Filtering is driven by the
344
475
  * `searchTerm` effect, so this only updates the term and notifies listeners. */
345
476
  onSearchTermChange(term) {
@@ -364,6 +495,18 @@ class SelectionDropdownComponent {
364
495
  entryKey(entry) {
365
496
  return entry.kind === 'item' ? `item:${entry.item.htmlId}` : `group:${entry.label}`;
366
497
  }
498
+ /**
499
+ * A filtered list changes under a screen reader with nothing said, and the field keeps the focus,
500
+ * so there is no new focus to read either. Announced after the debounce, once the count is final.
501
+ */
502
+ announceResults(term) {
503
+ if (!term) {
504
+ this.resultsAnnouncement.set('');
505
+ return;
506
+ }
507
+ const count = this.filteredItems().length;
508
+ this.resultsAnnouncement.set(count === 0 ? this.noSearchResultsText() : this.searchResultsText().replace('{count}', String(count)));
509
+ }
367
510
  /** Updates the filtered items based on search term */
368
511
  updateFilteredItems(searchTerm, items) {
369
512
  if (!searchTerm) {
@@ -374,13 +517,14 @@ class SelectionDropdownComponent {
374
517
  this.filteredItems.set(filtered);
375
518
  }
376
519
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: SelectionDropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
377
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: SelectionDropdownComponent, isStandalone: true, selector: "ap-selection-dropdown", inputs: { headerButtonId: { classPropertyName: "headerButtonId", publicName: "headerButtonId", isSignal: true, isRequired: false, transformFunction: null }, footerButtonId: { classPropertyName: "footerButtonId", publicName: "footerButtonId", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, searchEnabled: { classPropertyName: "searchEnabled", publicName: "searchEnabled", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, footerButtonText: { classPropertyName: "footerButtonText", publicName: "footerButtonText", isSignal: true, isRequired: false, transformFunction: null }, footerButtonSymbolId: { classPropertyName: "footerButtonSymbolId", publicName: "footerButtonSymbolId", isSignal: true, isRequired: false, transformFunction: null }, headerButtonText: { classPropertyName: "headerButtonText", publicName: "headerButtonText", isSignal: true, isRequired: false, transformFunction: null }, headerButtonSymbolId: { classPropertyName: "headerButtonSymbolId", publicName: "headerButtonSymbolId", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholderText: { classPropertyName: "searchPlaceholderText", publicName: "searchPlaceholderText", isSignal: true, isRequired: false, transformFunction: null }, noSearchResultsText: { classPropertyName: "noSearchResultsText", publicName: "noSearchResultsText", isSignal: true, isRequired: false, transformFunction: null }, showBackdrop: { classPropertyName: "showBackdrop", publicName: "showBackdrop", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, searchTerm: { classPropertyName: "searchTerm", publicName: "searchTerm", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { opened: "opened", closed: "closed", selectionChange: "selectionChange", footerButtonClick: "footerButtonClick", headerButtonClick: "headerButtonClick", searchInputChange: "searchInputChange", searchTerm: "searchTermChange" }, queries: [{ propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true, isSignal: true }], viewQueries: [{ propertyName: "panel", first: true, predicate: DropdownPanelComponent, descendants: true, isSignal: true }, { propertyName: "inputSearchComponent", first: true, predicate: ["inputSearchElement"], descendants: true, isSignal: true }], ngImport: i0, template: "<ap-dropdown-panel\n [placement]=\"placement()\"\n [showBackdrop]=\"showBackdrop()\"\n (closed)=\"onPanelClosed()\">\n <div\n *apDropdownContent\n class=\"ap-selection-dropdown__content\"\n [class.ap-selection-dropdown__content--single]=\"isSingleSelect()\">\n <!-- Header -->\n @if (headerVisible()) {\n <div class=\"ap-selection-dropdown__header\">\n @if (headerTopVisible()) {\n <div class=\"ap-selection-dropdown__header-top\">\n @if (title()) {\n <h3 class=\"ap-selection-dropdown__title\">\n {{ title() }}\n </h3>\n }\n @if (headerButtonText()) {\n <a\n class=\"standalone\"\n role=\"link\"\n tabindex=\"0\"\n [id]=\"headerButtonId()\"\n (click)=\"onHeaderButtonClick()\"\n (keydown)=\"onHeaderButtonKeydown($event)\">\n <ap-symbol [symbolId]=\"headerButtonSymbolId()\" />\n {{ headerButtonText() }}\n </a>\n }\n </div>\n }\n @if (searchVisible()) {\n <ap-input-search\n #inputSearchElement\n [placeholder]=\"searchPlaceholderText()\"\n [clearable]=\"true\"\n [ngModel]=\"searchTerm()\"\n (ngModelChange)=\"onSearchTermChange($event)\" />\n }\n </div>\n }\n\n <!-- Selection dropdown items -->\n <div\n class=\"ap-selection-dropdown__items\"\n [attr.role]=\"isSingleSelect() ? 'listbox' : null\"\n [attr.aria-label]=\"isSingleSelect() ? title() : null\">\n @if (filteredItems().length === 0 && searchTerm()) {\n <div class=\"ap-selection-dropdown__no-results\">\n {{ noSearchResultsText() }}\n </div>\n } @else if (isSingleSelect()) {\n @for (item of filteredItems(); track item.htmlId) {\n <button\n type=\"button\"\n role=\"option\"\n class=\"ap-selection-dropdown__option\"\n [attr.aria-selected]=\"item.selected\"\n [attr.aria-disabled]=\"item.disabled || item.isFeatureLocked\"\n [attr.data-track]=\"item.dataTrack\"\n [apTooltip]=\"item.disabled ? (item.disabledTooltip ?? null) : null\"\n apTooltipPosition=\"right\"\n (click)=\"onItemToggle(item)\">\n <ap-dropdown-item-single-one-line\n [text]=\"item.text\"\n [selected]=\"item.selected\"\n [disabled]=\"item.disabled || false\"\n [avatarUrl]=\"item.avatarUrl\"\n [symbolId]=\"item.symbolId\"\n [badgeText]=\"item.badgeText\"\n [isFeatureLocked]=\"item.isFeatureLocked || false\"\n [roundedAvatar]=\"!!item.roundedAvatar\"\n [network]=\"item.network\"\n [standaloneModeEnabled]=\"true\" />\n </button>\n }\n } @else {\n <!-- Selected items section (at the top) -->\n @if (selectedItems().length > 0) {\n <div class=\"ap-selection-dropdown__selected-section\">\n @for (item of selectedItems(); track item.htmlId) {\n <div [apTooltip]=\"item.disabledTooltip\">\n <button\n type=\"button\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n class=\"ap-selection-dropdown__item-button\"\n [class.ap-selection-dropdown__item-button--disabled]=\"item.disabled || item.isFeatureLocked\"\n (click)=\"onItemToggle(item)\">\n <ap-dropdown-item-multiple-one-line\n class=\"ap-selection-dropdown__item\"\n [text]=\"item.text\"\n [selected]=\"item.selected\"\n [indeterminate]=\"item.indeterminate ?? false\"\n [htmlId]=\"item.htmlId\"\n [disabled]=\"item.disabled || false\"\n [avatarUrl]=\"item.avatarUrl\"\n [symbolId]=\"item.symbolId\"\n [badgeText]=\"item.badgeText\"\n [isFeatureLocked]=\"item.isFeatureLocked || false\"\n [roundedAvatar]=\"!!item.roundedAvatar\"\n [network]=\"item.network\"\n [symbolColor]=\"item.symbolColor\"\n [symbolTooltipText]=\"item.symbolTooltipText\" />\n </button>\n </div>\n }\n </div>\n }\n\n <!-- Unselected zone: items & groups in first-encounter order -->\n @for (entry of displayEntries(); track entryKey(entry)) {\n @if (entry.kind === 'item') {\n <div [apTooltip]=\"entry.item.disabledTooltip\">\n <button\n type=\"button\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n class=\"ap-selection-dropdown__item-button\"\n [class.ap-selection-dropdown__item-button--disabled]=\"entry.item.disabled || entry.item.isFeatureLocked\"\n (click)=\"onItemToggle(entry.item)\">\n <ap-dropdown-item-multiple-one-line\n class=\"ap-selection-dropdown__item\"\n [text]=\"entry.item.text\"\n [selected]=\"entry.item.selected\"\n [indeterminate]=\"entry.item.indeterminate ?? false\"\n [htmlId]=\"entry.item.htmlId\"\n [disabled]=\"entry.item.disabled || false\"\n [avatarUrl]=\"entry.item.avatarUrl\"\n [symbolId]=\"entry.item.symbolId\"\n [badgeText]=\"entry.item.badgeText\"\n [isFeatureLocked]=\"entry.item.isFeatureLocked || false\"\n [roundedAvatar]=\"!!entry.item.roundedAvatar\"\n [network]=\"entry.item.network\"\n [symbolColor]=\"entry.item.symbolColor\"\n [symbolTooltipText]=\"entry.item.symbolTooltipText\" />\n </button>\n </div>\n } @else {\n <div class=\"ap-selection-dropdown__group\">\n <!-- Group header with checkbox -->\n <div class=\"ap-selection-dropdown__group-header\">\n <div class=\"ap-selection-dropdown__group-label\">\n <ap-checkbox\n class=\"centered\"\n [name]=\"entry.label\"\n [checked]=\"groupSelectionStates()[entry.label] === 'selected'\"\n [indeterminate]=\"groupSelectionStates()[entry.label] === 'partial'\"\n (change)=\"onGroupToggle(entry.label, $event)\">\n {{ entry.label }}\n </ap-checkbox>\n </div>\n </div>\n\n <!-- Group items -->\n @for (item of entry.items; track item.htmlId) {\n <div [apTooltip]=\"item.disabledTooltip\">\n <button\n type=\"button\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n class=\"ap-selection-dropdown__item-button\"\n [class.ap-selection-dropdown__item-button--disabled]=\"item.disabled || item.isFeatureLocked\"\n (click)=\"onItemToggle(item)\">\n <ap-dropdown-item-multiple-one-line\n class=\"ap-selection-dropdown__item ap-selection-dropdown__item--grouped\"\n [text]=\"item.text\"\n [selected]=\"item.selected\"\n [indeterminate]=\"item.indeterminate ?? false\"\n [htmlId]=\"item.htmlId\"\n [disabled]=\"item.disabled || false\"\n [avatarUrl]=\"item.avatarUrl\"\n [symbolId]=\"item.symbolId\"\n [badgeText]=\"item.badgeText\"\n [isFeatureLocked]=\"item.isFeatureLocked || false\"\n [roundedAvatar]=\"!!item.roundedAvatar\"\n [network]=\"item.network\"\n [symbolColor]=\"item.symbolColor\"\n [symbolTooltipText]=\"item.symbolTooltipText\" />\n </button>\n </div>\n }\n </div>\n }\n }\n }\n </div>\n\n <!-- Footer -->\n @if (footerButtonText()) {\n <div class=\"ap-selection-dropdown__footer\">\n <a\n class=\"standalone\"\n role=\"link\"\n tabindex=\"0\"\n [id]=\"footerButtonId()\"\n (click)=\"onFooterButtonClick()\"\n (keydown)=\"onFooterButtonKeydown($event)\">\n <ap-symbol [symbolId]=\"footerButtonSymbolId()\" />\n {{ footerButtonText() }}\n </a>\n </div>\n }\n </div>\n</ap-dropdown-panel>\n", styles: [":host{display:none}.ap-selection-dropdown__content{border-radius:inherit;overflow:hidden;z-index:1000;width:370px;display:flex;flex-direction:column;max-height:min(400px,var(--ap-floating-available-height, 100vh))}.ap-selection-dropdown__content--single{width:auto;min-width:160px}.ap-selection-dropdown__option{display:block;width:100%;padding:0;border:none;background:none;font:inherit;text-align:inherit}.ap-selection-dropdown__item-button{display:block;width:100%;padding:0;margin:0;border:none;background:transparent;text-align:left;cursor:pointer;outline:none}.ap-selection-dropdown__item-button:hover{background-color:var(--ref-color-electric-blue-10)}.ap-selection-dropdown__item-button:active{background-color:var(--ref-color-electric-blue-20)}.ap-selection-dropdown__item-button:focus{outline:none}.ap-selection-dropdown__item-button:focus-visible{outline:none}.ap-selection-dropdown__item-button.ap-selection-dropdown__item-button--disabled{pointer-events:none}.ap-selection-dropdown__item{display:flex;align-items:center;width:100%;min-height:40px;padding:var(--ref-spacing-xxs) var(--ref-spacing-sm);background:transparent;cursor:pointer;font-family:Averta}.ap-selection-dropdown__group-header{display:flex;align-items:center;padding:var(--ref-spacing-xxs) var(--ref-spacing-sm);border-top:1px solid var(--ref-color-grey-10);background:var(--ref-color-grey-bg)}.ap-selection-dropdown__group-label{display:flex;align-items:center;flex:1;font-weight:700;color:var(--ref-color-grey-100)}.ap-selection-dropdown__group-label ap-checkbox{--comp-forms-label-font-weight: 700}.ap-selection-dropdown__header{border-bottom:1px solid var(--ref-color-grey-10);flex-shrink:0;display:flex;flex-direction:column}.ap-selection-dropdown__header .ap-selection-dropdown__header-top{display:flex;align-items:center;justify-content:space-between;padding:var(--ref-spacing-xs) var(--ref-spacing-sm)}.ap-selection-dropdown__header .ap-selection-dropdown__title{margin:0;font-size:var(--ref-font-size-md);font-weight:var(--ref-font-weight-bold);color:var(--ref-color-grey-100);flex:1}.ap-selection-dropdown__header ap-input-search{width:100%;padding:0 var(--ref-spacing-xxs) var(--ref-spacing-xxs)}.ap-selection-dropdown__items{padding:var(--ref-spacing-xxs) 0;flex:1;overflow-y:auto;min-height:0}.ap-selection-dropdown__no-results{padding:var(--ref-spacing-xxs) var(--ref-spacing-sm);color:var(--ref-color-grey-80);font-size:var(--ref-font-size-sm);font-style:italic}.ap-selection-dropdown__footer{height:40px;padding:var(--ref-spacing-xs) var(--ref-spacing-sm);border-top:1px solid var(--ref-color-grey-10);flex-shrink:0;display:flex;align-items:center;justify-content:flex-start}.ap-selection-dropdown__selected-section{margin-bottom:var(--ref-spacing-xxs);border-bottom:1px solid var(--ref-color-grey-10);padding-bottom:var(--ref-spacing-xxs)}.ap-selection-dropdown__selected-section ::ng-deep ap-checkbox{--comp-forms-label-font-weight: 700}\n"], dependencies: [{ kind: "component", type: CheckboxComponent, selector: "ap-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "disabled", "indeterminate", "checked", "fullyControlled", "required", "name"], outputs: ["change"] }, { kind: "directive", type: DropdownContentDirective, selector: "ng-template[apDropdownContent]" }, { kind: "component", type: DropdownItemMultipleOneLineComponent, selector: "ap-dropdown-item-multiple-one-line", inputs: ["text", "selected", "indeterminate", "htmlId", "disabled", "avatarUrl", "symbolId", "disabledTooltip", "badgeText", "dividerEnabled", "onlyEnabled", "onlyText", "isFeatureLocked", "roundedAvatar", "network", "symbolColor", "symbolTooltipText"], outputs: ["selectOnly", "lockedFeatureClicked"] }, { kind: "component", type: DropdownItemSingleOneLineComponent, selector: "ap-dropdown-item-single-one-line", inputs: ["text", "selected", "disabled", "avatarUrl", "showAvatarInitials", "symbolId", "disabledTooltip", "badgeText", "dividerEnabled", "network", "roundedAvatar", "isFeatureLocked", "standaloneModeEnabled"], outputs: ["lockedFeatureClicked"] }, { kind: "component", type: DropdownPanelComponent, selector: "ap-dropdown-panel", inputs: ["placement", "showBackdrop", "panelClass", "canDismiss"], outputs: ["opened", "closed"] }, { 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"] }, { kind: "component", type: SymbolComponent, selector: "ap-symbol", inputs: ["symbolId", "color", "size"], outputs: ["sizeChange"] }, { kind: "directive", type: TooltipDirective, selector: "[apTooltip]", inputs: ["apTooltip", "apTooltipPosition", "apTooltipShowDelay", "apTooltipHideDelay", "apTooltipDuration", "apTooltipDisabled", "apTooltipTruncatedTextOnly", "apTooltipTemplateContext", "apTooltipVirtualScrollElement", "apTooltipTrigger", "apTooltipType", "apTooltipPresentationContext", "apTooltipListItems", "apTooltipShowAvatarCaption"], exportAs: ["apTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
520
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: SelectionDropdownComponent, isStandalone: true, selector: "ap-selection-dropdown", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, selectedSectionText: { classPropertyName: "selectedSectionText", publicName: "selectedSectionText", isSignal: true, isRequired: false, transformFunction: null }, optionsSectionText: { classPropertyName: "optionsSectionText", publicName: "optionsSectionText", isSignal: true, isRequired: false, transformFunction: null }, headerButtonId: { classPropertyName: "headerButtonId", publicName: "headerButtonId", isSignal: true, isRequired: false, transformFunction: null }, footerButtonId: { classPropertyName: "footerButtonId", publicName: "footerButtonId", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, searchEnabled: { classPropertyName: "searchEnabled", publicName: "searchEnabled", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, footerButtonText: { classPropertyName: "footerButtonText", publicName: "footerButtonText", isSignal: true, isRequired: false, transformFunction: null }, footerButtonSymbolId: { classPropertyName: "footerButtonSymbolId", publicName: "footerButtonSymbolId", isSignal: true, isRequired: false, transformFunction: null }, headerButtonText: { classPropertyName: "headerButtonText", publicName: "headerButtonText", isSignal: true, isRequired: false, transformFunction: null }, headerButtonSymbolId: { classPropertyName: "headerButtonSymbolId", publicName: "headerButtonSymbolId", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholderText: { classPropertyName: "searchPlaceholderText", publicName: "searchPlaceholderText", isSignal: true, isRequired: false, transformFunction: null }, noSearchResultsText: { classPropertyName: "noSearchResultsText", publicName: "noSearchResultsText", isSignal: true, isRequired: false, transformFunction: null }, searchResultsText: { classPropertyName: "searchResultsText", publicName: "searchResultsText", isSignal: true, isRequired: false, transformFunction: null }, showBackdrop: { classPropertyName: "showBackdrop", publicName: "showBackdrop", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, searchTerm: { classPropertyName: "searchTerm", publicName: "searchTerm", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { opened: "opened", closed: "closed", selectionChange: "selectionChange", footerButtonClick: "footerButtonClick", headerButtonClick: "headerButtonClick", searchInputChange: "searchInputChange", searchTerm: "searchTermChange" }, queries: [{ propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true, isSignal: true }], viewQueries: [{ propertyName: "panel", first: true, predicate: DropdownPanelComponent, descendants: true, isSignal: true }, { propertyName: "options", predicate: DropdownOptionDirective, descendants: true, isSignal: true }, { propertyName: "inputSearchComponent", first: true, predicate: ["inputSearchElement"], descendants: true, isSignal: true }], ngImport: i0, template: "<ap-dropdown-panel\n [placement]=\"placement()\"\n [showBackdrop]=\"showBackdrop()\"\n (closed)=\"onPanelClosed()\">\n <!-- `dialog`, not a combobox: a combobox must close when focus leaves it, and this panel holds a\n search field, a header, a footer and group checkboxes beside its lists \u2014 closing on Tab left\n every one of them unreachable. -->\n <div\n *apDropdownContent\n class=\"ap-selection-dropdown__content\"\n role=\"dialog\"\n tabindex=\"-1\"\n [attr.aria-label]=\"panelLabel()\"\n (keydown)=\"onOptionsKeyDown($event)\"\n [class.ap-selection-dropdown__content--single]=\"isSingleSelect()\">\n <!-- Header -->\n @if (headerVisible()) {\n <div class=\"ap-selection-dropdown__header\">\n @if (headerTopVisible()) {\n <div class=\"ap-selection-dropdown__header-top\">\n @if (title()) {\n <h3 class=\"ap-selection-dropdown__title\">\n {{ title() }}\n </h3>\n }\n @if (headerButtonText()) {\n <button\n type=\"button\"\n class=\"ap-link standalone\"\n [id]=\"headerButtonId()\"\n (click)=\"onHeaderButtonClick()\">\n <ap-symbol [symbolId]=\"headerButtonSymbolId()\" />\n {{ headerButtonText() }}\n </button>\n }\n </div>\n }\n @if (searchVisible()) {\n <ap-input-search\n #inputSearchElement\n [placeholder]=\"searchPlaceholderText()\"\n [clearable]=\"true\"\n [ariaControls]=\"listboxId\"\n [ariaActiveDescendant]=\"activeDescendantId()\"\n [ngModel]=\"searchTerm()\"\n (blur)=\"onSearchBlur()\"\n (ngModelChange)=\"onSearchTermChange($event)\" />\n }\n </div>\n }\n\n <!-- Selection dropdown items -->\n <div\n class=\"ap-selection-dropdown__items\"\n [id]=\"listboxId\"\n [attr.role]=\"isSingleSelect() ? 'listbox' : null\"\n [attr.aria-label]=\"isSingleSelect() ? (title() ?? null) : null\">\n @if (filteredItems().length === 0 && searchTerm()) {\n <div class=\"ap-selection-dropdown__no-results\">\n {{ noSearchResultsText() }}\n </div>\n } @else if (isSingleSelect()) {\n @for (item of filteredItems(); track item.htmlId) {\n <button\n type=\"button\"\n role=\"option\"\n class=\"ap-selection-dropdown__option\"\n [id]=\"optionId(item)\"\n [apDropdownOption]=\"item.text\"\n [apDropdownOptionDisabled]=\"!!(item.disabled || item.isFeatureLocked)\"\n [tabindex]=\"optionTabIndex(activeIndex() === $index)\"\n [attr.aria-selected]=\"item.selected\"\n [attr.aria-disabled]=\"item.disabled || item.isFeatureLocked\"\n [attr.data-track]=\"item.dataTrack\"\n [apTooltip]=\"item.disabled ? (item.disabledTooltip ?? null) : null\"\n apTooltipPosition=\"right\"\n (click)=\"onItemToggle(item)\">\n <ap-dropdown-item-single-one-line\n [text]=\"item.text\"\n [selected]=\"item.selected\"\n [disabled]=\"item.disabled || false\"\n [avatarUrl]=\"item.avatarUrl\"\n [symbolId]=\"item.symbolId\"\n [badgeText]=\"item.badgeText\"\n [isFeatureLocked]=\"item.isFeatureLocked || false\"\n [roundedAvatar]=\"!!item.roundedAvatar\"\n [network]=\"item.network\"\n [standaloneModeEnabled]=\"true\" />\n </button>\n }\n } @else {\n <!-- A listbox owns only options, so each section is its own, and a group's checkbox sits beside it. -->\n @if (selectedItems().length > 0) {\n <div\n role=\"listbox\"\n aria-multiselectable=\"true\"\n class=\"ap-selection-dropdown__selected-section\"\n [attr.aria-label]=\"selectedSectionText()\">\n @for (item of selectedItems(); track item.htmlId) {\n @let grouped = false;\n <button\n type=\"button\"\n role=\"option\"\n class=\"ap-selection-dropdown__item-button\"\n [id]=\"optionId(item)\"\n [tabindex]=\"optionTabIndex(tabbableOption(item))\"\n [apDropdownOption]=\"item.text\"\n [apDropdownOptionDisabled]=\"!!(item.disabled || item.isFeatureLocked)\"\n [attr.aria-selected]=\"item.selected\"\n [class.ap-selection-dropdown__item-button--disabled]=\"item.disabled || item.isFeatureLocked\"\n [apTooltip]=\"item.disabledTooltip\"\n (click)=\"onItemToggle(item)\">\n <ap-dropdown-item-multiple-one-line\n presentational\n class=\"ap-selection-dropdown__item\"\n [class.ap-selection-dropdown__item--grouped]=\"grouped\"\n [text]=\"item.text\"\n [selected]=\"item.selected\"\n [indeterminate]=\"item.indeterminate ?? false\"\n [htmlId]=\"item.htmlId\"\n [disabled]=\"item.disabled || false\"\n [avatarUrl]=\"item.avatarUrl\"\n [symbolId]=\"item.symbolId\"\n [badgeText]=\"item.badgeText\"\n [isFeatureLocked]=\"item.isFeatureLocked || false\"\n [roundedAvatar]=\"!!item.roundedAvatar\"\n [network]=\"item.network\"\n [symbolColor]=\"item.symbolColor\"\n [symbolTooltipText]=\"item.symbolTooltipText\" />\n </button>\n }\n </div>\n }\n\n <!-- Unselected zone: items & groups in first-encounter order -->\n @for (run of displayRuns(); track runKey(run)) {\n @if (run.kind === 'items') {\n <div\n role=\"listbox\"\n aria-multiselectable=\"true\"\n [attr.aria-label]=\"title() ?? optionsSectionText()\">\n @for (item of run.items; track item.htmlId) {\n @let grouped = false;\n <button\n type=\"button\"\n role=\"option\"\n class=\"ap-selection-dropdown__item-button\"\n [id]=\"optionId(item)\"\n [tabindex]=\"optionTabIndex(tabbableOption(item))\"\n [apDropdownOption]=\"item.text\"\n [apDropdownOptionDisabled]=\"!!(item.disabled || item.isFeatureLocked)\"\n [attr.aria-selected]=\"item.selected\"\n [class.ap-selection-dropdown__item-button--disabled]=\"item.disabled || item.isFeatureLocked\"\n [apTooltip]=\"item.disabledTooltip\"\n (click)=\"onItemToggle(item)\">\n <ap-dropdown-item-multiple-one-line\n presentational\n class=\"ap-selection-dropdown__item\"\n [class.ap-selection-dropdown__item--grouped]=\"grouped\"\n [text]=\"item.text\"\n [selected]=\"item.selected\"\n [indeterminate]=\"item.indeterminate ?? false\"\n [htmlId]=\"item.htmlId\"\n [disabled]=\"item.disabled || false\"\n [avatarUrl]=\"item.avatarUrl\"\n [symbolId]=\"item.symbolId\"\n [badgeText]=\"item.badgeText\"\n [isFeatureLocked]=\"item.isFeatureLocked || false\"\n [roundedAvatar]=\"!!item.roundedAvatar\"\n [network]=\"item.network\"\n [symbolColor]=\"item.symbolColor\"\n [symbolTooltipText]=\"item.symbolTooltipText\" />\n </button>\n }\n </div>\n } @else {\n <div class=\"ap-selection-dropdown__group\">\n <!-- Group header with checkbox -->\n <div class=\"ap-selection-dropdown__group-header\">\n <div class=\"ap-selection-dropdown__group-label\">\n <ap-checkbox\n class=\"centered\"\n [name]=\"run.label\"\n [checked]=\"groupSelectionStates()[run.label] === 'selected'\"\n [indeterminate]=\"groupSelectionStates()[run.label] === 'partial'\"\n (change)=\"onGroupToggle(run.label, $event)\">\n {{ run.label }}\n </ap-checkbox>\n </div>\n </div>\n\n <div\n role=\"listbox\"\n aria-multiselectable=\"true\"\n [attr.aria-label]=\"run.label\">\n @for (item of run.items; track item.htmlId) {\n @let grouped = true;\n <button\n type=\"button\"\n role=\"option\"\n class=\"ap-selection-dropdown__item-button\"\n [id]=\"optionId(item)\"\n [tabindex]=\"optionTabIndex(tabbableOption(item))\"\n [apDropdownOption]=\"item.text\"\n [apDropdownOptionDisabled]=\"!!(item.disabled || item.isFeatureLocked)\"\n [attr.aria-selected]=\"item.selected\"\n [class.ap-selection-dropdown__item-button--disabled]=\"item.disabled || item.isFeatureLocked\"\n [apTooltip]=\"item.disabledTooltip\"\n (click)=\"onItemToggle(item)\">\n <ap-dropdown-item-multiple-one-line\n presentational\n class=\"ap-selection-dropdown__item\"\n [class.ap-selection-dropdown__item--grouped]=\"grouped\"\n [text]=\"item.text\"\n [selected]=\"item.selected\"\n [indeterminate]=\"item.indeterminate ?? false\"\n [htmlId]=\"item.htmlId\"\n [disabled]=\"item.disabled || false\"\n [avatarUrl]=\"item.avatarUrl\"\n [symbolId]=\"item.symbolId\"\n [badgeText]=\"item.badgeText\"\n [isFeatureLocked]=\"item.isFeatureLocked || false\"\n [roundedAvatar]=\"!!item.roundedAvatar\"\n [network]=\"item.network\"\n [symbolColor]=\"item.symbolColor\"\n [symbolTooltipText]=\"item.symbolTooltipText\" />\n </button>\n }\n </div>\n </div>\n }\n }\n }\n </div>\n\n <div\n class=\"ap-selection-dropdown__status\"\n role=\"status\"\n aria-atomic=\"true\">\n {{ resultsAnnouncement() }}\n </div>\n\n <!-- Footer -->\n @if (footerButtonText()) {\n <div class=\"ap-selection-dropdown__footer\">\n <button\n type=\"button\"\n class=\"ap-link standalone\"\n [id]=\"footerButtonId()\"\n (click)=\"onFooterButtonClick()\">\n <ap-symbol [symbolId]=\"footerButtonSymbolId()\" />\n {{ footerButtonText() }}\n </button>\n </div>\n }\n </div>\n</ap-dropdown-panel>\n", styles: [":host{display:none}.ap-selection-dropdown__content{border-radius:inherit;overflow:hidden;z-index:1000;width:370px;display:flex;flex-direction:column;max-height:min(400px,var(--ap-floating-available-height, 100vh))}.ap-selection-dropdown__content--single{width:auto;min-width:160px}.ap-selection-dropdown__option{display:block;width:100%;padding:0;border:none;background:none;font:inherit;text-align:inherit}.ap-selection-dropdown__item-button{display:block;width:100%;padding:0;margin:0;border:none;background:transparent;text-align:left;cursor:pointer;outline:none}.ap-selection-dropdown__item-button:hover,.ap-selection-dropdown__item-button.ap-dropdown-option--active{background-color:var(--ref-color-electric-blue-10)}.ap-selection-dropdown__item-button:active{background-color:var(--ref-color-electric-blue-20)}.ap-selection-dropdown__item-button:focus{outline:none}.ap-selection-dropdown__item-button:focus-visible{outline:none}.ap-selection-dropdown__item-button.ap-selection-dropdown__item-button--disabled{pointer-events:none}.ap-selection-dropdown__item{display:flex;align-items:center;width:100%;min-height:40px;padding:var(--ref-spacing-xxs) var(--ref-spacing-sm);background:transparent;cursor:pointer;font-family:Averta}.ap-selection-dropdown__group-header{display:flex;align-items:center;padding:var(--ref-spacing-xxs) var(--ref-spacing-sm);border-top:1px solid var(--ref-color-grey-10);background:var(--ref-color-grey-bg)}.ap-selection-dropdown__group-label{display:flex;align-items:center;flex:1;font-weight:700;color:var(--ref-color-grey-100)}.ap-selection-dropdown__group-label ap-checkbox{--comp-forms-label-font-weight: 700}.ap-selection-dropdown__header{border-bottom:1px solid var(--ref-color-grey-10);flex-shrink:0;display:flex;flex-direction:column}.ap-selection-dropdown__header .ap-selection-dropdown__header-top{display:flex;align-items:center;justify-content:space-between;padding:var(--ref-spacing-xs) var(--ref-spacing-sm)}.ap-selection-dropdown__header .ap-selection-dropdown__title{margin:0;font-size:var(--ref-font-size-md);font-weight:var(--ref-font-weight-bold);color:var(--ref-color-grey-100);flex:1}.ap-selection-dropdown__header ap-input-search{width:100%;padding:0 var(--ref-spacing-xxs) var(--ref-spacing-xxs)}.ap-selection-dropdown__items{padding:var(--ref-spacing-xxs) 0;flex:1;overflow-y:auto;min-height:0}.ap-selection-dropdown__no-results{padding:var(--ref-spacing-xxs) var(--ref-spacing-sm);color:var(--ref-color-grey-80);font-size:var(--ref-font-size-sm);font-style:italic}.ap-selection-dropdown__footer{height:40px;padding:var(--ref-spacing-xs) var(--ref-spacing-sm);border-top:1px solid var(--ref-color-grey-10);flex-shrink:0;display:flex;align-items:center;justify-content:flex-start}.ap-selection-dropdown__selected-section{margin-bottom:var(--ref-spacing-xxs);border-bottom:1px solid var(--ref-color-grey-10);padding-bottom:var(--ref-spacing-xxs)}.ap-selection-dropdown__selected-section ::ng-deep ap-checkbox{--comp-forms-label-font-weight: 700}.ap-selection-dropdown__status{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}\n"], dependencies: [{ kind: "component", type: CheckboxComponent, selector: "ap-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "disabled", "indeterminate", "checked", "fullyControlled", "presentational", "required", "name"], outputs: ["change"] }, { kind: "directive", type: DropdownContentDirective, selector: "ng-template[apDropdownContent]" }, { kind: "directive", type: DropdownOptionDirective, selector: "[apDropdownOption]", inputs: ["apDropdownOption", "apDropdownOptionDisabled"] }, { kind: "component", type: DropdownItemMultipleOneLineComponent, selector: "ap-dropdown-item-multiple-one-line", inputs: ["text", "selected", "indeterminate", "htmlId", "disabled", "avatarUrl", "symbolId", "disabledTooltip", "badgeText", "dividerEnabled", "presentational", "onlyEnabled", "onlyText", "isFeatureLocked", "roundedAvatar", "network", "symbolColor", "symbolTooltipText"], outputs: ["selectOnly", "lockedFeatureClicked"] }, { kind: "component", type: DropdownItemSingleOneLineComponent, selector: "ap-dropdown-item-single-one-line", inputs: ["text", "selected", "disabled", "avatarUrl", "showAvatarInitials", "symbolId", "disabledTooltip", "badgeText", "dividerEnabled", "network", "roundedAvatar", "isFeatureLocked", "standaloneModeEnabled"], outputs: ["lockedFeatureClicked"] }, { kind: "component", type: DropdownPanelComponent, selector: "ap-dropdown-panel", inputs: ["placement", "showBackdrop", "panelClass", "canDismiss"], outputs: ["opened", "closed"] }, { 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", "ariaControls", "ariaActiveDescendant"], outputs: ["focus", "blur", "keyup"] }, { kind: "component", type: SymbolComponent, selector: "ap-symbol", inputs: ["symbolId", "color", "size"], outputs: ["sizeChange"] }, { kind: "directive", type: TooltipDirective, selector: "[apTooltip]", inputs: ["apTooltip", "apTooltipPosition", "apTooltipShowDelay", "apTooltipHideDelay", "apTooltipDuration", "apTooltipDisabled", "apTooltipTruncatedTextOnly", "apTooltipTemplateContext", "apTooltipVirtualScrollElement", "apTooltipTrigger", "apTooltipType", "apTooltipPresentationContext", "apTooltipListItems", "apTooltipShowAvatarCaption"], exportAs: ["apTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
378
521
  }
379
522
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: SelectionDropdownComponent, decorators: [{
380
523
  type: Component,
381
524
  args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'ap-selection-dropdown', imports: [
382
525
  CheckboxComponent,
383
526
  DropdownContentDirective,
527
+ DropdownOptionDirective,
384
528
  DropdownItemMultipleOneLineComponent,
385
529
  DropdownItemSingleOneLineComponent,
386
530
  DropdownPanelComponent,
@@ -388,8 +532,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
388
532
  InputSearchComponent,
389
533
  SymbolComponent,
390
534
  TooltipDirective,
391
- ], template: "<ap-dropdown-panel\n [placement]=\"placement()\"\n [showBackdrop]=\"showBackdrop()\"\n (closed)=\"onPanelClosed()\">\n <div\n *apDropdownContent\n class=\"ap-selection-dropdown__content\"\n [class.ap-selection-dropdown__content--single]=\"isSingleSelect()\">\n <!-- Header -->\n @if (headerVisible()) {\n <div class=\"ap-selection-dropdown__header\">\n @if (headerTopVisible()) {\n <div class=\"ap-selection-dropdown__header-top\">\n @if (title()) {\n <h3 class=\"ap-selection-dropdown__title\">\n {{ title() }}\n </h3>\n }\n @if (headerButtonText()) {\n <a\n class=\"standalone\"\n role=\"link\"\n tabindex=\"0\"\n [id]=\"headerButtonId()\"\n (click)=\"onHeaderButtonClick()\"\n (keydown)=\"onHeaderButtonKeydown($event)\">\n <ap-symbol [symbolId]=\"headerButtonSymbolId()\" />\n {{ headerButtonText() }}\n </a>\n }\n </div>\n }\n @if (searchVisible()) {\n <ap-input-search\n #inputSearchElement\n [placeholder]=\"searchPlaceholderText()\"\n [clearable]=\"true\"\n [ngModel]=\"searchTerm()\"\n (ngModelChange)=\"onSearchTermChange($event)\" />\n }\n </div>\n }\n\n <!-- Selection dropdown items -->\n <div\n class=\"ap-selection-dropdown__items\"\n [attr.role]=\"isSingleSelect() ? 'listbox' : null\"\n [attr.aria-label]=\"isSingleSelect() ? title() : null\">\n @if (filteredItems().length === 0 && searchTerm()) {\n <div class=\"ap-selection-dropdown__no-results\">\n {{ noSearchResultsText() }}\n </div>\n } @else if (isSingleSelect()) {\n @for (item of filteredItems(); track item.htmlId) {\n <button\n type=\"button\"\n role=\"option\"\n class=\"ap-selection-dropdown__option\"\n [attr.aria-selected]=\"item.selected\"\n [attr.aria-disabled]=\"item.disabled || item.isFeatureLocked\"\n [attr.data-track]=\"item.dataTrack\"\n [apTooltip]=\"item.disabled ? (item.disabledTooltip ?? null) : null\"\n apTooltipPosition=\"right\"\n (click)=\"onItemToggle(item)\">\n <ap-dropdown-item-single-one-line\n [text]=\"item.text\"\n [selected]=\"item.selected\"\n [disabled]=\"item.disabled || false\"\n [avatarUrl]=\"item.avatarUrl\"\n [symbolId]=\"item.symbolId\"\n [badgeText]=\"item.badgeText\"\n [isFeatureLocked]=\"item.isFeatureLocked || false\"\n [roundedAvatar]=\"!!item.roundedAvatar\"\n [network]=\"item.network\"\n [standaloneModeEnabled]=\"true\" />\n </button>\n }\n } @else {\n <!-- Selected items section (at the top) -->\n @if (selectedItems().length > 0) {\n <div class=\"ap-selection-dropdown__selected-section\">\n @for (item of selectedItems(); track item.htmlId) {\n <div [apTooltip]=\"item.disabledTooltip\">\n <button\n type=\"button\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n class=\"ap-selection-dropdown__item-button\"\n [class.ap-selection-dropdown__item-button--disabled]=\"item.disabled || item.isFeatureLocked\"\n (click)=\"onItemToggle(item)\">\n <ap-dropdown-item-multiple-one-line\n class=\"ap-selection-dropdown__item\"\n [text]=\"item.text\"\n [selected]=\"item.selected\"\n [indeterminate]=\"item.indeterminate ?? false\"\n [htmlId]=\"item.htmlId\"\n [disabled]=\"item.disabled || false\"\n [avatarUrl]=\"item.avatarUrl\"\n [symbolId]=\"item.symbolId\"\n [badgeText]=\"item.badgeText\"\n [isFeatureLocked]=\"item.isFeatureLocked || false\"\n [roundedAvatar]=\"!!item.roundedAvatar\"\n [network]=\"item.network\"\n [symbolColor]=\"item.symbolColor\"\n [symbolTooltipText]=\"item.symbolTooltipText\" />\n </button>\n </div>\n }\n </div>\n }\n\n <!-- Unselected zone: items & groups in first-encounter order -->\n @for (entry of displayEntries(); track entryKey(entry)) {\n @if (entry.kind === 'item') {\n <div [apTooltip]=\"entry.item.disabledTooltip\">\n <button\n type=\"button\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n class=\"ap-selection-dropdown__item-button\"\n [class.ap-selection-dropdown__item-button--disabled]=\"entry.item.disabled || entry.item.isFeatureLocked\"\n (click)=\"onItemToggle(entry.item)\">\n <ap-dropdown-item-multiple-one-line\n class=\"ap-selection-dropdown__item\"\n [text]=\"entry.item.text\"\n [selected]=\"entry.item.selected\"\n [indeterminate]=\"entry.item.indeterminate ?? false\"\n [htmlId]=\"entry.item.htmlId\"\n [disabled]=\"entry.item.disabled || false\"\n [avatarUrl]=\"entry.item.avatarUrl\"\n [symbolId]=\"entry.item.symbolId\"\n [badgeText]=\"entry.item.badgeText\"\n [isFeatureLocked]=\"entry.item.isFeatureLocked || false\"\n [roundedAvatar]=\"!!entry.item.roundedAvatar\"\n [network]=\"entry.item.network\"\n [symbolColor]=\"entry.item.symbolColor\"\n [symbolTooltipText]=\"entry.item.symbolTooltipText\" />\n </button>\n </div>\n } @else {\n <div class=\"ap-selection-dropdown__group\">\n <!-- Group header with checkbox -->\n <div class=\"ap-selection-dropdown__group-header\">\n <div class=\"ap-selection-dropdown__group-label\">\n <ap-checkbox\n class=\"centered\"\n [name]=\"entry.label\"\n [checked]=\"groupSelectionStates()[entry.label] === 'selected'\"\n [indeterminate]=\"groupSelectionStates()[entry.label] === 'partial'\"\n (change)=\"onGroupToggle(entry.label, $event)\">\n {{ entry.label }}\n </ap-checkbox>\n </div>\n </div>\n\n <!-- Group items -->\n @for (item of entry.items; track item.htmlId) {\n <div [apTooltip]=\"item.disabledTooltip\">\n <button\n type=\"button\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n class=\"ap-selection-dropdown__item-button\"\n [class.ap-selection-dropdown__item-button--disabled]=\"item.disabled || item.isFeatureLocked\"\n (click)=\"onItemToggle(item)\">\n <ap-dropdown-item-multiple-one-line\n class=\"ap-selection-dropdown__item ap-selection-dropdown__item--grouped\"\n [text]=\"item.text\"\n [selected]=\"item.selected\"\n [indeterminate]=\"item.indeterminate ?? false\"\n [htmlId]=\"item.htmlId\"\n [disabled]=\"item.disabled || false\"\n [avatarUrl]=\"item.avatarUrl\"\n [symbolId]=\"item.symbolId\"\n [badgeText]=\"item.badgeText\"\n [isFeatureLocked]=\"item.isFeatureLocked || false\"\n [roundedAvatar]=\"!!item.roundedAvatar\"\n [network]=\"item.network\"\n [symbolColor]=\"item.symbolColor\"\n [symbolTooltipText]=\"item.symbolTooltipText\" />\n </button>\n </div>\n }\n </div>\n }\n }\n }\n </div>\n\n <!-- Footer -->\n @if (footerButtonText()) {\n <div class=\"ap-selection-dropdown__footer\">\n <a\n class=\"standalone\"\n role=\"link\"\n tabindex=\"0\"\n [id]=\"footerButtonId()\"\n (click)=\"onFooterButtonClick()\"\n (keydown)=\"onFooterButtonKeydown($event)\">\n <ap-symbol [symbolId]=\"footerButtonSymbolId()\" />\n {{ footerButtonText() }}\n </a>\n </div>\n }\n </div>\n</ap-dropdown-panel>\n", styles: [":host{display:none}.ap-selection-dropdown__content{border-radius:inherit;overflow:hidden;z-index:1000;width:370px;display:flex;flex-direction:column;max-height:min(400px,var(--ap-floating-available-height, 100vh))}.ap-selection-dropdown__content--single{width:auto;min-width:160px}.ap-selection-dropdown__option{display:block;width:100%;padding:0;border:none;background:none;font:inherit;text-align:inherit}.ap-selection-dropdown__item-button{display:block;width:100%;padding:0;margin:0;border:none;background:transparent;text-align:left;cursor:pointer;outline:none}.ap-selection-dropdown__item-button:hover{background-color:var(--ref-color-electric-blue-10)}.ap-selection-dropdown__item-button:active{background-color:var(--ref-color-electric-blue-20)}.ap-selection-dropdown__item-button:focus{outline:none}.ap-selection-dropdown__item-button:focus-visible{outline:none}.ap-selection-dropdown__item-button.ap-selection-dropdown__item-button--disabled{pointer-events:none}.ap-selection-dropdown__item{display:flex;align-items:center;width:100%;min-height:40px;padding:var(--ref-spacing-xxs) var(--ref-spacing-sm);background:transparent;cursor:pointer;font-family:Averta}.ap-selection-dropdown__group-header{display:flex;align-items:center;padding:var(--ref-spacing-xxs) var(--ref-spacing-sm);border-top:1px solid var(--ref-color-grey-10);background:var(--ref-color-grey-bg)}.ap-selection-dropdown__group-label{display:flex;align-items:center;flex:1;font-weight:700;color:var(--ref-color-grey-100)}.ap-selection-dropdown__group-label ap-checkbox{--comp-forms-label-font-weight: 700}.ap-selection-dropdown__header{border-bottom:1px solid var(--ref-color-grey-10);flex-shrink:0;display:flex;flex-direction:column}.ap-selection-dropdown__header .ap-selection-dropdown__header-top{display:flex;align-items:center;justify-content:space-between;padding:var(--ref-spacing-xs) var(--ref-spacing-sm)}.ap-selection-dropdown__header .ap-selection-dropdown__title{margin:0;font-size:var(--ref-font-size-md);font-weight:var(--ref-font-weight-bold);color:var(--ref-color-grey-100);flex:1}.ap-selection-dropdown__header ap-input-search{width:100%;padding:0 var(--ref-spacing-xxs) var(--ref-spacing-xxs)}.ap-selection-dropdown__items{padding:var(--ref-spacing-xxs) 0;flex:1;overflow-y:auto;min-height:0}.ap-selection-dropdown__no-results{padding:var(--ref-spacing-xxs) var(--ref-spacing-sm);color:var(--ref-color-grey-80);font-size:var(--ref-font-size-sm);font-style:italic}.ap-selection-dropdown__footer{height:40px;padding:var(--ref-spacing-xs) var(--ref-spacing-sm);border-top:1px solid var(--ref-color-grey-10);flex-shrink:0;display:flex;align-items:center;justify-content:flex-start}.ap-selection-dropdown__selected-section{margin-bottom:var(--ref-spacing-xxs);border-bottom:1px solid var(--ref-color-grey-10);padding-bottom:var(--ref-spacing-xxs)}.ap-selection-dropdown__selected-section ::ng-deep ap-checkbox{--comp-forms-label-font-weight: 700}\n"] }]
392
- }], ctorParameters: () => [], propDecorators: { panel: [{ type: i0.ViewChild, args: [i0.forwardRef(() => DropdownPanelComponent), { isSignal: true }] }], trigger: [{ type: i0.ContentChild, args: ['trigger', { isSignal: true }] }], headerButtonId: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerButtonId", required: false }] }], footerButtonId: [{ type: i0.Input, args: [{ isSignal: true, alias: "footerButtonId", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], selectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionMode", required: false }] }], searchEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchEnabled", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], footerButtonText: [{ type: i0.Input, args: [{ isSignal: true, alias: "footerButtonText", required: false }] }], footerButtonSymbolId: [{ type: i0.Input, args: [{ isSignal: true, alias: "footerButtonSymbolId", required: false }] }], headerButtonText: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerButtonText", required: false }] }], headerButtonSymbolId: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerButtonSymbolId", required: false }] }], searchPlaceholderText: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholderText", required: false }] }], noSearchResultsText: [{ type: i0.Input, args: [{ isSignal: true, alias: "noSearchResultsText", required: false }] }], showBackdrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "showBackdrop", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], footerButtonClick: [{ type: i0.Output, args: ["footerButtonClick"] }], headerButtonClick: [{ type: i0.Output, args: ["headerButtonClick"] }], searchInputChange: [{ type: i0.Output, args: ["searchInputChange"] }], searchTerm: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchTerm", required: false }] }, { type: i0.Output, args: ["searchTermChange"] }], inputSearchComponent: [{ type: i0.ViewChild, args: ['inputSearchElement', { isSignal: true }] }] } });
535
+ ], template: "<ap-dropdown-panel\n [placement]=\"placement()\"\n [showBackdrop]=\"showBackdrop()\"\n (closed)=\"onPanelClosed()\">\n <!-- `dialog`, not a combobox: a combobox must close when focus leaves it, and this panel holds a\n search field, a header, a footer and group checkboxes beside its lists \u2014 closing on Tab left\n every one of them unreachable. -->\n <div\n *apDropdownContent\n class=\"ap-selection-dropdown__content\"\n role=\"dialog\"\n tabindex=\"-1\"\n [attr.aria-label]=\"panelLabel()\"\n (keydown)=\"onOptionsKeyDown($event)\"\n [class.ap-selection-dropdown__content--single]=\"isSingleSelect()\">\n <!-- Header -->\n @if (headerVisible()) {\n <div class=\"ap-selection-dropdown__header\">\n @if (headerTopVisible()) {\n <div class=\"ap-selection-dropdown__header-top\">\n @if (title()) {\n <h3 class=\"ap-selection-dropdown__title\">\n {{ title() }}\n </h3>\n }\n @if (headerButtonText()) {\n <button\n type=\"button\"\n class=\"ap-link standalone\"\n [id]=\"headerButtonId()\"\n (click)=\"onHeaderButtonClick()\">\n <ap-symbol [symbolId]=\"headerButtonSymbolId()\" />\n {{ headerButtonText() }}\n </button>\n }\n </div>\n }\n @if (searchVisible()) {\n <ap-input-search\n #inputSearchElement\n [placeholder]=\"searchPlaceholderText()\"\n [clearable]=\"true\"\n [ariaControls]=\"listboxId\"\n [ariaActiveDescendant]=\"activeDescendantId()\"\n [ngModel]=\"searchTerm()\"\n (blur)=\"onSearchBlur()\"\n (ngModelChange)=\"onSearchTermChange($event)\" />\n }\n </div>\n }\n\n <!-- Selection dropdown items -->\n <div\n class=\"ap-selection-dropdown__items\"\n [id]=\"listboxId\"\n [attr.role]=\"isSingleSelect() ? 'listbox' : null\"\n [attr.aria-label]=\"isSingleSelect() ? (title() ?? null) : null\">\n @if (filteredItems().length === 0 && searchTerm()) {\n <div class=\"ap-selection-dropdown__no-results\">\n {{ noSearchResultsText() }}\n </div>\n } @else if (isSingleSelect()) {\n @for (item of filteredItems(); track item.htmlId) {\n <button\n type=\"button\"\n role=\"option\"\n class=\"ap-selection-dropdown__option\"\n [id]=\"optionId(item)\"\n [apDropdownOption]=\"item.text\"\n [apDropdownOptionDisabled]=\"!!(item.disabled || item.isFeatureLocked)\"\n [tabindex]=\"optionTabIndex(activeIndex() === $index)\"\n [attr.aria-selected]=\"item.selected\"\n [attr.aria-disabled]=\"item.disabled || item.isFeatureLocked\"\n [attr.data-track]=\"item.dataTrack\"\n [apTooltip]=\"item.disabled ? (item.disabledTooltip ?? null) : null\"\n apTooltipPosition=\"right\"\n (click)=\"onItemToggle(item)\">\n <ap-dropdown-item-single-one-line\n [text]=\"item.text\"\n [selected]=\"item.selected\"\n [disabled]=\"item.disabled || false\"\n [avatarUrl]=\"item.avatarUrl\"\n [symbolId]=\"item.symbolId\"\n [badgeText]=\"item.badgeText\"\n [isFeatureLocked]=\"item.isFeatureLocked || false\"\n [roundedAvatar]=\"!!item.roundedAvatar\"\n [network]=\"item.network\"\n [standaloneModeEnabled]=\"true\" />\n </button>\n }\n } @else {\n <!-- A listbox owns only options, so each section is its own, and a group's checkbox sits beside it. -->\n @if (selectedItems().length > 0) {\n <div\n role=\"listbox\"\n aria-multiselectable=\"true\"\n class=\"ap-selection-dropdown__selected-section\"\n [attr.aria-label]=\"selectedSectionText()\">\n @for (item of selectedItems(); track item.htmlId) {\n @let grouped = false;\n <button\n type=\"button\"\n role=\"option\"\n class=\"ap-selection-dropdown__item-button\"\n [id]=\"optionId(item)\"\n [tabindex]=\"optionTabIndex(tabbableOption(item))\"\n [apDropdownOption]=\"item.text\"\n [apDropdownOptionDisabled]=\"!!(item.disabled || item.isFeatureLocked)\"\n [attr.aria-selected]=\"item.selected\"\n [class.ap-selection-dropdown__item-button--disabled]=\"item.disabled || item.isFeatureLocked\"\n [apTooltip]=\"item.disabledTooltip\"\n (click)=\"onItemToggle(item)\">\n <ap-dropdown-item-multiple-one-line\n presentational\n class=\"ap-selection-dropdown__item\"\n [class.ap-selection-dropdown__item--grouped]=\"grouped\"\n [text]=\"item.text\"\n [selected]=\"item.selected\"\n [indeterminate]=\"item.indeterminate ?? false\"\n [htmlId]=\"item.htmlId\"\n [disabled]=\"item.disabled || false\"\n [avatarUrl]=\"item.avatarUrl\"\n [symbolId]=\"item.symbolId\"\n [badgeText]=\"item.badgeText\"\n [isFeatureLocked]=\"item.isFeatureLocked || false\"\n [roundedAvatar]=\"!!item.roundedAvatar\"\n [network]=\"item.network\"\n [symbolColor]=\"item.symbolColor\"\n [symbolTooltipText]=\"item.symbolTooltipText\" />\n </button>\n }\n </div>\n }\n\n <!-- Unselected zone: items & groups in first-encounter order -->\n @for (run of displayRuns(); track runKey(run)) {\n @if (run.kind === 'items') {\n <div\n role=\"listbox\"\n aria-multiselectable=\"true\"\n [attr.aria-label]=\"title() ?? optionsSectionText()\">\n @for (item of run.items; track item.htmlId) {\n @let grouped = false;\n <button\n type=\"button\"\n role=\"option\"\n class=\"ap-selection-dropdown__item-button\"\n [id]=\"optionId(item)\"\n [tabindex]=\"optionTabIndex(tabbableOption(item))\"\n [apDropdownOption]=\"item.text\"\n [apDropdownOptionDisabled]=\"!!(item.disabled || item.isFeatureLocked)\"\n [attr.aria-selected]=\"item.selected\"\n [class.ap-selection-dropdown__item-button--disabled]=\"item.disabled || item.isFeatureLocked\"\n [apTooltip]=\"item.disabledTooltip\"\n (click)=\"onItemToggle(item)\">\n <ap-dropdown-item-multiple-one-line\n presentational\n class=\"ap-selection-dropdown__item\"\n [class.ap-selection-dropdown__item--grouped]=\"grouped\"\n [text]=\"item.text\"\n [selected]=\"item.selected\"\n [indeterminate]=\"item.indeterminate ?? false\"\n [htmlId]=\"item.htmlId\"\n [disabled]=\"item.disabled || false\"\n [avatarUrl]=\"item.avatarUrl\"\n [symbolId]=\"item.symbolId\"\n [badgeText]=\"item.badgeText\"\n [isFeatureLocked]=\"item.isFeatureLocked || false\"\n [roundedAvatar]=\"!!item.roundedAvatar\"\n [network]=\"item.network\"\n [symbolColor]=\"item.symbolColor\"\n [symbolTooltipText]=\"item.symbolTooltipText\" />\n </button>\n }\n </div>\n } @else {\n <div class=\"ap-selection-dropdown__group\">\n <!-- Group header with checkbox -->\n <div class=\"ap-selection-dropdown__group-header\">\n <div class=\"ap-selection-dropdown__group-label\">\n <ap-checkbox\n class=\"centered\"\n [name]=\"run.label\"\n [checked]=\"groupSelectionStates()[run.label] === 'selected'\"\n [indeterminate]=\"groupSelectionStates()[run.label] === 'partial'\"\n (change)=\"onGroupToggle(run.label, $event)\">\n {{ run.label }}\n </ap-checkbox>\n </div>\n </div>\n\n <div\n role=\"listbox\"\n aria-multiselectable=\"true\"\n [attr.aria-label]=\"run.label\">\n @for (item of run.items; track item.htmlId) {\n @let grouped = true;\n <button\n type=\"button\"\n role=\"option\"\n class=\"ap-selection-dropdown__item-button\"\n [id]=\"optionId(item)\"\n [tabindex]=\"optionTabIndex(tabbableOption(item))\"\n [apDropdownOption]=\"item.text\"\n [apDropdownOptionDisabled]=\"!!(item.disabled || item.isFeatureLocked)\"\n [attr.aria-selected]=\"item.selected\"\n [class.ap-selection-dropdown__item-button--disabled]=\"item.disabled || item.isFeatureLocked\"\n [apTooltip]=\"item.disabledTooltip\"\n (click)=\"onItemToggle(item)\">\n <ap-dropdown-item-multiple-one-line\n presentational\n class=\"ap-selection-dropdown__item\"\n [class.ap-selection-dropdown__item--grouped]=\"grouped\"\n [text]=\"item.text\"\n [selected]=\"item.selected\"\n [indeterminate]=\"item.indeterminate ?? false\"\n [htmlId]=\"item.htmlId\"\n [disabled]=\"item.disabled || false\"\n [avatarUrl]=\"item.avatarUrl\"\n [symbolId]=\"item.symbolId\"\n [badgeText]=\"item.badgeText\"\n [isFeatureLocked]=\"item.isFeatureLocked || false\"\n [roundedAvatar]=\"!!item.roundedAvatar\"\n [network]=\"item.network\"\n [symbolColor]=\"item.symbolColor\"\n [symbolTooltipText]=\"item.symbolTooltipText\" />\n </button>\n }\n </div>\n </div>\n }\n }\n }\n </div>\n\n <div\n class=\"ap-selection-dropdown__status\"\n role=\"status\"\n aria-atomic=\"true\">\n {{ resultsAnnouncement() }}\n </div>\n\n <!-- Footer -->\n @if (footerButtonText()) {\n <div class=\"ap-selection-dropdown__footer\">\n <button\n type=\"button\"\n class=\"ap-link standalone\"\n [id]=\"footerButtonId()\"\n (click)=\"onFooterButtonClick()\">\n <ap-symbol [symbolId]=\"footerButtonSymbolId()\" />\n {{ footerButtonText() }}\n </button>\n </div>\n }\n </div>\n</ap-dropdown-panel>\n", styles: [":host{display:none}.ap-selection-dropdown__content{border-radius:inherit;overflow:hidden;z-index:1000;width:370px;display:flex;flex-direction:column;max-height:min(400px,var(--ap-floating-available-height, 100vh))}.ap-selection-dropdown__content--single{width:auto;min-width:160px}.ap-selection-dropdown__option{display:block;width:100%;padding:0;border:none;background:none;font:inherit;text-align:inherit}.ap-selection-dropdown__item-button{display:block;width:100%;padding:0;margin:0;border:none;background:transparent;text-align:left;cursor:pointer;outline:none}.ap-selection-dropdown__item-button:hover,.ap-selection-dropdown__item-button.ap-dropdown-option--active{background-color:var(--ref-color-electric-blue-10)}.ap-selection-dropdown__item-button:active{background-color:var(--ref-color-electric-blue-20)}.ap-selection-dropdown__item-button:focus{outline:none}.ap-selection-dropdown__item-button:focus-visible{outline:none}.ap-selection-dropdown__item-button.ap-selection-dropdown__item-button--disabled{pointer-events:none}.ap-selection-dropdown__item{display:flex;align-items:center;width:100%;min-height:40px;padding:var(--ref-spacing-xxs) var(--ref-spacing-sm);background:transparent;cursor:pointer;font-family:Averta}.ap-selection-dropdown__group-header{display:flex;align-items:center;padding:var(--ref-spacing-xxs) var(--ref-spacing-sm);border-top:1px solid var(--ref-color-grey-10);background:var(--ref-color-grey-bg)}.ap-selection-dropdown__group-label{display:flex;align-items:center;flex:1;font-weight:700;color:var(--ref-color-grey-100)}.ap-selection-dropdown__group-label ap-checkbox{--comp-forms-label-font-weight: 700}.ap-selection-dropdown__header{border-bottom:1px solid var(--ref-color-grey-10);flex-shrink:0;display:flex;flex-direction:column}.ap-selection-dropdown__header .ap-selection-dropdown__header-top{display:flex;align-items:center;justify-content:space-between;padding:var(--ref-spacing-xs) var(--ref-spacing-sm)}.ap-selection-dropdown__header .ap-selection-dropdown__title{margin:0;font-size:var(--ref-font-size-md);font-weight:var(--ref-font-weight-bold);color:var(--ref-color-grey-100);flex:1}.ap-selection-dropdown__header ap-input-search{width:100%;padding:0 var(--ref-spacing-xxs) var(--ref-spacing-xxs)}.ap-selection-dropdown__items{padding:var(--ref-spacing-xxs) 0;flex:1;overflow-y:auto;min-height:0}.ap-selection-dropdown__no-results{padding:var(--ref-spacing-xxs) var(--ref-spacing-sm);color:var(--ref-color-grey-80);font-size:var(--ref-font-size-sm);font-style:italic}.ap-selection-dropdown__footer{height:40px;padding:var(--ref-spacing-xs) var(--ref-spacing-sm);border-top:1px solid var(--ref-color-grey-10);flex-shrink:0;display:flex;align-items:center;justify-content:flex-start}.ap-selection-dropdown__selected-section{margin-bottom:var(--ref-spacing-xxs);border-bottom:1px solid var(--ref-color-grey-10);padding-bottom:var(--ref-spacing-xxs)}.ap-selection-dropdown__selected-section ::ng-deep ap-checkbox{--comp-forms-label-font-weight: 700}.ap-selection-dropdown__status{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}\n"] }]
536
+ }], ctorParameters: () => [], propDecorators: { panel: [{ type: i0.ViewChild, args: [i0.forwardRef(() => DropdownPanelComponent), { isSignal: true }] }], options: [{ type: i0.ViewChildren, args: [i0.forwardRef(() => DropdownOptionDirective), { isSignal: true }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], selectedSectionText: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedSectionText", required: false }] }], optionsSectionText: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionsSectionText", required: false }] }], trigger: [{ type: i0.ContentChild, args: ['trigger', { isSignal: true }] }], headerButtonId: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerButtonId", required: false }] }], footerButtonId: [{ type: i0.Input, args: [{ isSignal: true, alias: "footerButtonId", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], selectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionMode", required: false }] }], searchEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchEnabled", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], footerButtonText: [{ type: i0.Input, args: [{ isSignal: true, alias: "footerButtonText", required: false }] }], footerButtonSymbolId: [{ type: i0.Input, args: [{ isSignal: true, alias: "footerButtonSymbolId", required: false }] }], headerButtonText: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerButtonText", required: false }] }], headerButtonSymbolId: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerButtonSymbolId", required: false }] }], searchPlaceholderText: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholderText", required: false }] }], noSearchResultsText: [{ type: i0.Input, args: [{ isSignal: true, alias: "noSearchResultsText", required: false }] }], searchResultsText: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchResultsText", required: false }] }], showBackdrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "showBackdrop", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], footerButtonClick: [{ type: i0.Output, args: ["footerButtonClick"] }], headerButtonClick: [{ type: i0.Output, args: ["headerButtonClick"] }], searchInputChange: [{ type: i0.Output, args: ["searchInputChange"] }], searchTerm: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchTerm", required: false }] }, { type: i0.Output, args: ["searchTermChange"] }], inputSearchComponent: [{ type: i0.ViewChild, args: ['inputSearchElement', { isSignal: true }] }] } });
393
537
 
394
538
  /**
395
539
  * Generated bundle index. Do not edit.