@agorapulse/ui-components 22.0.29 → 22.0.30

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.
@@ -19,6 +19,7 @@ import { apMore, apFeatureLock as apFeatureLock$1, apPlus } from '@agorapulse/ui
19
19
  import { CheckboxComponent } from '@agorapulse/ui-components/checkbox';
20
20
  import { CounterComponent } from '@agorapulse/ui-components/counter';
21
21
  import { ActionDropdownComponent, ActionDropdownTriggerDirective } from '@agorapulse/ui-components/action-dropdown';
22
+ import { FilterDropdownButtonComponent } from '@agorapulse/ui-components/filter-dropdown';
22
23
 
23
24
  class NavSelectorPopoverItemComponent {
24
25
  selected = input(false, /* @ts-ignore */
@@ -200,6 +201,92 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
200
201
  }]
201
202
  }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }], propDecorators: { apNavSelectorPopoverTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "apNavSelectorPopoverTrigger", required: true }] }], apNavSelectorPopoverTriggerMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "apNavSelectorPopoverTriggerMode", required: false }] }], apNavSelectorPopoverDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "apNavSelectorPopoverDisabled", required: false }] }] } });
202
203
 
204
+ /**
205
+ * Create a Record of key/value pairs from an array of objects
206
+ * @param array
207
+ * @param key attribute of the object to use as key
208
+ */
209
+ const associateBy = (array, key) => array.reduce((previousValue, currentValue) => {
210
+ previousValue[`${currentValue[key]}`] = currentValue;
211
+ return previousValue;
212
+ }, {});
213
+ const isInternalNavSelectorEntryALeafFocusable = (leaf, { parentFolded, multipleMode }) => {
214
+ if (parentFolded) {
215
+ return false;
216
+ }
217
+ if (multipleMode) {
218
+ return !leaf.disabled && !leaf.displayTokenInvalid && !leaf.displayFeatureLocked;
219
+ }
220
+ return !leaf.disabled;
221
+ };
222
+ const computeFolded = (entry, children) => {
223
+ // If the entry is not folded, we keep it unfolded
224
+ if (!entry.folded) {
225
+ return false;
226
+ }
227
+ return !children.some(child => (isInternalNavSelectorEntryALeaf(child) && (child.selected || !child.folded)) ||
228
+ (isInternalNavSelectorEntryANode(child) && !child.folded) ||
229
+ (isInternalNavSelectorEntryAGroup(child) && child.undeterminedSelection));
230
+ };
231
+ const computeNumberOfDisplayableChildrenOnUnfold = (entry) => {
232
+ if (isInternalNavSelectorEntryANode(entry)) {
233
+ const nbChildren = entry.children.length;
234
+ const nbDisplayableChildrenOfUnfoldedChild = entry.children
235
+ .filter(child => !child.folded)
236
+ .reduce((acc, child) => {
237
+ return acc + computeNumberOfDisplayableChildrenOnUnfold(child);
238
+ }, 0);
239
+ return nbDisplayableChildrenOfUnfoldedChild + nbChildren;
240
+ }
241
+ if (isInternalNavSelectorEntryALeaf(entry)) {
242
+ return entry.details.length;
243
+ }
244
+ return 0;
245
+ };
246
+ const computeSelectableUids = (entries) => {
247
+ return entries.flatMap(entry => computeSelectableUidsByEntry(entry));
248
+ };
249
+ const computeSelectableUidsByEntry = (entry) => {
250
+ if (isInternalNavSelectorEntryALeaf(entry)) {
251
+ // Disabled leafs can now be selected programmatically
252
+ return [entry.uid, ...entry.details.filter(detail => !detail.hidden).map(detail => detail.uid)];
253
+ }
254
+ if (isInternalNavSelectorEntryANode(entry)) {
255
+ return [entry.uid, ...entry.children.flatMap(child => computeSelectableUidsByEntry(child))];
256
+ }
257
+ return [];
258
+ };
259
+ const computeVisibleUids = (entries) => {
260
+ return entries.flatMap(entry => computeVisibleUidsByEntry(entry));
261
+ };
262
+ const computeVisibleUidsByEntry = (entry) => {
263
+ if (entry.hidden) {
264
+ return [];
265
+ }
266
+ if (isInternalNavSelectorEntryALeaf(entry)) {
267
+ return [entry.uid, ...entry.details.filter(detail => !detail.hidden).map(detail => detail.uid)];
268
+ }
269
+ if (isInternalNavSelectorEntryANode(entry)) {
270
+ return entry.children.flatMap(child => computeVisibleUidsByEntry(child));
271
+ }
272
+ // Fallback for unexpected entry types (should never be reached)
273
+ return [];
274
+ };
275
+ const getLeaves = (entries) => {
276
+ return entries.flatMap(entry => {
277
+ if (isInternalNavSelectorEntryALeaf(entry)) {
278
+ return [entry];
279
+ }
280
+ if (isInternalNavSelectorEntryAGroup(entry)) {
281
+ return entry.children;
282
+ }
283
+ if (isInternalNavSelectorEntryACategory(entry)) {
284
+ return getLeaves(entry.children);
285
+ }
286
+ return [];
287
+ });
288
+ };
289
+
203
290
  /**
204
291
  * NavSelectorAccessibility is a utility class that provides methods to manage the accessibility and the focusability of nav selector entries.
205
292
  */
@@ -332,13 +419,18 @@ class NavSelectorAccessibility {
332
419
  */
333
420
  static flatten(entries) {
334
421
  return entries.flatMap(entry => {
422
+ // The accessibility object is cloned as well: the focus helpers below assign tabIndex in place, and
423
+ // sharing it with the source entries would retroactively change every previously returned tree.
335
424
  if (isInternalNavSelectorEntryAGroup(entry) || isInternalNavSelectorEntryACategory(entry)) {
336
- return [{ ...entry, children: [] }, ...this.flatten(entry.children)];
425
+ return [{ ...entry, accessibility: { ...entry.accessibility }, children: [] }, ...this.flatten(entry.children)];
337
426
  }
338
427
  if (isInternalNavSelectorEntryALeaf(entry)) {
339
- return [{ ...entry, details: [] }, ...entry.details.map(detail => ({ ...detail }))];
428
+ return [
429
+ { ...entry, accessibility: { ...entry.accessibility }, details: [] },
430
+ ...entry.details.map(detail => ({ ...detail, accessibility: { ...detail.accessibility } })),
431
+ ];
340
432
  }
341
- return [{ ...entry }];
433
+ return [{ ...entry, accessibility: { ...entry.accessibility } }];
342
434
  });
343
435
  }
344
436
  /**
@@ -378,78 +470,6 @@ class NavSelectorAccessibility {
378
470
  }
379
471
  }
380
472
 
381
- /**
382
- * Create a Record of key/value pairs from an array of objects
383
- * @param array
384
- * @param key attribute of the object to use as key
385
- */
386
- const associateBy = (array, key) => array.reduce((previousValue, currentValue) => {
387
- previousValue[`${currentValue[key]}`] = currentValue;
388
- return previousValue;
389
- }, {});
390
- const isInternalNavSelectorEntryALeafFocusable = (leaf, { parentFolded, multipleMode }) => {
391
- if (parentFolded) {
392
- return false;
393
- }
394
- if (multipleMode) {
395
- return !leaf.disabled && !leaf.displayTokenInvalid && !leaf.displayFeatureLocked;
396
- }
397
- return !leaf.disabled;
398
- };
399
- const computeFolded = (entry, children) => {
400
- // If the entry is not folded, we keep it unfolded
401
- if (!entry.folded) {
402
- return false;
403
- }
404
- return !children.some(child => (isInternalNavSelectorEntryALeaf(child) && (child.selected || !child.folded)) ||
405
- (isInternalNavSelectorEntryANode(child) && !child.folded) ||
406
- (isInternalNavSelectorEntryAGroup(child) && child.undeterminedSelection));
407
- };
408
- const computeNumberOfDisplayableChildrenOnUnfold = (entry) => {
409
- if (isInternalNavSelectorEntryANode(entry)) {
410
- const nbChildren = entry.children.length;
411
- const nbDisplayableChildrenOfUnfoldedChild = entry.children
412
- .filter(child => !child.folded)
413
- .reduce((acc, child) => {
414
- return acc + computeNumberOfDisplayableChildrenOnUnfold(child);
415
- }, 0);
416
- return nbDisplayableChildrenOfUnfoldedChild + nbChildren;
417
- }
418
- if (isInternalNavSelectorEntryALeaf(entry)) {
419
- return entry.details.length;
420
- }
421
- return 0;
422
- };
423
- const computeSelectableUids = (entries) => {
424
- return entries.flatMap(entry => computeSelectableUidsByEntry(entry));
425
- };
426
- const computeSelectableUidsByEntry = (entry) => {
427
- if (isInternalNavSelectorEntryALeaf(entry)) {
428
- // Disabled leafs can now be selected programmatically
429
- return [entry.uid, ...entry.details.filter(detail => !detail.hidden).map(detail => detail.uid)];
430
- }
431
- if (isInternalNavSelectorEntryANode(entry)) {
432
- return [entry.uid, ...entry.children.flatMap(child => computeSelectableUidsByEntry(child))];
433
- }
434
- return [];
435
- };
436
- const computeVisibleUids = (entries) => {
437
- return entries.flatMap(entry => computeVisibleUidsByEntry(entry));
438
- };
439
- const computeVisibleUidsByEntry = (entry) => {
440
- if (entry.hidden) {
441
- return [];
442
- }
443
- if (isInternalNavSelectorEntryALeaf(entry)) {
444
- return [entry.uid, ...entry.details.filter(detail => !detail.hidden).map(detail => detail.uid)];
445
- }
446
- if (isInternalNavSelectorEntryANode(entry)) {
447
- return entry.children.flatMap(child => computeVisibleUidsByEntry(child));
448
- }
449
- // Fallback for unexpected entry types (should never be reached)
450
- return [];
451
- };
452
-
453
473
  /**
454
474
  * Class to handle the folding and unfolding of nav selector entries.
455
475
  */
@@ -1124,6 +1144,7 @@ class NavSelectorBuilder {
1124
1144
  detailsDisplayable,
1125
1145
  details: leaf.details.map(detail => this.buildLeafDetail(detail, level + 1, focusable && !folded)),
1126
1146
  detailSelected: false,
1147
+ tags: leaf.tags,
1127
1148
  type: 'LEAF',
1128
1149
  viewMoreDisplayable,
1129
1150
  viewMoreDisplayed: viewMoreDisplayable,
@@ -1196,40 +1217,56 @@ class NavSelectorBuilder {
1196
1217
  */
1197
1218
  class NavSelectorFilter {
1198
1219
  /**
1199
- * Filters the entries based on the search string
1220
+ * Filters the entries based on the search string and the filtered tags.
1200
1221
  *
1201
1222
  * The search string is normalized and lowercase and trimmed.
1202
1223
  *
1203
- * If a category matches the search string, all its children are unfolded, marked as focusable, and not hidden.
1204
- *
1205
- * If a group matches the search string, the group is unfolded and all its children are unfolded, marked as focusable, and not hidden.
1206
- *
1207
- * If a leaf matches the search string, it is marked as not hidden and focusable.
1224
+ * The search picks a scope, the tags filter inside it: when a category or a group matches the search string, every
1225
+ * entry it holds inherits that match, and only the tags keep filtering underneath. A leaf is therefore displayed
1226
+ * when the search is satisfied, by its own alias or by one of its parents, and when it carries one of the filtered
1227
+ * tags. Categories and groups carry no tag of their own, so they are displayed for the leaves they still hold and
1228
+ * hidden once all of them are.
1208
1229
  *
1209
- * Else the entry marked as hidden and not focusable.
1230
+ * Displayed nodes are unfolded and marked as focusable, hidden entries are marked as not focusable.
1210
1231
  *
1211
1232
  * It also determines whenever counter and token invalid should be displayed on groups and leaves.
1212
1233
  *
1213
1234
  * @param entries The entries to filter.
1214
- * @param search The search string.
1235
+ * @param criteria all criteria to apply.
1215
1236
  * @param multipleMode to update the focusable state of leaves correctly.
1216
1237
  * @returns The filtered entries.
1217
1238
  */
1218
- static filter(entries, search, multipleMode) {
1219
- const formattedSearch = this.cleanValue(search);
1220
- if (!formattedSearch) {
1239
+ static filter(entries, criteria, multipleMode) {
1240
+ const formattedSearch = this.cleanValue(criteria.search);
1241
+ const shouldFilterByTags = Object.values(criteria.tags).some(tags => tags.length > 0);
1242
+ if (!formattedSearch && !shouldFilterByTags) {
1221
1243
  return this.resetState(entries);
1222
1244
  }
1223
- return this.filterEntries(entries, formattedSearch, multipleMode);
1245
+ const tags = Object.entries(criteria.tags).reduce((acc, [key, values]) => {
1246
+ // A tag name selected with no value filters nothing, keeping it would hide every leaf.
1247
+ if (!values.length) {
1248
+ return acc;
1249
+ }
1250
+ const castKey = key;
1251
+ const tagValues = (acc[castKey] ??= {});
1252
+ values.forEach(value => (tagValues[value] = true));
1253
+ return acc;
1254
+ }, {});
1255
+ return this.filterEntries(entries, { search: formattedSearch, tags }, multipleMode);
1224
1256
  }
1225
- static filterEntries(entries, formattedSearch, multipleMode) {
1257
+ static filterEntries(entries, formattedCriteria, multipleMode, searchSatisfiedByAncestor = false) {
1226
1258
  const newEntries = entries.map(entry => {
1227
- if (this.matches(entry.alias, formattedSearch)) {
1228
- return this.recursivelyUnfoldEntry(entry, multipleMode);
1229
- }
1259
+ // Matching the search opens a scope: descendants inherit the match and only the tags filter underneath.
1260
+ const searchSatisfied = searchSatisfiedByAncestor || this.searchSatisfiedBy(entry, formattedCriteria);
1230
1261
  if (isInternalNavSelectorEntryANode(entry)) {
1231
- const children = this.filterEntries(entry.children, formattedSearch, multipleMode);
1232
- if (children.every(({ hidden }) => hidden)) {
1262
+ // A node carries no tag of its own, so it is kept for the entries it still holds. An empty node has
1263
+ // none to speak for it: it is kept when it satisfies the search itself, and dropped as soon as tags
1264
+ // are filtered, having none.
1265
+ const children = this.filterEntries(entry.children, formattedCriteria, multipleMode, searchSatisfied);
1266
+ const displayable = children.length
1267
+ ? children.some(({ hidden }) => !hidden)
1268
+ : searchSatisfied && !this.tagsFiltered(formattedCriteria);
1269
+ if (!displayable) {
1233
1270
  return {
1234
1271
  ...entry,
1235
1272
  children,
@@ -1248,6 +1285,9 @@ class NavSelectorFilter {
1248
1285
  };
1249
1286
  }
1250
1287
  if (isInternalNavSelectorEntryALeaf(entry)) {
1288
+ if (searchSatisfied && this.tagsSatisfiedBy(entry, formattedCriteria)) {
1289
+ return this.displayLeaf(entry, multipleMode);
1290
+ }
1251
1291
  return {
1252
1292
  ...entry,
1253
1293
  focusable: false,
@@ -1258,54 +1298,51 @@ class NavSelectorFilter {
1258
1298
  })),
1259
1299
  };
1260
1300
  }
1261
- return {
1262
- ...entry,
1263
- focusable: false,
1264
- hidden: true,
1265
- };
1301
+ return searchSatisfied
1302
+ ? entry
1303
+ : {
1304
+ ...entry,
1305
+ focusable: false,
1306
+ hidden: true,
1307
+ };
1266
1308
  });
1267
1309
  return NavSelectorAccessibility.resetFocus(newEntries);
1268
1310
  }
1269
- static recursivelyUnfoldEntry(entry, multipleMode) {
1270
- if (isInternalNavSelectorEntryAGroup(entry)) {
1271
- const children = entry.children.map(child => this.recursivelyUnfoldEntry(child, multipleMode));
1272
- return {
1273
- ...entry,
1274
- hidden: false,
1275
- folded: false,
1276
- focusable: true,
1277
- children,
1278
- displayCounter: false,
1279
- displayTokenInvalid: false,
1280
- };
1281
- }
1282
- else if (isInternalNavSelectorEntryALeaf(entry)) {
1283
- const leafFocusable = isInternalNavSelectorEntryALeafFocusable(entry, { parentFolded: false, multipleMode });
1284
- return {
1285
- ...entry,
1286
- hidden: false,
1287
- focusable: leafFocusable,
1288
- displayCounter: entry.folded && entry.counterDisplayable,
1289
- details: entry.details.map(detail => ({
1290
- ...detail,
1291
- focusable: !entry.folded,
1292
- })),
1293
- };
1294
- }
1295
- else if (isInternalNavSelectorEntryACategory(entry)) {
1296
- const children = entry.children.map(child => this.recursivelyUnfoldEntry(child, multipleMode));
1297
- return {
1298
- ...entry,
1299
- focusable: true,
1300
- folded: false,
1301
- hidden: false,
1302
- children,
1303
- };
1311
+ /**
1312
+ * Displays a leaf that satisfies every criterion, its details following the leaf own folded state.
1313
+ */
1314
+ static displayLeaf(leaf, multipleMode) {
1315
+ return {
1316
+ ...leaf,
1317
+ hidden: false,
1318
+ focusable: isInternalNavSelectorEntryALeafFocusable(leaf, { parentFolded: false, multipleMode }),
1319
+ displayCounter: leaf.folded && leaf.counterDisplayable,
1320
+ details: leaf.details.map(detail => ({
1321
+ ...detail,
1322
+ focusable: !leaf.folded,
1323
+ })),
1324
+ };
1325
+ }
1326
+ /**
1327
+ * Whether the entry satisfies the search by its own alias. An inactive search is satisfied by every entry.
1328
+ */
1329
+ static searchSatisfiedBy(entry, formattedCriteria) {
1330
+ return !formattedCriteria.search || this.cleanValue(entry.alias).includes(formattedCriteria.search);
1331
+ }
1332
+ /**
1333
+ * Whether the leaf carries at least one of the filtered tag values. Inactive tag criteria are satisfied by every leaf.
1334
+ */
1335
+ static tagsSatisfiedBy(leaf, formattedCriteria) {
1336
+ if (!this.tagsFiltered(formattedCriteria)) {
1337
+ return true;
1304
1338
  }
1305
- return entry;
1339
+ return Object.entries(leaf.tags).some(([key, tags]) => tags.some(tag => (formattedCriteria.tags[key] ?? {})[tag]));
1306
1340
  }
1307
- static matches(alias, formattedSearch) {
1308
- return this.cleanValue(alias).includes(formattedSearch);
1341
+ /**
1342
+ * Whether at least one tag value is being filtered on.
1343
+ */
1344
+ static tagsFiltered(formattedCriteria) {
1345
+ return Object.keys(formattedCriteria.tags).length > 0;
1309
1346
  }
1310
1347
  static cleanValue(value) {
1311
1348
  return value.trim().normalize('NFKC').toLowerCase();
@@ -1814,8 +1851,18 @@ class NavSelectorState {
1814
1851
  noResults: '',
1815
1852
  viewMore: '',
1816
1853
  viewLess: '',
1854
+ filter: '',
1855
+ clearFilters: '',
1856
+ applyFilters: '',
1857
+ tagNames: { attributes: '' },
1817
1858
  }, /* @ts-ignore */
1818
1859
  ...(ngDevMode ? [{ debugName: "_texts" }] : /* istanbul ignore next */ []));
1860
+ tagsFilterDisplayed = computed(() => {
1861
+ return getLeaves(this.entries()).some(leaf => Object.values(leaf.tags).some(tag => Object.values(tag).length > 0));
1862
+ }, /* @ts-ignore */
1863
+ ...(ngDevMode ? [{ debugName: "tagsFilterDisplayed" }] : /* istanbul ignore next */ []));
1864
+ tagsFilters = signal({}, /* @ts-ignore */
1865
+ ...(ngDevMode ? [{ debugName: "tagsFilters" }] : /* istanbul ignore next */ []));
1819
1866
  isMultipleModeEnabled = this.multipleModeEnabled;
1820
1867
  search = signal('', /* @ts-ignore */
1821
1868
  ...(ngDevMode ? [{ debugName: "search" }] : /* istanbul ignore next */ []));
@@ -1861,9 +1908,9 @@ class NavSelectorState {
1861
1908
  });
1862
1909
  });
1863
1910
  effect(() => {
1864
- const search = this.search();
1911
+ const criteria = { search: this.search(), tags: this.tagsFilters() };
1865
1912
  untracked(() => {
1866
- this._entries.update(entries => NavSelectorFilter.filter(entries, search, this.multipleModeEnabled()));
1913
+ this._entries.update(entries => NavSelectorFilter.filter(entries, criteria, this.multipleModeEnabled()));
1867
1914
  });
1868
1915
  });
1869
1916
  }
@@ -1890,7 +1937,7 @@ class NavSelectorState {
1890
1937
  const previouslySelectedUids = this.collectSelectedUids(oldEntries);
1891
1938
  const mergeEntries = NavSelectorMerger.mergeInternalNavSelectorEntries(newEntries, oldEntries);
1892
1939
  const unfoldedEntries = this.unfoldParentsOfNewlySelectedEntries(mergeEntries, previouslySelectedUids);
1893
- return NavSelectorFilter.filter(unfoldedEntries, this.search(), this.multipleModeEnabled());
1940
+ return NavSelectorFilter.filter(unfoldedEntries, { search: this.search(), tags: this.tagsFilters() }, this.multipleModeEnabled());
1894
1941
  });
1895
1942
  }
1896
1943
  /**
@@ -2054,6 +2101,12 @@ class NavSelectorState {
2054
2101
  minified: !this.expanded(),
2055
2102
  };
2056
2103
  }
2104
+ filterTags(tags) {
2105
+ this.tagsFilters.set(tags);
2106
+ }
2107
+ clearFilterTags() {
2108
+ this.tagsFilters.set({});
2109
+ }
2057
2110
  fold(entry) {
2058
2111
  this._entries.update(entries => NavSelectorFolding.fold(entries, entry.uid, this.getFoldingOptions()));
2059
2112
  }
@@ -3071,6 +3124,90 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
3071
3124
  ], template: "<!-- eslint-disable @angular-eslint/template/interactive-supports-focus -->\n@if (navSelectorCategoryPresenter.expanded()) {\n <div\n class=\"content\"\n apTooltipPosition=\"right\"\n [attr.data-test]=\"dataTestId()\"\n [apTooltip]=\"tooltipContent()\"\n [apTooltipDisabled]=\"tooltipDisabled()\"\n [apTreeNodeAccessibility]=\"category()\"\n (keydown.space)=\"navSelectorCategoryPresenter.toggleFolding($event, category())\"\n (keydown.enter)=\"navSelectorCategoryPresenter.toggleFolding($event, category())\"\n (click)=\"navSelectorCategoryPresenter.toggleFolding($event, category())\">\n @if (category().avatarDisplayed) {\n @if (category().avatarPictureUrlDisplayed) {\n <ap-avatar\n size=\"16\"\n [showInitials]=\"true\"\n [username]=\"category().alias\"\n [profilePicture]=\"category().avatarPictureUrl\"\n [rounded]=\"category().avatarRounded\" />\n } @else {\n <ap-symbol\n size=\"sm\"\n color=\"grey-blue\"\n [symbolId]=\"category().avatarSymbolId\" />\n }\n }\n\n <span\n #alias\n class=\"caption\">\n {{ category().alias }}\n </span>\n\n <ap-symbol\n class=\"folding-button\"\n size=\"sm\"\n [symbolId]=\"foldSymbol()\" />\n </div>\n\n <div\n class=\"children-container\"\n [@accordion]=\"{\n value: animationState(),\n params: {\n maxHeight: maxHeight(),\n },\n }\">\n @if (!foldedWithDelay()) {\n <div class=\"children\">\n @if (category().children.length === 0) {\n <div class=\"empty-state\">\n @if (category().emptyStateTitle) {\n <div class=\"empty-state__title\">\n {{ category().emptyStateTitle }}\n </div>\n }\n @if (category().emptyStateAction; as emptyStateAction) {\n <a\n class=\"standalone\"\n [attr.id]=\"emptyStateAction?.id\"\n (click)=\"onEmptyStateActionClick(emptyStateAction.name)\">\n @if (emptyStateAction?.symbolId; as symbolId) {\n <ap-symbol\n size=\"sm\"\n [symbolId]=\"symbolId\" />\n }\n {{ emptyStateAction.title }}\n @if (emptyStateAction?.featureLocked) {\n <ap-symbol\n size=\"sm\"\n color=\"purple\"\n symbolId=\"feature-lock\" />\n }\n </a>\n }\n </div>\n } @else {\n @for (child of category().children; track child.uid) {\n @if (!child.hidden) {\n <div\n class=\"entry\"\n [class.folder]=\"child.type === 'GROUP'\">\n @if (child.type === 'LEAF') {\n <ap-nav-selector-leaf\n [leaf]=\"child\"\n (actionClicked)=\"actionClicked.emit($event)\" />\n } @else if (child.type === 'GROUP') {\n <ap-nav-selector-group\n [group]=\"child\"\n (actionClicked)=\"actionClicked.emit($event)\" />\n }\n </div>\n }\n }\n }\n </div>\n }\n </div>\n} @else {\n <div\n class=\"content\"\n apTooltipPosition=\"right\"\n [apTreeNodeAccessibility]=\"category()\"\n [apTooltip]=\"tooltipContent()\"\n [apTooltipDisabled]=\"tooltipDisabled()\"\n (click)=\"navSelectorCategoryPresenter.toggleFolding($event, category())\"\n (keydown.space)=\"navSelectorCategoryPresenter.toggleFolding($event, category())\"\n (keydown.enter)=\"navSelectorCategoryPresenter.toggleFolding($event, category())\">\n <div class=\"name-container\">\n <span class=\"caption\">{{ category().alias }}</span>\n </div>\n\n <div class=\"toggle\">\n <ap-symbol\n size=\"sm\"\n [symbolId]=\"foldSymbol()\" />\n </div>\n </div>\n\n <div\n class=\"children-container\"\n [@accordion]=\"{\n value: animationState(),\n params: {\n maxHeight: maxHeight(),\n },\n }\">\n @if (!foldedWithDelay()) {\n <div class=\"children\">\n @for (child of category().children; track child.uid) {\n @if (!child.hidden) {\n <div\n class=\"entry\"\n [class.folder]=\"child.type === 'GROUP'\">\n @if (child.type === 'LEAF') {\n <ap-nav-selector-leaf\n [leaf]=\"child\"\n (actionClicked)=\"actionClicked.emit($event)\" />\n } @else if (child.type === 'GROUP') {\n <ap-nav-selector-group\n [group]=\"child\"\n (actionClicked)=\"actionClicked.emit($event)\" />\n }\n </div>\n }\n }\n </div>\n }\n </div>\n}\n", styles: [":host{display:flex;align-items:center;flex-shrink:0;align-self:stretch;flex-direction:column}:host .children-container{align-self:stretch}:host .children-container .empty-state{display:flex;padding:0 var(--ref-spacing-xxs) var(--ref-spacing-xxs) var(--ref-spacing-xxs);flex-direction:column;align-items:flex-start;gap:var(--ref-spacing-xxs)}:host .children-container .empty-state__title{font-size:var(--ref-font-size-xs);font-weight:var(--ref-font-weight-regular);font-style:italic;color:var(--ref-color-grey-80)}:host .folding-button{display:flex;width:16px;height:16px;justify-content:center;align-items:center;flex-shrink:0}:host .content{padding:0 var(--ref-spacing-xxs);display:flex;height:36px;align-items:center;gap:var(--ref-spacing-xxs);flex-shrink:0;flex-grow:1;align-self:stretch;cursor:pointer}:host .content:hover{border-radius:var(--ref-border-radius-sm);background:var(--ref-color-electric-blue-10)}:host .content:active{border-radius:var(--ref-border-radius-sm);background:var(--ref-color-electric-blue-20)}:host .content:focus-visible{outline:none;border-radius:var(--ref-border-radius-sm);background:var(--ref-color-electric-blue-10);box-shadow:0 0 0 1px var(--ref-color-white),0 0 0 3px var(--ref-color-electric-blue-100)}:host ap-symbol[symbol-id=chevron-down],:host ap-symbol[symbol-id=chevron-up]{color:var(--ref-color-grey-80)}:host .caption{-webkit-box-orient:vertical;-webkit-line-clamp:1;flex:1 0 0;overflow:hidden;white-space:nowrap;color:var(--ref-color-grey-100);text-overflow:ellipsis;font-family:Averta;font-size:var(--sys-text-style-h4-size);font-style:normal;font-weight:var(--ref-font-weight-bold);line-height:var(--ref-font-line-height-md)}:host .children{display:flex;flex-direction:column;align-items:flex-start;flex:1 0 0;align-self:stretch}:host .children .entry{display:flex;flex-direction:column;align-items:flex-start;flex:1 0 0;align-self:stretch;margin-left:calc(-1 * var(--ref-spacing-xxs));margin-right:calc(-1 * var(--ref-spacing-xxs))}:host .children .entry.folder{padding:var(--ref-spacing-xxs);border-bottom:1px solid var(--sys-border-color-default)}:host .children .entry.folder+.entry:not(.folder){padding-top:var(--ref-spacing-xxs)}:host .children .entry.folder:first-child{padding-top:0}:host .children .entry.folder:last-child{border-bottom:none;padding-bottom:0}:host .children .entry:not(.folder){padding-left:var(--ref-spacing-xxs);padding-right:var(--ref-spacing-xxs)}:host .children .entry:not(.folder):first-child:not(:last-child){padding-top:var(--ref-spacing-xxs)}:host .children .entry:not(.folder):last-child:not(:first-child){padding-bottom:var(--ref-spacing-xxs);border-bottom:none}:host .children .entry:not(.folder):has(+.entry.folder){padding-bottom:var(--ref-spacing-xxs)}:host .children .entry:not(.folder)+.entry.folder{border-top:1px solid var(--sys-border-color-default)}:host.minified .name-container{overflow:hidden;display:flex}:host.minified .name-container span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden;display:inline-block}:host.minified .caption{white-space:nowrap}:host.minified .content{position:relative}:host.minified .content .toggle{position:absolute;display:none}:host.minified .content:hover .toggle,:host.minified .content:focus-visible .toggle{inset:0;display:flex;justify-content:center;align-items:center}:host.minified .content:hover .name-container,:host.minified .content:focus-visible .name-container{display:none}\n"] }]
3072
3125
  }], ctorParameters: () => [{ type: i0.ElementRef }, { type: NavSelectorCategoryPresenter }], propDecorators: { category: [{ type: i0.Input, args: [{ isSignal: true, alias: "category", required: true }] }], emptyStateActionClicked: [{ type: i0.Output, args: ["emptyStateActionClicked"] }], actionClicked: [{ type: i0.Output, args: ["actionClicked"] }], aliasEl: [{ type: i0.ViewChild, args: ['alias', { isSignal: true }] }] } });
3073
3126
 
3127
+ class NavSelectorTagsFilterComponent {
3128
+ state = inject(NavSelectorState);
3129
+ filterButtonText = computed(() => this.state.texts().filter, /* @ts-ignore */
3130
+ ...(ngDevMode ? [{ debugName: "filterButtonText" }] : /* istanbul ignore next */ []));
3131
+ clearFiltersText = computed(() => this.state.texts().clearFilters, /* @ts-ignore */
3132
+ ...(ngDevMode ? [{ debugName: "clearFiltersText" }] : /* istanbul ignore next */ []));
3133
+ applyFiltersText = computed(() => this.state.texts().applyFilters, /* @ts-ignore */
3134
+ ...(ngDevMode ? [{ debugName: "applyFiltersText" }] : /* istanbul ignore next */ []));
3135
+ value = computed(() => Object.entries(this.state.tagsFilters()).reduce((previousValue, [key, values]) => {
3136
+ previousValue[key] = {
3137
+ filterType: 'checkbox',
3138
+ selected: values,
3139
+ };
3140
+ return previousValue;
3141
+ }, {}), /* @ts-ignore */
3142
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
3143
+ uniqueTagValuesByTagName = computed(() => {
3144
+ return getLeaves(this.state.entries())
3145
+ .map(({ tags }) => tags)
3146
+ .reduce((previousValue, currentValue) => {
3147
+ Object.entries(currentValue).forEach(([tagName, tagValues]) => {
3148
+ if (!previousValue[tagName]) {
3149
+ previousValue[tagName] = {};
3150
+ }
3151
+ for (const tagValue of tagValues) {
3152
+ previousValue[tagName][tagValue] = true;
3153
+ }
3154
+ });
3155
+ return previousValue;
3156
+ }, {});
3157
+ }, /* @ts-ignore */
3158
+ ...(ngDevMode ? [{ debugName: "uniqueTagValuesByTagName" }] : /* istanbul ignore next */ []));
3159
+ groups = computed(() => {
3160
+ const tagNames = this.state.texts().tagNames;
3161
+ return Object.entries(this.uniqueTagValuesByTagName()).map(([tagName, tagValues]) => ({
3162
+ key: tagName,
3163
+ // Tags come from consumer data, so a tag name outside NavSelectorLeafTags may turn up untranslated at
3164
+ // runtime. Showing it raw is poor, but better than showing nothing at all.
3165
+ title: tagNames[tagName] ?? tagName,
3166
+ expanded: false,
3167
+ filterType: 'checkbox',
3168
+ items: Object.keys(tagValues).map(value => ({ label: value, name: value })),
3169
+ }));
3170
+ }, /* @ts-ignore */
3171
+ ...(ngDevMode ? [{ debugName: "groups" }] : /* istanbul ignore next */ []));
3172
+ onApplyFilters(dropdownOutput) {
3173
+ this.state.filterTags(Object.entries(dropdownOutput).reduce((previousValue, [key, dropdownValues]) => {
3174
+ previousValue[key] = dropdownValues.selected;
3175
+ return previousValue;
3176
+ }, {}));
3177
+ }
3178
+ onClearFilters() {
3179
+ this.state.clearFilterTags();
3180
+ }
3181
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NavSelectorTagsFilterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3182
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.5", type: NavSelectorTagsFilterComponent, isStandalone: true, selector: "ap-nav-selector-tags-filter", ngImport: i0, template: `
3183
+ <ap-filter-dropdown-button
3184
+ [buttonFilterText]="filterButtonText()"
3185
+ [clearFilterText]="clearFiltersText()"
3186
+ [applyFiltersText]="applyFiltersText()"
3187
+ [groups]="groups()"
3188
+ [closable]="false"
3189
+ [value]="value()"
3190
+ [needApplyButton]="true"
3191
+ (clearFilters)="onClearFilters()"
3192
+ (applyFilters)="onApplyFilters($event)" />
3193
+ `, isInline: true, styles: [""], dependencies: [{ kind: "component", type: FilterDropdownButtonComponent, selector: "ap-filter-dropdown-button", inputs: ["buttonFilterText", "groups", "value", "savedValue", "needApplyButton", "needClearButton", "closable", "expandOnOpen", "presetsFeatureLocked", "savePresetsMode", "editingPresetsMode", "showBackdrop", "disabled", "defaultPosition", "panelClass", "saveNewPresetsText", "saveAsNewPresetText", "savePresetText", "updateExistingPresetText", "resetFilterText", "applyFiltersText", "clearFilterText"], outputs: ["opened", "closed", "presetsLockedClicked", "saveNewPresets", "updatePresets", "applyFilters", "clearFilters", "resetFilters", "lockedFeatureClicked", "filterDropdownGroupLockedClicked"] }] });
3194
+ }
3195
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NavSelectorTagsFilterComponent, decorators: [{
3196
+ type: Component,
3197
+ args: [{ selector: 'ap-nav-selector-tags-filter', template: `
3198
+ <ap-filter-dropdown-button
3199
+ [buttonFilterText]="filterButtonText()"
3200
+ [clearFilterText]="clearFiltersText()"
3201
+ [applyFiltersText]="applyFiltersText()"
3202
+ [groups]="groups()"
3203
+ [closable]="false"
3204
+ [value]="value()"
3205
+ [needApplyButton]="true"
3206
+ (clearFilters)="onClearFilters()"
3207
+ (applyFilters)="onApplyFilters($event)" />
3208
+ `, imports: [FilterDropdownButtonComponent] }]
3209
+ }] });
3210
+
3074
3211
  const AUTO_MINIFIED_STATE_WIDTH_BREAKPOINT = 1280;
3075
3212
  const EXPAND_ANIMATION_TIMINGS = '250ms cubic-bezier(.4, 0, .3, 1)';
3076
3213
  const EXPANDED_STATE_WIDTH = '224px';
@@ -3262,7 +3399,7 @@ class NavSelectorComponent {
3262
3399
  }
3263
3400
  }
3264
3401
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: NavSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3265
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: NavSelectorComponent, isStandalone: true, selector: "ap-nav-selector", inputs: { navSelectorEntries: { classPropertyName: "navSelectorEntries", publicName: "navSelectorEntries", isSignal: true, isRequired: true, transformFunction: null }, translatedTexts: { classPropertyName: "translatedTexts", publicName: "translatedTexts", isSignal: true, isRequired: true, transformFunction: null }, multipleModeEnabled: { classPropertyName: "multipleModeEnabled", publicName: "multipleModeEnabled", isSignal: true, isRequired: false, transformFunction: null }, style: { classPropertyName: "style", publicName: "style", isSignal: true, isRequired: false, transformFunction: null }, detailsDisplayedLimit: { classPropertyName: "detailsDisplayedLimit", publicName: "detailsDisplayedLimit", isSignal: true, isRequired: false, transformFunction: null }, embedded: { classPropertyName: "embedded", publicName: "embedded", isSignal: true, isRequired: false, transformFunction: null }, forceExpanded: { classPropertyName: "forceExpanded", publicName: "forceExpanded", isSignal: true, isRequired: false, transformFunction: null }, expandedStateLocalStorageKey: { classPropertyName: "expandedStateLocalStorageKey", publicName: "expandedStateLocalStorageKey", isSignal: true, isRequired: false, transformFunction: null }, selectedEntryUids: { classPropertyName: "selectedEntryUids", publicName: "selectedEntryUids", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { selectedEntryUids: "selectedEntryUidsChange", actionClicked: "actionClicked", emptyStateActionClicked: "emptyStateActionClicked", onExpansionStateChange: "onExpansionStateChange", visibleAccountsChange: "visibleAccountsChange" }, host: { attributes: { "role": "tree" }, listeners: { "keydown.arrowDown": "onArrowDown($event)", "keydown.arrowUp": "onArrowUp($event)", "window:resize": "onWindowResize()" }, properties: { "class.minified": "!navSelectorState.expanded()", "class.embedded": "embedded()", "@expand": "expansionState()" } }, providers: [NavSelectorState, withSymbols(apArrowExpand, apArrowReduce, apSearch)], queries: [{ propertyName: "headerProjection", first: true, predicate: ["header"], descendants: true, isSignal: true }, { propertyName: "contentHeaderProjection", first: true, predicate: ["contentHeader"], descendants: true, isSignal: true }, { propertyName: "footerProjection", first: true, predicate: ["footer"], descendants: true, isSignal: true }], ngImport: i0, template: "<nav [class.embedded]=\"embedded()\">\n @let headerProjectionNotNull = headerProjection();\n @let contentHeaderProjectionNotNull = contentHeaderProjection();\n @let footerProjectionNotNull = footerProjection();\n\n <div class=\"nav-selector__header\">\n @if (!embedded()) {\n @if (navSelectorState.expanded()) {\n <span class=\"h3\">{{ translatedTexts().title }}</span>\n }\n\n <button\n type=\"button\"\n class=\"expand-button\"\n [class.expanded]=\"navSelectorState.expanded()\"\n (click)=\"clickExpandButton()\">\n <ap-symbol\n size=\"sm\"\n [symbolId]=\"navSelectorState.expanded() ? 'arrow-reduce' : 'arrow-expand'\" />\n </button>\n }\n\n @if (headerProjectionNotNull) {\n <ng-container\n [ngTemplateOutlet]=\"headerProjectionNotNull\"\n [ngTemplateOutletContext]=\"{\n expanded: navSelectorState.expanded(),\n }\" />\n }\n\n @if (navSelectorState.expanded()) {\n <ap-input-search\n [id]=\"componentUid + '_search'\"\n [placeholder]=\"translatedTexts().searchPlaceholder\"\n [ngModel]=\"navSelectorState.search()\"\n (ngModelChange)=\"navSelectorState.search.set($event ?? '')\" />\n } @else {\n <ap-icon-button\n type=\"stroked\"\n role=\"search\"\n (onClick)=\"onMinifiedSearchClicked()\">\n <ap-symbol symbolId=\"search\" />\n </ap-icon-button>\n }\n\n @if (contentHeaderProjectionNotNull) {\n <ng-container\n [ngTemplateOutlet]=\"contentHeaderProjectionNotNull\"\n [ngTemplateOutletContext]=\"{\n expanded: navSelectorState.expanded(),\n }\" />\n }\n </div>\n\n <div\n class=\"nav-selector__content\"\n role=\"tree\"\n [attr.aria-multiselectable]=\"navSelectorState.isMultipleModeEnabled()\">\n @for (entry of navSelectorState.entries(); track entry.uid) {\n @if (!entry.hidden) {\n <div\n class=\"entry\"\n [class.folder]=\"entry.type === 'GROUP' || entry.type === 'CATEGORY'\">\n @if (entry.type === 'LEAF') {\n <ap-nav-selector-leaf\n [leaf]=\"entry\"\n (actionClicked)=\"actionClicked.emit($event)\" />\n } @else if (entry.type === 'GROUP') {\n <ap-nav-selector-group\n [group]=\"entry\"\n (actionClicked)=\"actionClicked.emit($event)\" />\n } @else if (entry.type === 'CATEGORY') {\n <ap-nav-selector-category\n [category]=\"$any(entry)\"\n (actionClicked)=\"actionClicked.emit($event)\"\n (emptyStateActionClicked)=\"emptyStateActionClicked.emit($event)\"/>\n }\n </div>\n }\n }\n @if (navSelectorState.expanded() && navSelectorState.noResults()) {\n <div class=\"no-result\">{{ translatedTexts().noResults }}</div>\n }\n </div>\n\n @if (displayFooter() && footerProjectionNotNull) {\n <div class=\"nav-selector__footer\">\n <ng-container\n [ngTemplateOutlet]=\"footerProjectionNotNull\"\n [ngTemplateOutletContext]=\"{\n expanded: navSelectorState.expanded(),\n }\" />\n </div>\n }\n</nav>\n", styles: [":host,nav{width:224px}@media only screen and (min-width:1400px){:host:not(.embedded),nav:not(.embedded){width:250px}:host:not(.embedded) .nav-selector__content,nav:not(.embedded) .nav-selector__content{width:250px}}:host{display:flex;flex-direction:column;align-items:flex-start;flex-shrink:0;flex-grow:1}:host :hover .expand-button.expanded{animation-name:translateExpandButton}:host nav{display:flex;height:100%;flex-grow:1;flex-direction:column;align-items:flex-start;flex-shrink:0;overflow:hidden;background:var(--ref-color-white);transition:width .25s cubic-bezier(.4,0,.3,1)}:host nav:not(.embedded){border-right:1px solid var(--ref-color-grey-10)}:host .nav-selector__header{position:relative;display:flex;padding:var(--ref-spacing-xs) var(--ref-spacing-sm);flex-direction:column;align-items:flex-start;gap:var(--ref-spacing-xxs);align-self:stretch;white-space:nowrap;border-bottom:1px solid var(--ref-color-grey-10);background:var(--ref-color-white)}:host .nav-selector__header .h3{color:var(--ref-color-grey-100);font-family:Averta;font-size:var(--sys-text-style-h3-size);font-style:normal;font-weight:var(--ref-font-weight-bold);line-height:var(--ref-font-line-height-lg)}:host .nav-selector__header .expand-button-container{position:absolute;right:0;top:var(--ref-spacing-xs)}:host .nav-selector__header ap-input-search{width:100%}@keyframes translateHideButton{0%{transform:translate(0)}to{transform:translate(100%)}}@keyframes translateExpandButton{0%{transform:translate(100%)}to{transform:translate(0)}}:host .nav-selector__header .expand-button{animation-duration:70ms;animation-timing-function:cubic-bezier(0,0,.2,1);animation-fill-mode:forwards;animation-name:translateHideButton}:host .nav-selector__header .expand-button.expanded{position:absolute;right:0;top:12px;transform:translate(100%)}:host .nav-selector__header .expand-button{display:flex;width:24px;height:24px;justify-content:center;align-items:center;background:var(--ref-color-grey-bg);border-top:1px solid var(--ref-color-grey-20);border-right:none;border-bottom:1px solid var(--ref-color-grey-20);border-left:1px solid var(--ref-color-grey-20);border-top-left-radius:var(--ref-border-radius-sm);border-bottom-left-radius:var(--ref-border-radius-sm);cursor:pointer}:host .nav-selector__header .expand-button ap-symbol[symbol-id=arrow-reduce],:host .nav-selector__header .expand-button ap-symbol[symbol-id=arrow-expand]{color:var(--ref-color-grey-80)}:host .nav-selector__header .expand-button:focus-visible.expanded{animation-name:translateExpandButton}:host .nav-selector__header .expand-button:focus-visible{border-radius:var(--ref-border-radius-sm) 0px 0px var(--ref-border-radius-sm);border-top:1px solid var(--ref-color-grey-20);border-bottom:1px solid var(--ref-color-grey-20);border-left:1px solid var(--ref-color-grey-20);background:var(--ref-color-grey-10);box-shadow:0 0 0 1px #fff,0 0 0 3px #178dfe}:host .nav-selector__header .expand-button:hover{background-color:var(--ref-color-grey-10)}:host .nav-selector__header .expand-button:active{background-color:var(--ref-color-grey-20)}:host .nav-selector__content{display:flex;flex-direction:column;align-items:flex-start;flex:1 0 0;align-self:stretch;width:224px;overflow-y:auto;overflow-x:hidden;transition:width .25s cubic-bezier(.4,0,.3,1)}:host .nav-selector__content .entry{align-self:stretch;display:flex;flex-direction:column}:host .nav-selector__content .entry.folder{padding:var(--ref-spacing-xxs);border-bottom:1px solid var(--sys-border-color-default)}:host .nav-selector__content .entry.folder+.entry:not(.folder){padding-top:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder){padding-left:var(--ref-spacing-xxs);padding-right:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder):first-child{padding-top:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder):last-child{padding-bottom:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder):has(+.entry.folder){padding-bottom:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder)+.entry.folder{border-top:1px solid var(--sys-border-color-default)}:host .nav-selector__content .no-result{display:flex;padding:var(--ref-spacing-sm);flex-direction:column;align-items:flex-start;flex:1 0 0;align-self:stretch;color:var(--ref-color-grey-80);font-family:Averta;font-size:var(--ref-font-size-sm);font-style:italic;font-weight:400;line-height:var(--ref-font-line-height-sm)}:host .nav-selector__footer{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ref-spacing-xxs);align-self:stretch;border-top:1px solid var(--sys-border-color-default);background:var(--ref-color-white)}:host.minified{width:64px}:host.minified nav{width:64px}:host.minified nav .nav-selector__header{align-items:center}:host.minified nav .nav-selector__header .expand-button{animation-name:none;border-radius:var(--ref-border-radius-sm);border:1px solid var(--ref-color-grey-20);background:var(--ref-color-grey-bg)}:host.minified nav .nav-selector__content{width:64px}:host.minified nav .nav-selector__content .entry{padding:var(--ref-spacing-xxxs)}\n"], dependencies: [{ kind: "component", type: NavSelectorLeafComponent, selector: "ap-nav-selector-leaf", inputs: ["leaf"], outputs: ["actionClicked"] }, { kind: "component", type: NavSelectorGroupComponent, selector: "ap-nav-selector-group", inputs: ["group"], outputs: ["actionClicked"] }, { kind: "component", type: NavSelectorCategoryComponent, selector: "ap-nav-selector-category", inputs: ["category"], outputs: ["emptyStateActionClicked", "actionClicked"] }, { kind: "component", type: InputSearchComponent, selector: "ap-input-search", inputs: ["id", "placeholder", "clearable"], outputs: ["focus", "blur", "keyup"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: SymbolComponent, selector: "ap-symbol", inputs: ["symbolId", "color", "size"], outputs: ["sizeChange"] }, { kind: "component", type: IconButtonComponent, selector: "ap-icon-button", inputs: ["ariaLabel", "name", "color", "disabled", "menuTrigger", "symbolId", "locked", "loading", "type"], outputs: ["onClick", "onFocus", "onBlur", "menuOpened", "menuClosed"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], animations: [
3402
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: NavSelectorComponent, isStandalone: true, selector: "ap-nav-selector", inputs: { navSelectorEntries: { classPropertyName: "navSelectorEntries", publicName: "navSelectorEntries", isSignal: true, isRequired: true, transformFunction: null }, translatedTexts: { classPropertyName: "translatedTexts", publicName: "translatedTexts", isSignal: true, isRequired: true, transformFunction: null }, multipleModeEnabled: { classPropertyName: "multipleModeEnabled", publicName: "multipleModeEnabled", isSignal: true, isRequired: false, transformFunction: null }, style: { classPropertyName: "style", publicName: "style", isSignal: true, isRequired: false, transformFunction: null }, detailsDisplayedLimit: { classPropertyName: "detailsDisplayedLimit", publicName: "detailsDisplayedLimit", isSignal: true, isRequired: false, transformFunction: null }, embedded: { classPropertyName: "embedded", publicName: "embedded", isSignal: true, isRequired: false, transformFunction: null }, forceExpanded: { classPropertyName: "forceExpanded", publicName: "forceExpanded", isSignal: true, isRequired: false, transformFunction: null }, expandedStateLocalStorageKey: { classPropertyName: "expandedStateLocalStorageKey", publicName: "expandedStateLocalStorageKey", isSignal: true, isRequired: false, transformFunction: null }, selectedEntryUids: { classPropertyName: "selectedEntryUids", publicName: "selectedEntryUids", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { selectedEntryUids: "selectedEntryUidsChange", actionClicked: "actionClicked", emptyStateActionClicked: "emptyStateActionClicked", onExpansionStateChange: "onExpansionStateChange", visibleAccountsChange: "visibleAccountsChange" }, host: { attributes: { "role": "tree" }, listeners: { "keydown.arrowDown": "onArrowDown($event)", "keydown.arrowUp": "onArrowUp($event)", "window:resize": "onWindowResize()" }, properties: { "class.minified": "!navSelectorState.expanded()", "class.embedded": "embedded()", "@expand": "expansionState()" } }, providers: [NavSelectorState, withSymbols(apArrowExpand, apArrowReduce, apSearch)], queries: [{ propertyName: "headerProjection", first: true, predicate: ["header"], descendants: true, isSignal: true }, { propertyName: "contentHeaderProjection", first: true, predicate: ["contentHeader"], descendants: true, isSignal: true }, { propertyName: "footerProjection", first: true, predicate: ["footer"], descendants: true, isSignal: true }], ngImport: i0, template: "<nav [class.embedded]=\"embedded()\">\n @let headerProjectionNotNull = headerProjection();\n @let contentHeaderProjectionNotNull = contentHeaderProjection();\n @let footerProjectionNotNull = footerProjection();\n\n <div class=\"nav-selector__header\">\n @if (!embedded()) {\n @if (navSelectorState.expanded()) {\n <span class=\"h3\">{{ translatedTexts().title }}</span>\n }\n\n <button\n type=\"button\"\n class=\"expand-button\"\n [class.expanded]=\"navSelectorState.expanded()\"\n (click)=\"clickExpandButton()\">\n <ap-symbol\n size=\"sm\"\n [symbolId]=\"navSelectorState.expanded() ? 'arrow-reduce' : 'arrow-expand'\" />\n </button>\n }\n\n @if (headerProjectionNotNull) {\n <ng-container\n [ngTemplateOutlet]=\"headerProjectionNotNull\"\n [ngTemplateOutletContext]=\"{\n expanded: navSelectorState.expanded(),\n }\" />\n }\n\n @if (navSelectorState.expanded()) {\n <ap-input-search\n [id]=\"componentUid + '_search'\"\n [placeholder]=\"translatedTexts().searchPlaceholder\"\n [ngModel]=\"navSelectorState.search()\"\n (ngModelChange)=\"navSelectorState.search.set($event ?? '')\" />\n\n @if (navSelectorState.tagsFilterDisplayed()) {\n <ap-nav-selector-tags-filter />\n }\n } @else {\n <ap-icon-button\n type=\"stroked\"\n role=\"search\"\n (onClick)=\"onMinifiedSearchClicked()\">\n <ap-symbol symbolId=\"search\" />\n </ap-icon-button>\n }\n\n @if (contentHeaderProjectionNotNull) {\n <ng-container\n [ngTemplateOutlet]=\"contentHeaderProjectionNotNull\"\n [ngTemplateOutletContext]=\"{\n expanded: navSelectorState.expanded(),\n }\" />\n }\n </div>\n\n <div\n class=\"nav-selector__content\"\n role=\"tree\"\n [attr.aria-multiselectable]=\"navSelectorState.isMultipleModeEnabled()\">\n @for (entry of navSelectorState.entries(); track entry.uid) {\n @if (!entry.hidden) {\n <div\n class=\"entry\"\n [class.folder]=\"entry.type === 'GROUP' || entry.type === 'CATEGORY'\">\n @if (entry.type === 'LEAF') {\n <ap-nav-selector-leaf\n [leaf]=\"entry\"\n (actionClicked)=\"actionClicked.emit($event)\" />\n } @else if (entry.type === 'GROUP') {\n <ap-nav-selector-group\n [group]=\"entry\"\n (actionClicked)=\"actionClicked.emit($event)\" />\n } @else if (entry.type === 'CATEGORY') {\n <ap-nav-selector-category\n [category]=\"$any(entry)\"\n (actionClicked)=\"actionClicked.emit($event)\"\n (emptyStateActionClicked)=\"emptyStateActionClicked.emit($event)\" />\n }\n </div>\n }\n }\n @if (navSelectorState.expanded() && navSelectorState.noResults()) {\n <div class=\"no-result\">{{ translatedTexts().noResults }}</div>\n }\n </div>\n\n @if (displayFooter() && footerProjectionNotNull) {\n <div class=\"nav-selector__footer\">\n <ng-container\n [ngTemplateOutlet]=\"footerProjectionNotNull\"\n [ngTemplateOutletContext]=\"{\n expanded: navSelectorState.expanded(),\n }\" />\n </div>\n }\n</nav>\n", styles: [":host,nav{width:224px}@media only screen and (min-width:1400px){:host:not(.embedded),nav:not(.embedded){width:250px}:host:not(.embedded) .nav-selector__content,nav:not(.embedded) .nav-selector__content{width:250px}}:host{display:flex;flex-direction:column;align-items:flex-start;flex-shrink:0;flex-grow:1}:host :hover .expand-button.expanded{animation-name:translateExpandButton}:host nav{display:flex;height:100%;flex-grow:1;flex-direction:column;align-items:flex-start;flex-shrink:0;overflow:hidden;background:var(--ref-color-white);transition:width .25s cubic-bezier(.4,0,.3,1)}:host nav:not(.embedded){border-right:1px solid var(--ref-color-grey-10)}:host .nav-selector__header{position:relative;display:flex;padding:var(--ref-spacing-xs) var(--ref-spacing-sm);flex-direction:column;align-items:flex-start;gap:var(--ref-spacing-xxs);align-self:stretch;white-space:nowrap;border-bottom:1px solid var(--ref-color-grey-10);background:var(--ref-color-white)}:host .nav-selector__header .h3{color:var(--ref-color-grey-100);font-family:Averta;font-size:var(--sys-text-style-h3-size);font-style:normal;font-weight:var(--ref-font-weight-bold);line-height:var(--ref-font-line-height-lg)}:host .nav-selector__header .expand-button-container{position:absolute;right:0;top:var(--ref-spacing-xs)}:host .nav-selector__header ap-input-search{width:100%}@keyframes translateHideButton{0%{transform:translate(0)}to{transform:translate(100%)}}@keyframes translateExpandButton{0%{transform:translate(100%)}to{transform:translate(0)}}:host .nav-selector__header .expand-button{animation-duration:70ms;animation-timing-function:cubic-bezier(0,0,.2,1);animation-fill-mode:forwards;animation-name:translateHideButton}:host .nav-selector__header .expand-button.expanded{position:absolute;right:0;top:12px;transform:translate(100%)}:host .nav-selector__header .expand-button{display:flex;width:24px;height:24px;justify-content:center;align-items:center;background:var(--ref-color-grey-bg);border-top:1px solid var(--ref-color-grey-20);border-right:none;border-bottom:1px solid var(--ref-color-grey-20);border-left:1px solid var(--ref-color-grey-20);border-top-left-radius:var(--ref-border-radius-sm);border-bottom-left-radius:var(--ref-border-radius-sm);cursor:pointer}:host .nav-selector__header .expand-button ap-symbol[symbol-id=arrow-reduce],:host .nav-selector__header .expand-button ap-symbol[symbol-id=arrow-expand]{color:var(--ref-color-grey-80)}:host .nav-selector__header .expand-button:focus-visible.expanded{animation-name:translateExpandButton}:host .nav-selector__header .expand-button:focus-visible{border-radius:var(--ref-border-radius-sm) 0px 0px var(--ref-border-radius-sm);border-top:1px solid var(--ref-color-grey-20);border-bottom:1px solid var(--ref-color-grey-20);border-left:1px solid var(--ref-color-grey-20);background:var(--ref-color-grey-10);box-shadow:0 0 0 1px #fff,0 0 0 3px #178dfe}:host .nav-selector__header .expand-button:hover{background-color:var(--ref-color-grey-10)}:host .nav-selector__header .expand-button:active{background-color:var(--ref-color-grey-20)}:host .nav-selector__content{display:flex;flex-direction:column;align-items:flex-start;flex:1 0 0;align-self:stretch;width:224px;overflow-y:auto;overflow-x:hidden;transition:width .25s cubic-bezier(.4,0,.3,1)}:host .nav-selector__content .entry{align-self:stretch;display:flex;flex-direction:column}:host .nav-selector__content .entry.folder{padding:var(--ref-spacing-xxs);border-bottom:1px solid var(--sys-border-color-default)}:host .nav-selector__content .entry.folder+.entry:not(.folder){padding-top:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder){padding-left:var(--ref-spacing-xxs);padding-right:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder):first-child{padding-top:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder):last-child{padding-bottom:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder):has(+.entry.folder){padding-bottom:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder)+.entry.folder{border-top:1px solid var(--sys-border-color-default)}:host .nav-selector__content .no-result{display:flex;padding:var(--ref-spacing-sm);flex-direction:column;align-items:flex-start;flex:1 0 0;align-self:stretch;color:var(--ref-color-grey-80);font-family:Averta;font-size:var(--ref-font-size-sm);font-style:italic;font-weight:400;line-height:var(--ref-font-line-height-sm)}:host .nav-selector__footer{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ref-spacing-xxs);align-self:stretch;border-top:1px solid var(--sys-border-color-default);background:var(--ref-color-white)}:host.minified{width:64px}:host.minified nav{width:64px}:host.minified nav .nav-selector__header{align-items:center}:host.minified nav .nav-selector__header .expand-button{animation-name:none;border-radius:var(--ref-border-radius-sm);border:1px solid var(--ref-color-grey-20);background:var(--ref-color-grey-bg)}:host.minified nav .nav-selector__content{width:64px}:host.minified nav .nav-selector__content .entry{padding:var(--ref-spacing-xxxs)}\n"], dependencies: [{ kind: "component", type: NavSelectorLeafComponent, selector: "ap-nav-selector-leaf", inputs: ["leaf"], outputs: ["actionClicked"] }, { kind: "component", type: NavSelectorGroupComponent, selector: "ap-nav-selector-group", inputs: ["group"], outputs: ["actionClicked"] }, { kind: "component", type: NavSelectorCategoryComponent, selector: "ap-nav-selector-category", inputs: ["category"], outputs: ["emptyStateActionClicked", "actionClicked"] }, { kind: "component", type: InputSearchComponent, selector: "ap-input-search", inputs: ["id", "placeholder", "clearable"], outputs: ["focus", "blur", "keyup"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: SymbolComponent, selector: "ap-symbol", inputs: ["symbolId", "color", "size"], outputs: ["sizeChange"] }, { kind: "component", type: IconButtonComponent, selector: "ap-icon-button", inputs: ["ariaLabel", "name", "color", "disabled", "menuTrigger", "symbolId", "locked", "loading", "type"], outputs: ["onClick", "onFocus", "onBlur", "menuOpened", "menuClosed"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: NavSelectorTagsFilterComponent, selector: "ap-nav-selector-tags-filter" }], animations: [
3266
3403
  trigger('expand', [
3267
3404
  transition('expanded => minified', animate(EXPAND_ANIMATION_TIMINGS, keyframes([style({ width: EXPANDED_STATE_WIDTH }), style({ width: '100px' }), style({ width: MINIFIED_STATE_WIDTH })]))),
3268
3405
  transition('minified => expanded', animate(EXPAND_ANIMATION_TIMINGS, keyframes([style({ width: MINIFIED_STATE_WIDTH }), style({ width: '50%' }), style({ width: '100%' })]))),
@@ -3280,6 +3417,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
3280
3417
  SymbolComponent,
3281
3418
  IconButtonComponent,
3282
3419
  NgTemplateOutlet,
3420
+ NavSelectorTagsFilterComponent,
3283
3421
  ], providers: [NavSelectorState, withSymbols(apArrowExpand, apArrowReduce, apSearch)], host: {
3284
3422
  '[class.minified]': '!navSelectorState.expanded()',
3285
3423
  '[class.embedded]': 'embedded()',
@@ -3293,7 +3431,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
3293
3431
  transition('expanded => minified', animate(EXPAND_ANIMATION_TIMINGS, keyframes([style({ width: EXPANDED_STATE_WIDTH }), style({ width: '100px' }), style({ width: MINIFIED_STATE_WIDTH })]))),
3294
3432
  transition('minified => expanded', animate(EXPAND_ANIMATION_TIMINGS, keyframes([style({ width: MINIFIED_STATE_WIDTH }), style({ width: '50%' }), style({ width: '100%' })]))),
3295
3433
  ]),
3296
- ], template: "<nav [class.embedded]=\"embedded()\">\n @let headerProjectionNotNull = headerProjection();\n @let contentHeaderProjectionNotNull = contentHeaderProjection();\n @let footerProjectionNotNull = footerProjection();\n\n <div class=\"nav-selector__header\">\n @if (!embedded()) {\n @if (navSelectorState.expanded()) {\n <span class=\"h3\">{{ translatedTexts().title }}</span>\n }\n\n <button\n type=\"button\"\n class=\"expand-button\"\n [class.expanded]=\"navSelectorState.expanded()\"\n (click)=\"clickExpandButton()\">\n <ap-symbol\n size=\"sm\"\n [symbolId]=\"navSelectorState.expanded() ? 'arrow-reduce' : 'arrow-expand'\" />\n </button>\n }\n\n @if (headerProjectionNotNull) {\n <ng-container\n [ngTemplateOutlet]=\"headerProjectionNotNull\"\n [ngTemplateOutletContext]=\"{\n expanded: navSelectorState.expanded(),\n }\" />\n }\n\n @if (navSelectorState.expanded()) {\n <ap-input-search\n [id]=\"componentUid + '_search'\"\n [placeholder]=\"translatedTexts().searchPlaceholder\"\n [ngModel]=\"navSelectorState.search()\"\n (ngModelChange)=\"navSelectorState.search.set($event ?? '')\" />\n } @else {\n <ap-icon-button\n type=\"stroked\"\n role=\"search\"\n (onClick)=\"onMinifiedSearchClicked()\">\n <ap-symbol symbolId=\"search\" />\n </ap-icon-button>\n }\n\n @if (contentHeaderProjectionNotNull) {\n <ng-container\n [ngTemplateOutlet]=\"contentHeaderProjectionNotNull\"\n [ngTemplateOutletContext]=\"{\n expanded: navSelectorState.expanded(),\n }\" />\n }\n </div>\n\n <div\n class=\"nav-selector__content\"\n role=\"tree\"\n [attr.aria-multiselectable]=\"navSelectorState.isMultipleModeEnabled()\">\n @for (entry of navSelectorState.entries(); track entry.uid) {\n @if (!entry.hidden) {\n <div\n class=\"entry\"\n [class.folder]=\"entry.type === 'GROUP' || entry.type === 'CATEGORY'\">\n @if (entry.type === 'LEAF') {\n <ap-nav-selector-leaf\n [leaf]=\"entry\"\n (actionClicked)=\"actionClicked.emit($event)\" />\n } @else if (entry.type === 'GROUP') {\n <ap-nav-selector-group\n [group]=\"entry\"\n (actionClicked)=\"actionClicked.emit($event)\" />\n } @else if (entry.type === 'CATEGORY') {\n <ap-nav-selector-category\n [category]=\"$any(entry)\"\n (actionClicked)=\"actionClicked.emit($event)\"\n (emptyStateActionClicked)=\"emptyStateActionClicked.emit($event)\"/>\n }\n </div>\n }\n }\n @if (navSelectorState.expanded() && navSelectorState.noResults()) {\n <div class=\"no-result\">{{ translatedTexts().noResults }}</div>\n }\n </div>\n\n @if (displayFooter() && footerProjectionNotNull) {\n <div class=\"nav-selector__footer\">\n <ng-container\n [ngTemplateOutlet]=\"footerProjectionNotNull\"\n [ngTemplateOutletContext]=\"{\n expanded: navSelectorState.expanded(),\n }\" />\n </div>\n }\n</nav>\n", styles: [":host,nav{width:224px}@media only screen and (min-width:1400px){:host:not(.embedded),nav:not(.embedded){width:250px}:host:not(.embedded) .nav-selector__content,nav:not(.embedded) .nav-selector__content{width:250px}}:host{display:flex;flex-direction:column;align-items:flex-start;flex-shrink:0;flex-grow:1}:host :hover .expand-button.expanded{animation-name:translateExpandButton}:host nav{display:flex;height:100%;flex-grow:1;flex-direction:column;align-items:flex-start;flex-shrink:0;overflow:hidden;background:var(--ref-color-white);transition:width .25s cubic-bezier(.4,0,.3,1)}:host nav:not(.embedded){border-right:1px solid var(--ref-color-grey-10)}:host .nav-selector__header{position:relative;display:flex;padding:var(--ref-spacing-xs) var(--ref-spacing-sm);flex-direction:column;align-items:flex-start;gap:var(--ref-spacing-xxs);align-self:stretch;white-space:nowrap;border-bottom:1px solid var(--ref-color-grey-10);background:var(--ref-color-white)}:host .nav-selector__header .h3{color:var(--ref-color-grey-100);font-family:Averta;font-size:var(--sys-text-style-h3-size);font-style:normal;font-weight:var(--ref-font-weight-bold);line-height:var(--ref-font-line-height-lg)}:host .nav-selector__header .expand-button-container{position:absolute;right:0;top:var(--ref-spacing-xs)}:host .nav-selector__header ap-input-search{width:100%}@keyframes translateHideButton{0%{transform:translate(0)}to{transform:translate(100%)}}@keyframes translateExpandButton{0%{transform:translate(100%)}to{transform:translate(0)}}:host .nav-selector__header .expand-button{animation-duration:70ms;animation-timing-function:cubic-bezier(0,0,.2,1);animation-fill-mode:forwards;animation-name:translateHideButton}:host .nav-selector__header .expand-button.expanded{position:absolute;right:0;top:12px;transform:translate(100%)}:host .nav-selector__header .expand-button{display:flex;width:24px;height:24px;justify-content:center;align-items:center;background:var(--ref-color-grey-bg);border-top:1px solid var(--ref-color-grey-20);border-right:none;border-bottom:1px solid var(--ref-color-grey-20);border-left:1px solid var(--ref-color-grey-20);border-top-left-radius:var(--ref-border-radius-sm);border-bottom-left-radius:var(--ref-border-radius-sm);cursor:pointer}:host .nav-selector__header .expand-button ap-symbol[symbol-id=arrow-reduce],:host .nav-selector__header .expand-button ap-symbol[symbol-id=arrow-expand]{color:var(--ref-color-grey-80)}:host .nav-selector__header .expand-button:focus-visible.expanded{animation-name:translateExpandButton}:host .nav-selector__header .expand-button:focus-visible{border-radius:var(--ref-border-radius-sm) 0px 0px var(--ref-border-radius-sm);border-top:1px solid var(--ref-color-grey-20);border-bottom:1px solid var(--ref-color-grey-20);border-left:1px solid var(--ref-color-grey-20);background:var(--ref-color-grey-10);box-shadow:0 0 0 1px #fff,0 0 0 3px #178dfe}:host .nav-selector__header .expand-button:hover{background-color:var(--ref-color-grey-10)}:host .nav-selector__header .expand-button:active{background-color:var(--ref-color-grey-20)}:host .nav-selector__content{display:flex;flex-direction:column;align-items:flex-start;flex:1 0 0;align-self:stretch;width:224px;overflow-y:auto;overflow-x:hidden;transition:width .25s cubic-bezier(.4,0,.3,1)}:host .nav-selector__content .entry{align-self:stretch;display:flex;flex-direction:column}:host .nav-selector__content .entry.folder{padding:var(--ref-spacing-xxs);border-bottom:1px solid var(--sys-border-color-default)}:host .nav-selector__content .entry.folder+.entry:not(.folder){padding-top:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder){padding-left:var(--ref-spacing-xxs);padding-right:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder):first-child{padding-top:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder):last-child{padding-bottom:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder):has(+.entry.folder){padding-bottom:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder)+.entry.folder{border-top:1px solid var(--sys-border-color-default)}:host .nav-selector__content .no-result{display:flex;padding:var(--ref-spacing-sm);flex-direction:column;align-items:flex-start;flex:1 0 0;align-self:stretch;color:var(--ref-color-grey-80);font-family:Averta;font-size:var(--ref-font-size-sm);font-style:italic;font-weight:400;line-height:var(--ref-font-line-height-sm)}:host .nav-selector__footer{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ref-spacing-xxs);align-self:stretch;border-top:1px solid var(--sys-border-color-default);background:var(--ref-color-white)}:host.minified{width:64px}:host.minified nav{width:64px}:host.minified nav .nav-selector__header{align-items:center}:host.minified nav .nav-selector__header .expand-button{animation-name:none;border-radius:var(--ref-border-radius-sm);border:1px solid var(--ref-color-grey-20);background:var(--ref-color-grey-bg)}:host.minified nav .nav-selector__content{width:64px}:host.minified nav .nav-selector__content .entry{padding:var(--ref-spacing-xxxs)}\n"] }]
3434
+ ], template: "<nav [class.embedded]=\"embedded()\">\n @let headerProjectionNotNull = headerProjection();\n @let contentHeaderProjectionNotNull = contentHeaderProjection();\n @let footerProjectionNotNull = footerProjection();\n\n <div class=\"nav-selector__header\">\n @if (!embedded()) {\n @if (navSelectorState.expanded()) {\n <span class=\"h3\">{{ translatedTexts().title }}</span>\n }\n\n <button\n type=\"button\"\n class=\"expand-button\"\n [class.expanded]=\"navSelectorState.expanded()\"\n (click)=\"clickExpandButton()\">\n <ap-symbol\n size=\"sm\"\n [symbolId]=\"navSelectorState.expanded() ? 'arrow-reduce' : 'arrow-expand'\" />\n </button>\n }\n\n @if (headerProjectionNotNull) {\n <ng-container\n [ngTemplateOutlet]=\"headerProjectionNotNull\"\n [ngTemplateOutletContext]=\"{\n expanded: navSelectorState.expanded(),\n }\" />\n }\n\n @if (navSelectorState.expanded()) {\n <ap-input-search\n [id]=\"componentUid + '_search'\"\n [placeholder]=\"translatedTexts().searchPlaceholder\"\n [ngModel]=\"navSelectorState.search()\"\n (ngModelChange)=\"navSelectorState.search.set($event ?? '')\" />\n\n @if (navSelectorState.tagsFilterDisplayed()) {\n <ap-nav-selector-tags-filter />\n }\n } @else {\n <ap-icon-button\n type=\"stroked\"\n role=\"search\"\n (onClick)=\"onMinifiedSearchClicked()\">\n <ap-symbol symbolId=\"search\" />\n </ap-icon-button>\n }\n\n @if (contentHeaderProjectionNotNull) {\n <ng-container\n [ngTemplateOutlet]=\"contentHeaderProjectionNotNull\"\n [ngTemplateOutletContext]=\"{\n expanded: navSelectorState.expanded(),\n }\" />\n }\n </div>\n\n <div\n class=\"nav-selector__content\"\n role=\"tree\"\n [attr.aria-multiselectable]=\"navSelectorState.isMultipleModeEnabled()\">\n @for (entry of navSelectorState.entries(); track entry.uid) {\n @if (!entry.hidden) {\n <div\n class=\"entry\"\n [class.folder]=\"entry.type === 'GROUP' || entry.type === 'CATEGORY'\">\n @if (entry.type === 'LEAF') {\n <ap-nav-selector-leaf\n [leaf]=\"entry\"\n (actionClicked)=\"actionClicked.emit($event)\" />\n } @else if (entry.type === 'GROUP') {\n <ap-nav-selector-group\n [group]=\"entry\"\n (actionClicked)=\"actionClicked.emit($event)\" />\n } @else if (entry.type === 'CATEGORY') {\n <ap-nav-selector-category\n [category]=\"$any(entry)\"\n (actionClicked)=\"actionClicked.emit($event)\"\n (emptyStateActionClicked)=\"emptyStateActionClicked.emit($event)\" />\n }\n </div>\n }\n }\n @if (navSelectorState.expanded() && navSelectorState.noResults()) {\n <div class=\"no-result\">{{ translatedTexts().noResults }}</div>\n }\n </div>\n\n @if (displayFooter() && footerProjectionNotNull) {\n <div class=\"nav-selector__footer\">\n <ng-container\n [ngTemplateOutlet]=\"footerProjectionNotNull\"\n [ngTemplateOutletContext]=\"{\n expanded: navSelectorState.expanded(),\n }\" />\n </div>\n }\n</nav>\n", styles: [":host,nav{width:224px}@media only screen and (min-width:1400px){:host:not(.embedded),nav:not(.embedded){width:250px}:host:not(.embedded) .nav-selector__content,nav:not(.embedded) .nav-selector__content{width:250px}}:host{display:flex;flex-direction:column;align-items:flex-start;flex-shrink:0;flex-grow:1}:host :hover .expand-button.expanded{animation-name:translateExpandButton}:host nav{display:flex;height:100%;flex-grow:1;flex-direction:column;align-items:flex-start;flex-shrink:0;overflow:hidden;background:var(--ref-color-white);transition:width .25s cubic-bezier(.4,0,.3,1)}:host nav:not(.embedded){border-right:1px solid var(--ref-color-grey-10)}:host .nav-selector__header{position:relative;display:flex;padding:var(--ref-spacing-xs) var(--ref-spacing-sm);flex-direction:column;align-items:flex-start;gap:var(--ref-spacing-xxs);align-self:stretch;white-space:nowrap;border-bottom:1px solid var(--ref-color-grey-10);background:var(--ref-color-white)}:host .nav-selector__header .h3{color:var(--ref-color-grey-100);font-family:Averta;font-size:var(--sys-text-style-h3-size);font-style:normal;font-weight:var(--ref-font-weight-bold);line-height:var(--ref-font-line-height-lg)}:host .nav-selector__header .expand-button-container{position:absolute;right:0;top:var(--ref-spacing-xs)}:host .nav-selector__header ap-input-search{width:100%}@keyframes translateHideButton{0%{transform:translate(0)}to{transform:translate(100%)}}@keyframes translateExpandButton{0%{transform:translate(100%)}to{transform:translate(0)}}:host .nav-selector__header .expand-button{animation-duration:70ms;animation-timing-function:cubic-bezier(0,0,.2,1);animation-fill-mode:forwards;animation-name:translateHideButton}:host .nav-selector__header .expand-button.expanded{position:absolute;right:0;top:12px;transform:translate(100%)}:host .nav-selector__header .expand-button{display:flex;width:24px;height:24px;justify-content:center;align-items:center;background:var(--ref-color-grey-bg);border-top:1px solid var(--ref-color-grey-20);border-right:none;border-bottom:1px solid var(--ref-color-grey-20);border-left:1px solid var(--ref-color-grey-20);border-top-left-radius:var(--ref-border-radius-sm);border-bottom-left-radius:var(--ref-border-radius-sm);cursor:pointer}:host .nav-selector__header .expand-button ap-symbol[symbol-id=arrow-reduce],:host .nav-selector__header .expand-button ap-symbol[symbol-id=arrow-expand]{color:var(--ref-color-grey-80)}:host .nav-selector__header .expand-button:focus-visible.expanded{animation-name:translateExpandButton}:host .nav-selector__header .expand-button:focus-visible{border-radius:var(--ref-border-radius-sm) 0px 0px var(--ref-border-radius-sm);border-top:1px solid var(--ref-color-grey-20);border-bottom:1px solid var(--ref-color-grey-20);border-left:1px solid var(--ref-color-grey-20);background:var(--ref-color-grey-10);box-shadow:0 0 0 1px #fff,0 0 0 3px #178dfe}:host .nav-selector__header .expand-button:hover{background-color:var(--ref-color-grey-10)}:host .nav-selector__header .expand-button:active{background-color:var(--ref-color-grey-20)}:host .nav-selector__content{display:flex;flex-direction:column;align-items:flex-start;flex:1 0 0;align-self:stretch;width:224px;overflow-y:auto;overflow-x:hidden;transition:width .25s cubic-bezier(.4,0,.3,1)}:host .nav-selector__content .entry{align-self:stretch;display:flex;flex-direction:column}:host .nav-selector__content .entry.folder{padding:var(--ref-spacing-xxs);border-bottom:1px solid var(--sys-border-color-default)}:host .nav-selector__content .entry.folder+.entry:not(.folder){padding-top:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder){padding-left:var(--ref-spacing-xxs);padding-right:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder):first-child{padding-top:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder):last-child{padding-bottom:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder):has(+.entry.folder){padding-bottom:var(--ref-spacing-xxs)}:host .nav-selector__content .entry:not(.folder)+.entry.folder{border-top:1px solid var(--sys-border-color-default)}:host .nav-selector__content .no-result{display:flex;padding:var(--ref-spacing-sm);flex-direction:column;align-items:flex-start;flex:1 0 0;align-self:stretch;color:var(--ref-color-grey-80);font-family:Averta;font-size:var(--ref-font-size-sm);font-style:italic;font-weight:400;line-height:var(--ref-font-line-height-sm)}:host .nav-selector__footer{display:flex;flex-direction:column;align-items:flex-start;gap:var(--ref-spacing-xxs);align-self:stretch;border-top:1px solid var(--sys-border-color-default);background:var(--ref-color-white)}:host.minified{width:64px}:host.minified nav{width:64px}:host.minified nav .nav-selector__header{align-items:center}:host.minified nav .nav-selector__header .expand-button{animation-name:none;border-radius:var(--ref-border-radius-sm);border:1px solid var(--ref-color-grey-20);background:var(--ref-color-grey-bg)}:host.minified nav .nav-selector__content{width:64px}:host.minified nav .nav-selector__content .entry{padding:var(--ref-spacing-xxxs)}\n"] }]
3297
3435
  }], ctorParameters: () => [], propDecorators: { navSelectorEntries: [{ type: i0.Input, args: [{ isSignal: true, alias: "navSelectorEntries", required: true }] }], translatedTexts: [{ type: i0.Input, args: [{ isSignal: true, alias: "translatedTexts", required: true }] }], multipleModeEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "multipleModeEnabled", required: false }] }], style: [{ type: i0.Input, args: [{ isSignal: true, alias: "style", required: false }] }], detailsDisplayedLimit: [{ type: i0.Input, args: [{ isSignal: true, alias: "detailsDisplayedLimit", required: false }] }], embedded: [{ type: i0.Input, args: [{ isSignal: true, alias: "embedded", required: false }] }], forceExpanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "forceExpanded", required: false }] }], expandedStateLocalStorageKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandedStateLocalStorageKey", required: false }] }], selectedEntryUids: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedEntryUids", required: true }] }, { type: i0.Output, args: ["selectedEntryUidsChange"] }], actionClicked: [{ type: i0.Output, args: ["actionClicked"] }], emptyStateActionClicked: [{ type: i0.Output, args: ["emptyStateActionClicked"] }], headerProjection: [{ type: i0.ContentChild, args: ['header', { isSignal: true }] }], contentHeaderProjection: [{ type: i0.ContentChild, args: ['contentHeader', { isSignal: true }] }], footerProjection: [{ type: i0.ContentChild, args: ['footer', { isSignal: true }] }], onExpansionStateChange: [{ type: i0.Output, args: ["onExpansionStateChange"] }], visibleAccountsChange: [{ type: i0.Output, args: ["visibleAccountsChange"] }] } });
3298
3436
 
3299
3437
  /**