@sinequa/atomic-angular 2.11.0 → 2.12.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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from "@angular/core";
2
- import { ChangeDetectionStrategy, ChangeDetectorRef, Component, DOCUMENT, DestroyRef, Directive, ElementRef, EnvironmentInjector, HostBinding, HostListener, Inject, Injectable, InjectionToken, Injector, LOCALE_ID, Optional, Pipe, Service, TemplateRef, ViewEncapsulation, afterNextRender, afterRenderEffect, assertInInjectionContext, booleanAttribute, computed, contentChild, contentChildren, effect, inject, input, isDevMode, linkedSignal, makeEnvironmentProviders, model, numberAttribute, output, provideEnvironmentInitializer, resource, runInInjectionContext, signal, untracked, viewChild, viewChildren } from "@angular/core";
2
+ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, DOCUMENT, DestroyRef, Directive, ElementRef, EnvironmentInjector, HostBinding, HostListener, Inject, Injectable, InjectionToken, Injector, LOCALE_ID, Optional, Pipe, Service, TemplateRef, ViewContainerRef, ViewEncapsulation, afterNextRender, afterRenderEffect, assertInInjectionContext, booleanAttribute, computed, contentChild, contentChildren, effect, inject, input, isDevMode, linkedSignal, makeEnvironmentProviders, model, numberAttribute, output, provideEnvironmentInitializer, resource, runInInjectionContext, signal, untracked, viewChild, viewChildren } from "@angular/core";
3
3
  import { BehaviorSubject, EMPTY, Subject, Subscription, catchError, debounceTime, filter, firstValueFrom, from, fromEvent, map, of, scan, shareReplay, switchMap, tap, throwError } from "rxjs";
4
4
  import { TranslocoPipe, TranslocoService, provideTranslocoScope } from "@jsverse/transloco";
5
5
  import { ArrowDownIcon, ArrowDownZaIcon, ArrowLeftIcon, ArrowRightFromBracketIcon, ArrowRightIcon, ArrowUpAzIcon, ArrowUpIcon, ArrowUpRightFromSquareIcon, ArrowsMaximizeIcon, AutocompleteComponent, AvatarComponent, AvatarFallbackComponent, AvatarImageComponent, BadgeComponent, BarsIcon, BellIcon, BellSlashIcon, BookmarkIcon, BreakpointObserverService, BuildingIcon, ButtonComponent, CalendarDayIcon, CheckIcon, CheckboxComponent, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronsLeftIcon, ChevronsRightIcon, CircleCheckIcon, ClockIcon, CommentIcon, CommentsIcon, DIALOG_REF, DesktopIcon, DialogBodyComponent, DialogComponent, DialogContentComponent, DialogDescriptionComponent, DialogFooterComponent, DialogHeaderComponent, DialogTitleComponent, DropdownDirective, EditIcon, EllipsisIcon, EllipsisVerticalIcon, EyeIcon, EyeSlashIcon, FileHTMLIcon, FileIcon, FileOutputIcon, FileSpreadsheetIcon, FileTextIcon, FilterIcon, FlagEnglishIcon, FlagFrenchIcon, FlagGermanIcon, FlashlightIcon, FolderIcon, FolderOpenIcon, FrownIcon, GearIcon, GitForkIcon, GlobeIcon, GripVerticalIcon, HighlighterIcon, HistoryIcon, HomeIcon, ImageIcon, InboxIcon, InfoCircleIcon, InputComponent, InputControlDirective, InputIconRightDirective, KbdComponent, KbdGroupComponent, KeyIcon, KeyboardIcon, LanguageIcon, LightbulbIcon, LightbulbSlashIcon, LinkComponent, ListComponent, ListItemActionComponent, ListItemAvatarDirective, ListItemComponent, ListItemIconDirective, ListItemLeftDirective, ListItemTextComponent, LoadingCircleIcon, LockIcon, MagnifyingGlassIcon, MagnifyingGlassMinusIcon, MagnifyingGlassPlusIcon, MapPinIcon, MenuComponent, MenuContentComponent, MenuItemComponent, MenuTriggerDirective, MoonIcon, PaletteIcon, PaperclipIcon, PenToSquareIcon, PlusIcon, PopoverDirective, PopoverResizeHandleComponent, PresentationIcon, QuestionCircleIcon, QuickFilterIcon, RadioComponent, RobotIcon, SaveIcon, SearchBarComponent, SearchBarSuggestionsComponent, SearchIcon, SearchInputComponent, SelectComponent, SelectTriggerDirective, SendIcon, SheetBodyComponent, SheetComponent, SheetHeaderComponent, SidebarInsetDirective, SlashIcon, SlidersIcon, SortableDirective, SortableItemDirective, SparklesIcon, SpinnerIcon, SquareCheckIcon, SquareIcon, SquareMinusIcon, StarIcon, SunBrightIcon, SwitchComponent, SyncIcon, TabComponent, TabListComponent, TabPanelComponent, TabsComponent, TagComponent, TagIcon, TagInputComponent, TagsIcon, TextareaComponent, TextareaControlDirective, ThumbsDownIcon, ThumbsUpIcon, ToggleComponent, ToggleGroupComponent, ToggleItemComponent, ToggleLeftIcon, ToggleRightIcon, TooltipDirective, TrashCanIcon, TrashIcon, TreeComponent, TreeItemComponent, TreeItemExpanderComponent, TreeItemGroupComponent, TriangleAlertIcon, TruncatedDirective, UndoIcon, UserIcon, UserSecretIcon, VideoIcon, XMarkIcon, createCallable, injectCallRef, injectFloatingPanel, isApplePlatform } from "@sinequa/galactik";
@@ -23101,6 +23101,8 @@ var SearchFeedbackComponent = class SearchFeedbackComponent {
23101
23101
  injector = inject(Injector);
23102
23102
  pages = input.required(...ngDevMode ? [{ debugName: "pages" }] : /* istanbul ignore next */ []);
23103
23103
  variant = input("secondary", ...ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []);
23104
+ size = input("md", ...ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []);
23105
+ dismissible = input(true, ...ngDevMode ? [{ debugName: "dismissible" }] : /* istanbul ignore next */ []);
23104
23106
  auditService = inject(AuditService);
23105
23107
  queryParamsStore = inject(QueryParamsStore);
23106
23108
  transloco = inject(TranslocoService);
@@ -23220,12 +23222,26 @@ var SearchFeedbackComponent = class SearchFeedbackComponent {
23220
23222
  isSignal: true,
23221
23223
  isRequired: false,
23222
23224
  transformFunction: null
23225
+ },
23226
+ size: {
23227
+ classPropertyName: "size",
23228
+ publicName: "size",
23229
+ isSignal: true,
23230
+ isRequired: false,
23231
+ transformFunction: null
23232
+ },
23233
+ dismissible: {
23234
+ classPropertyName: "dismissible",
23235
+ publicName: "dismissible",
23236
+ isSignal: true,
23237
+ isRequired: false,
23238
+ transformFunction: null
23223
23239
  }
23224
23240
  },
23225
23241
  outputs: { onClose: "onClose" },
23226
23242
  providers: [provideTranslocoScope("feedback")],
23227
23243
  ngImport: i0,
23228
- template: "@if (showButton()) {\n @let feedback = \"feedback.label\" | transloco;\n <button\n [menuTrigger]=\"feedbackMenu\"\n [variant]=\"variant()\"\n [aria-label]=\"feedback\">\n <comment-icon />\n <span>{{ feedback }}</span>\n <x-mark-icon class=\"ms-2\" (click)=\"close($event)\" />\n </button>\n\n <menu #feedbackMenu=\"menu\" (itemSelected)=\"onMenuItemSelected($event)\">\n <MenuContent>\n @if (showLike() && !disliked()) {\n @let feedbackLike = \"feedback.like\" | transloco;\n @let feedbackLiked = \"feedback.liked\" | transloco;\n <MenuItem value=\"like\" aria-label=\"feedback\">\n @if (liked()) {\n <thumbs-up-icon [solid]=\"true\" />\n {{ feedbackLiked }}\n } @else {\n <thumbs-up-icon />\n {{ feedbackLike }}\n }\n </MenuItem>\n }\n @if (showDislike() && !liked()) {\n <MenuItem value=\"dislike\" [aria-label]=\"'feedback.dislike' | transloco\">\n @if (disliked()) {\n <thumbs-down-icon [solid]=\"true\" />\n {{ \"feedback.disliked\" | transloco }}\n } @else {\n <thumbs-down-icon />\n {{ \"feedback.dislike\" | transloco }}\n }\n </MenuItem>\n }\n @for (menu of visibleMenus(); track menu.type) {\n @let feedbackTitle = \"feedback.\" + menu.type + \".title\" | transloco;\n <MenuItem [value]=\"menu.type\" [aria-label]=\"feedbackTitle\">\n <fa-icon [faClass]=\"menu.icon\" />\n {{ feedbackTitle }}\n </MenuItem>\n }\n </MenuContent>\n </menu>\n}\n",
23244
+ template: "@if (showButton()) {\n @let feedback = \"feedback.label\" | transloco;\n <button\n [menuTrigger]=\"feedbackMenu\"\n [variant]=\"variant()\"\n [size]=\"size()\"\n [aria-label]=\"feedback\">\n <comment-icon />\n <span>{{ feedback }}</span>\n @if (dismissible()) {\n <x-mark-icon class=\"ms-2\" (click)=\"close($event)\" />\n }\n </button>\n\n <menu #feedbackMenu=\"menu\" (itemSelected)=\"onMenuItemSelected($event)\">\n <MenuContent>\n @if (showLike() && !disliked()) {\n @let feedbackLike = \"feedback.like\" | transloco;\n @let feedbackLiked = \"feedback.liked\" | transloco;\n <MenuItem value=\"like\" aria-label=\"feedback\">\n @if (liked()) {\n <thumbs-up-icon [solid]=\"true\" />\n {{ feedbackLiked }}\n } @else {\n <thumbs-up-icon />\n {{ feedbackLike }}\n }\n </MenuItem>\n }\n @if (showDislike() && !liked()) {\n <MenuItem value=\"dislike\" [aria-label]=\"'feedback.dislike' | transloco\">\n @if (disliked()) {\n <thumbs-down-icon [solid]=\"true\" />\n {{ \"feedback.disliked\" | transloco }}\n } @else {\n <thumbs-down-icon />\n {{ \"feedback.dislike\" | transloco }}\n }\n </MenuItem>\n }\n @for (menu of visibleMenus(); track menu.type) {\n @let feedbackTitle = \"feedback.\" + menu.type + \".title\" | transloco;\n <MenuItem [value]=\"menu.type\" [aria-label]=\"feedbackTitle\">\n <fa-icon [faClass]=\"menu.icon\" />\n {{ feedbackTitle }}\n </MenuItem>\n }\n </MenuContent>\n </menu>\n}\n",
23229
23245
  dependencies: [
23230
23246
  {
23231
23247
  kind: "directive",
@@ -23332,7 +23348,7 @@ i0.ɵɵngDeclareClassMetadata({
23332
23348
  A11yModule
23333
23349
  ],
23334
23350
  providers: [provideTranslocoScope("feedback")],
23335
- template: "@if (showButton()) {\n @let feedback = \"feedback.label\" | transloco;\n <button\n [menuTrigger]=\"feedbackMenu\"\n [variant]=\"variant()\"\n [aria-label]=\"feedback\">\n <comment-icon />\n <span>{{ feedback }}</span>\n <x-mark-icon class=\"ms-2\" (click)=\"close($event)\" />\n </button>\n\n <menu #feedbackMenu=\"menu\" (itemSelected)=\"onMenuItemSelected($event)\">\n <MenuContent>\n @if (showLike() && !disliked()) {\n @let feedbackLike = \"feedback.like\" | transloco;\n @let feedbackLiked = \"feedback.liked\" | transloco;\n <MenuItem value=\"like\" aria-label=\"feedback\">\n @if (liked()) {\n <thumbs-up-icon [solid]=\"true\" />\n {{ feedbackLiked }}\n } @else {\n <thumbs-up-icon />\n {{ feedbackLike }}\n }\n </MenuItem>\n }\n @if (showDislike() && !liked()) {\n <MenuItem value=\"dislike\" [aria-label]=\"'feedback.dislike' | transloco\">\n @if (disliked()) {\n <thumbs-down-icon [solid]=\"true\" />\n {{ \"feedback.disliked\" | transloco }}\n } @else {\n <thumbs-down-icon />\n {{ \"feedback.dislike\" | transloco }}\n }\n </MenuItem>\n }\n @for (menu of visibleMenus(); track menu.type) {\n @let feedbackTitle = \"feedback.\" + menu.type + \".title\" | transloco;\n <MenuItem [value]=\"menu.type\" [aria-label]=\"feedbackTitle\">\n <fa-icon [faClass]=\"menu.icon\" />\n {{ feedbackTitle }}\n </MenuItem>\n }\n </MenuContent>\n </menu>\n}\n"
23351
+ template: "@if (showButton()) {\n @let feedback = \"feedback.label\" | transloco;\n <button\n [menuTrigger]=\"feedbackMenu\"\n [variant]=\"variant()\"\n [size]=\"size()\"\n [aria-label]=\"feedback\">\n <comment-icon />\n <span>{{ feedback }}</span>\n @if (dismissible()) {\n <x-mark-icon class=\"ms-2\" (click)=\"close($event)\" />\n }\n </button>\n\n <menu #feedbackMenu=\"menu\" (itemSelected)=\"onMenuItemSelected($event)\">\n <MenuContent>\n @if (showLike() && !disliked()) {\n @let feedbackLike = \"feedback.like\" | transloco;\n @let feedbackLiked = \"feedback.liked\" | transloco;\n <MenuItem value=\"like\" aria-label=\"feedback\">\n @if (liked()) {\n <thumbs-up-icon [solid]=\"true\" />\n {{ feedbackLiked }}\n } @else {\n <thumbs-up-icon />\n {{ feedbackLike }}\n }\n </MenuItem>\n }\n @if (showDislike() && !liked()) {\n <MenuItem value=\"dislike\" [aria-label]=\"'feedback.dislike' | transloco\">\n @if (disliked()) {\n <thumbs-down-icon [solid]=\"true\" />\n {{ \"feedback.disliked\" | transloco }}\n } @else {\n <thumbs-down-icon />\n {{ \"feedback.dislike\" | transloco }}\n }\n </MenuItem>\n }\n @for (menu of visibleMenus(); track menu.type) {\n @let feedbackTitle = \"feedback.\" + menu.type + \".title\" | transloco;\n <MenuItem [value]=\"menu.type\" [aria-label]=\"feedbackTitle\">\n <fa-icon [faClass]=\"menu.icon\" />\n {{ feedbackTitle }}\n </MenuItem>\n }\n </MenuContent>\n </menu>\n}\n"
23336
23352
  }]
23337
23353
  }],
23338
23354
  propDecorators: {
@@ -23355,6 +23371,22 @@ i0.ɵɵngDeclareClassMetadata({
23355
23371
  alias: "variant",
23356
23372
  required: false
23357
23373
  }]
23374
+ }],
23375
+ size: [{
23376
+ type: i0.Input,
23377
+ args: [{
23378
+ isSignal: true,
23379
+ alias: "size",
23380
+ required: false
23381
+ }]
23382
+ }],
23383
+ dismissible: [{
23384
+ type: i0.Input,
23385
+ args: [{
23386
+ isSignal: true,
23387
+ alias: "dismissible",
23388
+ required: false
23389
+ }]
23358
23390
  }]
23359
23391
  }
23360
23392
  });
@@ -25125,7 +25157,7 @@ var AggregationPanelComponent = class AggregationPanelComponent {
25125
25157
  isSignal: true
25126
25158
  }],
25127
25159
  ngImport: i0,
25128
- template: "<!-- `<details>`/`<summary>` stay native (open/close, the `name`-based exclusive accordion): a facet is\n a disclosure, not a grid row. They used to sit in an `@angular/aria` grid so ArrowUp/ArrowDown could\n jump from one facet header to the next, but a grid without headers reads as a layout table\n (RGAA 5.3). The `<summary>` itself is `tabindex=\"-1\"`: Tab walks the header's chevron, never the header row, and the\n chevron is the keyboard way to collapse. Select all, clear and apply are not in the header: they are in the body, in a\n bar under the search field. Label, header actions (the count and the chevron) and body are `<ng-template>`s: `<ng-content select=\"…\">` can only be\n declared once, and the body is projected content. -->\n\n<ng-template #searchToggleSlot>\n <button\n #searchToggle\n type=\"button\"\n variant=\"tertiary\"\n [iconOnly]=\"true\"\n size=\"sm\"\n class=\"shrink-0 cursor-pointer\"\n [attr.aria-expanded]=\"showSearch()\"\n [attr.aria-controls]=\"searchId\"\n [tooltip]=\"\n 'filters.searchInFacet'\n | transloco: { facet: (aggregation()?.display | syslang | transloco) }\n \"\n (click)=\"toggleSearch($event)\">\n <search-icon class=\"shrink-0\" />\n <span class=\"sr-only\">{{\n \"filters.searchInFacet\"\n | transloco: { facet: (aggregation()?.display | syslang | transloco) }\n }}</span>\n </button>\n</ng-template>\n\n<ng-template #labelSlot>\n <ng-content select=\"label\">\n @let icon = aggregation()?.icon;\n @if (icon) {\n <FaIcon [faClass]=\"icon\" class=\"mr-1 shrink-0\" />\n }\n <span class=\"grow truncate\">{{\n aggregation()?.display | syslang | transloco\n }}</span>\n </ng-content>\n</ng-template>\n\n<ng-template #headerActionsSlot>\n @if (showFiltersCount() && filtersCount() > 0) {\n <Badge variant=\"number\" fill=\"primary\" scheme=\"sage\" size=\"xs\" class=\"ml-1\">\n {{ filtersCount() }}\n </Badge>\n }\n @if (canSearch() && !isCollapsed()) {\n <!-- The magnifier opens the search field of the facet (and closes it): the field is not on screen until then. It is\n in the header, next to the chevron, and only while the facet is open — there is nothing to search in a closed\n one. Interactive content in a summary does not toggle the details by itself, and the click is stopped anyway. -->\n <ng-container [ngTemplateOutlet]=\"searchToggleSlot\" />\n }\n @if (collapsible()) {\n <!-- The `<summary>` is out of the tab order (`tabindex=\"-1\"`), so this button is the keyboard way to\n collapse the facet. Its click bubbles to the `<summary>`, whose handler does the toggle, and it\n exposes `aria-expanded`. -->\n <button\n type=\"button\"\n variant=\"tertiary\"\n [iconOnly]=\"true\"\n size=\"sm\"\n [attr.aria-expanded]=\"!isCollapsed()\"\n [tooltip]=\"'filters.toggle' | transloco\"\n class=\"shrink-0 cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\n <chevron-right class=\"shrink-0\" />\n <span class=\"sr-only\">{{ \"filters.toggle\" | transloco }}</span>\n </button>\n }\n</ng-template>\n\n<ng-template #bodySlot>\n <div class=\"flex min-h-0 flex-1 flex-col\">\n @if (canSearch()) {\n <!-- The field is always in the DOM and folded to nothing until it is asked for: a grid row that goes from 0fr to 1fr is\n the one height animation that needs no measuring. `inert` takes the folded field out of the tab order and of the\n accessibility tree. The margins live in the inner box: a padding on the folded element itself would keep it\n from reaching zero.\n\n No `hotkey`: this field is one of many facet search boxes on the page, so it must not advertise a global shortcut.\n A placeholder is not a label (RGAA 11.1): the name says WHICH facet this box filters — the one thing that tells a\n dozen identical fields apart. SearchInput hands its class to its inner field, so a margin on it would count twice,\n which is one more reason for the padding on the box around it. -->\n <div\n [id]=\"searchId\"\n class=\"grid shrink-0 transition-[grid-template-rows,opacity] duration-200 ease-[cubic-bezier(0.32,0.72,0,1)] motion-reduce:transition-none\"\n [class]=\"\n showSearch()\n ? 'grid-rows-[1fr] opacity-100'\n : 'grid-rows-[0fr] opacity-0'\n \"\n [inert]=\"!showSearch()\">\n <!-- `-mx-1 px-1`: the box clips what is outside it, and the focus ring of the field is drawn outside the field,\n so it needs a few pixels of room on each side — taken back by the negative margin so nothing moves. -->\n <div class=\"-mx-1 min-h-0 overflow-hidden px-1\">\n <div [class]=\"headless() ? 'pt-0.5 pb-1' : 'pt-2 pb-1'\">\n <SearchInput\n [placeholder]=\"'search' | transloco\"\n [clearLabel]=\"'filters.clearSearch' | transloco\"\n [aria-label]=\"\n 'filters.searchInFacet'\n | transloco\n : { facet: (aggregation()?.display | syslang | transloco) }\n \"\n [(value)]=\"searchText\"\n (keydown.escape)=\"onSearchEscape($event)\">\n <ng-content select=\"[search-addon]\" />\n </SearchInput>\n </div>\n </div>\n </div>\n }\n\n @if (itemsLength() > 0 || hasFilters() || selection()) {\n <!-- The bar under the search field, in a popover and in the filters drawer alike: select all (the count of selected items in its tooltip), then clear and apply. Clear is a button\n with a text, not an icon, and stays in place (disabled) when there is nothing to clear. Apply only shows once\n something is pending, as it always did, and sits at the same level. The checkbox keeps its own name: the text\n beside it is a count, not the label of what it does. -->\n <div class=\"mb-1 flex shrink-0 items-center gap-1 pl-1.5\">\n <!-- How many are selected is in the tooltip of the checkbox, not written beside it: that room is what clear and apply need.\n Screen readers keep it as text (the tooltip only shows on hover and focus, and describes). -->\n <span\n class=\"inline-flex shrink-0\"\n [tooltip]=\"\n 'filters.selectedCount' | transloco: { count: selectedCount() }\n \"\n tooltipPosition=\"bottom\">\n <checkbox\n [checked]=\"isAllSelected()\"\n [indeterminate]=\"selectedCount() > 0 && !isAllSelected()\"\n [aria-label]=\"'filters.selectAllFilters' | transloco\"\n (checkedChange)=\"\n $event ? allSelected.emit() : allUnselected.emit()\n \" />\n </span>\n <span class=\"sr-only\" aria-live=\"polite\">{{\n \"filters.selectedCount\" | transloco: { count: selectedCount() }\n }}</span>\n <span class=\"flex-1\" aria-hidden=\"true\"></span>\n @if (headless() && canSearch()) {\n <ng-container [ngTemplateOutlet]=\"searchToggleSlot\" />\n }\n <button\n type=\"button\"\n variant=\"tertiary\"\n size=\"sm\"\n class=\"shrink-0\"\n [disabled]=\"!hasFilters() && selectedCount() === 0\"\n [attr.aria-label]=\"'filters.clearFilters' | transloco\"\n (click)=\"cleared.emit()\">\n {{ \"filters.clearAll\" | transloco }}\n </button>\n @if (selection()) {\n <!-- No icon: the room is short, and the word says it. -->\n <button\n type=\"button\"\n variant=\"accent\"\n size=\"sm\"\n class=\"shrink-0 overflow-hidden\"\n (click)=\"applied.emit()\">\n <span class=\"truncate\">{{ \"filters.apply\" | transloco }}</span>\n </button>\n }\n </div>\n }\n\n <ng-content />\n\n @if (hasMore() && searchedItemsLength() === 0) {\n <button\n type=\"button\"\n class=\"mt-1 flex w-full shrink-0 justify-center\"\n [attr.aria-label]=\"'loadMore' | transloco\"\n (click)=\"loadedMore.emit()\">\n {{ \"loadMore\" | transloco }}\n </button>\n }\n </div>\n</ng-template>\n\n@if (headless()) {\n <div class=\"flex min-h-0 flex-1 flex-col p-0.5\">\n <ng-container [ngTemplateOutlet]=\"bodySlot\" />\n </div>\n} @else {\n <details\n [attr.open]=\"expanded()\"\n [attr.name]=\"id()\"\n class=\"group flex min-h-0 flex-1 flex-col p-0.5 details-content:flex details-content:min-h-0 details-content:flex-col\"\n (toggle)=\"onToggle($event)\">\n <summary\n tabindex=\"-1\"\n [class.cursor-pointer]=\"collapsible() && !isEmpty()\"\n [class]=\"\n (isEmpty() ? 'text-(--font-neutral-muted) ' : '') + rowStateClass\n \"\n class=\"m-0 flex h-8 w-full shrink-0 scroll-mt-16 scroll-mb-3 items-center gap-1 pl-1 font-semibold select-none\"\n (click)=\"onHeaderClick($event)\">\n <ng-container [ngTemplateOutlet]=\"labelSlot\" />\n <ng-container [ngTemplateOutlet]=\"headerActionsSlot\" />\n </summary>\n <ng-container [ngTemplateOutlet]=\"bodySlot\" />\n </details>\n}\n",
25160
+ template: "<!-- `<details>`/`<summary>` stay native (open/close, the `name`-based exclusive accordion): a facet is\n a disclosure, not a grid row. They used to sit in an `@angular/aria` grid so ArrowUp/ArrowDown could\n jump from one facet header to the next, but a grid without headers reads as a layout table\n (RGAA 5.3). The `<summary>` itself is `tabindex=\"-1\"`: Tab walks the header's chevron, never the header row, and the\n chevron is the keyboard way to collapse. Select all, clear and apply are not in the header: they are in the body, in a\n bar under the search field. Label, header actions (the count and the chevron) and body are `<ng-template>`s: `<ng-content select=\"…\">` can only be\n declared once, and the body is projected content. -->\n\n<ng-template #searchToggleSlot>\n <button\n #searchToggle\n type=\"button\"\n variant=\"tertiary\"\n [iconOnly]=\"true\"\n size=\"sm\"\n class=\"shrink-0 cursor-pointer\"\n [attr.aria-expanded]=\"showSearch()\"\n [attr.aria-controls]=\"searchId\"\n [tooltip]=\"\n 'filters.searchInFacet'\n | transloco: { facet: (aggregation()?.display | syslang | transloco) }\n \"\n (click)=\"toggleSearch($event)\">\n <search-icon class=\"shrink-0\" />\n <span class=\"sr-only\">{{\n \"filters.searchInFacet\"\n | transloco: { facet: (aggregation()?.display | syslang | transloco) }\n }}</span>\n </button>\n</ng-template>\n\n<ng-template #labelSlot>\n <ng-content select=\"label\">\n @let icon = aggregation()?.icon;\n @if (icon) {\n <FaIcon [faClass]=\"icon\" class=\"mr-1 shrink-0\" />\n }\n <span class=\"grow truncate\">{{\n aggregation()?.display | syslang | transloco\n }}</span>\n </ng-content>\n</ng-template>\n\n<ng-template #headerActionsSlot>\n @if (showFiltersCount() && filtersCount() > 0) {\n <Badge variant=\"number\" fill=\"primary\" scheme=\"sage\" size=\"xs\" class=\"ml-1\">\n {{ filtersCount() }}\n </Badge>\n }\n @if (canSearch() && !isCollapsed()) {\n <!-- The magnifier opens the search field of the facet (and closes it): the field is not on screen until then. It is\n in the header, next to the chevron, and only while the facet is open — there is nothing to search in a closed\n one. Interactive content in a summary does not toggle the details by itself, and the click is stopped anyway. -->\n <ng-container [ngTemplateOutlet]=\"searchToggleSlot\" />\n }\n @if (collapsible()) {\n <!-- The `<summary>` is out of the tab order (`tabindex=\"-1\"`), so this button is the keyboard way to\n collapse the facet. Its click bubbles to the `<summary>`, whose handler does the toggle, and it\n exposes `aria-expanded`. -->\n <button\n type=\"button\"\n variant=\"tertiary\"\n [iconOnly]=\"true\"\n size=\"sm\"\n [attr.aria-expanded]=\"!isCollapsed()\"\n [tooltip]=\"'filters.toggle' | transloco\"\n class=\"shrink-0 cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\n <chevron-right class=\"shrink-0\" />\n <span class=\"sr-only\">{{ \"filters.toggle\" | transloco }}</span>\n </button>\n }\n</ng-template>\n\n<ng-template #bodySlot>\n <div class=\"flex min-h-0 flex-1 flex-col\">\n @if (canSearch()) {\n <!-- The field is always in the DOM and folded to nothing until it is asked for: a grid row that goes from 0fr to 1fr is\n the one height animation that needs no measuring. `inert` takes the folded field out of the tab order and of the\n accessibility tree. The margins live in the inner box: a padding on the folded element itself would keep it\n from reaching zero.\n\n No `hotkey`: this field is one of many facet search boxes on the page, so it must not advertise a global shortcut.\n A placeholder is not a label (RGAA 11.1): the name says WHICH facet this box filters — the one thing that tells a\n dozen identical fields apart. SearchInput hands its class to its inner field, so a margin on it would count twice,\n which is one more reason for the padding on the box around it. -->\n <div\n [id]=\"searchId\"\n class=\"grid shrink-0 transition-[grid-template-rows,opacity] duration-200 ease-[cubic-bezier(0.32,0.72,0,1)] motion-reduce:transition-none\"\n [class]=\"\n showSearch()\n ? 'grid-rows-[1fr] opacity-100'\n : 'grid-rows-[0fr] opacity-0'\n \"\n [inert]=\"!showSearch()\">\n <!-- `-mx-1 px-1`: the box clips what is outside it, and the focus ring of the field is drawn outside the field,\n so it needs a few pixels of room on each side — taken back by the negative margin so nothing moves. -->\n <div class=\"-mx-1 min-h-0 overflow-hidden px-1\">\n <div [class]=\"headless() ? 'pt-0.5 pb-1' : 'pt-2 pb-1'\">\n <SearchInput\n [placeholder]=\"'search' | transloco\"\n [clearLabel]=\"'filters.clearSearch' | transloco\"\n [aria-label]=\"\n 'filters.searchInFacet'\n | transloco\n : { facet: (aggregation()?.display | syslang | transloco) }\n \"\n [(value)]=\"searchText\"\n (keydown.escape)=\"onSearchEscape($event)\">\n <ng-content select=\"[search-addon]\" />\n </SearchInput>\n </div>\n </div>\n </div>\n }\n\n @if (itemsLength() > 0 || hasFilters() || selection()) {\n <!-- The bar under the search field, in a popover and in the filters drawer alike: clear and apply, and nothing else, so\n both keep their full text in the little room there is. Clear is a button with a text, not an icon, and stays in\n place (disabled) when there is nothing to clear. Apply only shows once something is pending, as it always did, and\n sits at the same level. -->\n <div\n data-bar=\"actions\"\n class=\"mb-1 flex shrink-0 items-center justify-end gap-1\">\n @if (headless() && canSearch()) {\n <ng-container [ngTemplateOutlet]=\"searchToggleSlot\" />\n }\n <button\n type=\"button\"\n variant=\"tertiary\"\n size=\"sm\"\n class=\"shrink-0\"\n [disabled]=\"!hasFilters() && selectedCount() === 0\"\n [attr.aria-label]=\"'filters.clearFilters' | transloco\"\n (click)=\"cleared.emit()\">\n {{ \"filters.clearAll\" | transloco }}\n </button>\n @if (selection()) {\n <!-- No icon: the room is short, and the word says it. -->\n <button\n type=\"button\"\n variant=\"accent\"\n size=\"sm\"\n class=\"shrink-0 overflow-hidden\"\n (click)=\"applied.emit()\">\n <span class=\"truncate\">{{ \"filters.apply\" | transloco }}</span>\n </button>\n }\n </div>\n }\n\n @if (itemsLength() > 0) {\n <!-- Select all is the first row of the list, written like one: the box lines up with the boxes of the items it drives and\n carries its own text, which a bare box next to two buttons never did. The whole row is the label, so it is as easy\n to hit as an item. The count of checked items is part of that same label (\"Select all (3)\"), so the two can never\n overlap: when the room is short the label is cut with an ellipsis as a whole. It stays out of the scroller of the list, so it does not scroll away with the items. -->\n <div\n data-bar=\"select-all\"\n class=\"mb-1 flex shrink-0 items-center pr-3 pl-1.5 text-sm\">\n <checkbox\n class=\"min-w-0 flex-1 items-center py-1 [&_.checkbox-label]:truncate [&_.checkbox-text-block]:min-w-0\"\n [checked]=\"isAllSelected()\"\n [indeterminate]=\"selectedCount() > 0 && !isAllSelected()\"\n (checkedChange)=\"$event ? allSelected.emit() : allUnselected.emit()\">\n {{\n (isAllSelected() ? \"filters.unselectAll\" : \"filters.selectAll\")\n | transloco\n }}\n @if (selectedCount() > 0) {\n <span class=\"text-(--font-primary-muted)\"\n >({{ selectedCount() }})</span\n >\n }\n </checkbox>\n <span class=\"sr-only\" aria-live=\"polite\">{{\n \"filters.selectedCount\" | transloco: { count: selectedCount() }\n }}</span>\n </div>\n }\n\n <ng-content />\n\n @if (hasMore() && searchedItemsLength() === 0) {\n <button\n type=\"button\"\n class=\"mt-1 flex w-full shrink-0 justify-center\"\n [attr.aria-label]=\"'loadMore' | transloco\"\n (click)=\"loadedMore.emit()\">\n {{ \"loadMore\" | transloco }}\n </button>\n }\n </div>\n</ng-template>\n\n@if (headless()) {\n <div class=\"flex min-h-0 flex-1 flex-col p-0.5\">\n <ng-container [ngTemplateOutlet]=\"bodySlot\" />\n </div>\n} @else {\n <details\n [attr.open]=\"expanded()\"\n [attr.name]=\"id()\"\n class=\"group flex min-h-0 flex-1 flex-col p-0.5 details-content:flex details-content:min-h-0 details-content:flex-col\"\n (toggle)=\"onToggle($event)\">\n <summary\n tabindex=\"-1\"\n [class.cursor-pointer]=\"collapsible() && !isEmpty()\"\n [class]=\"\n (isEmpty() ? 'text-(--font-neutral-muted) ' : '') + rowStateClass\n \"\n class=\"m-0 flex h-8 w-full shrink-0 scroll-mt-16 scroll-mb-3 items-center gap-1 pl-1 font-semibold select-none\"\n (click)=\"onHeaderClick($event)\">\n <ng-container [ngTemplateOutlet]=\"labelSlot\" />\n <ng-container [ngTemplateOutlet]=\"headerActionsSlot\" />\n </summary>\n <ng-container [ngTemplateOutlet]=\"bodySlot\" />\n </details>\n}\n",
25129
25161
  styles: [":host{interpolate-size:allow-keywords}details::details-content{flex:1 1 auto;block-size:0;overflow:clip;overflow-clip-margin:.25rem;transition:block-size .2s cubic-bezier(.32,.72,0,1),content-visibility .2s allow-discrete}details[open]::details-content{block-size:auto}@media(prefers-reduced-motion:reduce){details::details-content{transition:none}}\n"],
25130
25162
  dependencies: [
25131
25163
  {
@@ -25263,7 +25295,7 @@ i0.ɵɵngDeclareClassMetadata({
25263
25295
  ],
25264
25296
  providers: [provideTranslocoScope("filters")],
25265
25297
  host: { class: "flex min-h-0 flex-1 flex-col" },
25266
- template: "<!-- `<details>`/`<summary>` stay native (open/close, the `name`-based exclusive accordion): a facet is\n a disclosure, not a grid row. They used to sit in an `@angular/aria` grid so ArrowUp/ArrowDown could\n jump from one facet header to the next, but a grid without headers reads as a layout table\n (RGAA 5.3). The `<summary>` itself is `tabindex=\"-1\"`: Tab walks the header's chevron, never the header row, and the\n chevron is the keyboard way to collapse. Select all, clear and apply are not in the header: they are in the body, in a\n bar under the search field. Label, header actions (the count and the chevron) and body are `<ng-template>`s: `<ng-content select=\"…\">` can only be\n declared once, and the body is projected content. -->\n\n<ng-template #searchToggleSlot>\n <button\n #searchToggle\n type=\"button\"\n variant=\"tertiary\"\n [iconOnly]=\"true\"\n size=\"sm\"\n class=\"shrink-0 cursor-pointer\"\n [attr.aria-expanded]=\"showSearch()\"\n [attr.aria-controls]=\"searchId\"\n [tooltip]=\"\n 'filters.searchInFacet'\n | transloco: { facet: (aggregation()?.display | syslang | transloco) }\n \"\n (click)=\"toggleSearch($event)\">\n <search-icon class=\"shrink-0\" />\n <span class=\"sr-only\">{{\n \"filters.searchInFacet\"\n | transloco: { facet: (aggregation()?.display | syslang | transloco) }\n }}</span>\n </button>\n</ng-template>\n\n<ng-template #labelSlot>\n <ng-content select=\"label\">\n @let icon = aggregation()?.icon;\n @if (icon) {\n <FaIcon [faClass]=\"icon\" class=\"mr-1 shrink-0\" />\n }\n <span class=\"grow truncate\">{{\n aggregation()?.display | syslang | transloco\n }}</span>\n </ng-content>\n</ng-template>\n\n<ng-template #headerActionsSlot>\n @if (showFiltersCount() && filtersCount() > 0) {\n <Badge variant=\"number\" fill=\"primary\" scheme=\"sage\" size=\"xs\" class=\"ml-1\">\n {{ filtersCount() }}\n </Badge>\n }\n @if (canSearch() && !isCollapsed()) {\n <!-- The magnifier opens the search field of the facet (and closes it): the field is not on screen until then. It is\n in the header, next to the chevron, and only while the facet is open — there is nothing to search in a closed\n one. Interactive content in a summary does not toggle the details by itself, and the click is stopped anyway. -->\n <ng-container [ngTemplateOutlet]=\"searchToggleSlot\" />\n }\n @if (collapsible()) {\n <!-- The `<summary>` is out of the tab order (`tabindex=\"-1\"`), so this button is the keyboard way to\n collapse the facet. Its click bubbles to the `<summary>`, whose handler does the toggle, and it\n exposes `aria-expanded`. -->\n <button\n type=\"button\"\n variant=\"tertiary\"\n [iconOnly]=\"true\"\n size=\"sm\"\n [attr.aria-expanded]=\"!isCollapsed()\"\n [tooltip]=\"'filters.toggle' | transloco\"\n class=\"shrink-0 cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\n <chevron-right class=\"shrink-0\" />\n <span class=\"sr-only\">{{ \"filters.toggle\" | transloco }}</span>\n </button>\n }\n</ng-template>\n\n<ng-template #bodySlot>\n <div class=\"flex min-h-0 flex-1 flex-col\">\n @if (canSearch()) {\n <!-- The field is always in the DOM and folded to nothing until it is asked for: a grid row that goes from 0fr to 1fr is\n the one height animation that needs no measuring. `inert` takes the folded field out of the tab order and of the\n accessibility tree. The margins live in the inner box: a padding on the folded element itself would keep it\n from reaching zero.\n\n No `hotkey`: this field is one of many facet search boxes on the page, so it must not advertise a global shortcut.\n A placeholder is not a label (RGAA 11.1): the name says WHICH facet this box filters — the one thing that tells a\n dozen identical fields apart. SearchInput hands its class to its inner field, so a margin on it would count twice,\n which is one more reason for the padding on the box around it. -->\n <div\n [id]=\"searchId\"\n class=\"grid shrink-0 transition-[grid-template-rows,opacity] duration-200 ease-[cubic-bezier(0.32,0.72,0,1)] motion-reduce:transition-none\"\n [class]=\"\n showSearch()\n ? 'grid-rows-[1fr] opacity-100'\n : 'grid-rows-[0fr] opacity-0'\n \"\n [inert]=\"!showSearch()\">\n <!-- `-mx-1 px-1`: the box clips what is outside it, and the focus ring of the field is drawn outside the field,\n so it needs a few pixels of room on each side — taken back by the negative margin so nothing moves. -->\n <div class=\"-mx-1 min-h-0 overflow-hidden px-1\">\n <div [class]=\"headless() ? 'pt-0.5 pb-1' : 'pt-2 pb-1'\">\n <SearchInput\n [placeholder]=\"'search' | transloco\"\n [clearLabel]=\"'filters.clearSearch' | transloco\"\n [aria-label]=\"\n 'filters.searchInFacet'\n | transloco\n : { facet: (aggregation()?.display | syslang | transloco) }\n \"\n [(value)]=\"searchText\"\n (keydown.escape)=\"onSearchEscape($event)\">\n <ng-content select=\"[search-addon]\" />\n </SearchInput>\n </div>\n </div>\n </div>\n }\n\n @if (itemsLength() > 0 || hasFilters() || selection()) {\n <!-- The bar under the search field, in a popover and in the filters drawer alike: select all (the count of selected items in its tooltip), then clear and apply. Clear is a button\n with a text, not an icon, and stays in place (disabled) when there is nothing to clear. Apply only shows once\n something is pending, as it always did, and sits at the same level. The checkbox keeps its own name: the text\n beside it is a count, not the label of what it does. -->\n <div class=\"mb-1 flex shrink-0 items-center gap-1 pl-1.5\">\n <!-- How many are selected is in the tooltip of the checkbox, not written beside it: that room is what clear and apply need.\n Screen readers keep it as text (the tooltip only shows on hover and focus, and describes). -->\n <span\n class=\"inline-flex shrink-0\"\n [tooltip]=\"\n 'filters.selectedCount' | transloco: { count: selectedCount() }\n \"\n tooltipPosition=\"bottom\">\n <checkbox\n [checked]=\"isAllSelected()\"\n [indeterminate]=\"selectedCount() > 0 && !isAllSelected()\"\n [aria-label]=\"'filters.selectAllFilters' | transloco\"\n (checkedChange)=\"\n $event ? allSelected.emit() : allUnselected.emit()\n \" />\n </span>\n <span class=\"sr-only\" aria-live=\"polite\">{{\n \"filters.selectedCount\" | transloco: { count: selectedCount() }\n }}</span>\n <span class=\"flex-1\" aria-hidden=\"true\"></span>\n @if (headless() && canSearch()) {\n <ng-container [ngTemplateOutlet]=\"searchToggleSlot\" />\n }\n <button\n type=\"button\"\n variant=\"tertiary\"\n size=\"sm\"\n class=\"shrink-0\"\n [disabled]=\"!hasFilters() && selectedCount() === 0\"\n [attr.aria-label]=\"'filters.clearFilters' | transloco\"\n (click)=\"cleared.emit()\">\n {{ \"filters.clearAll\" | transloco }}\n </button>\n @if (selection()) {\n <!-- No icon: the room is short, and the word says it. -->\n <button\n type=\"button\"\n variant=\"accent\"\n size=\"sm\"\n class=\"shrink-0 overflow-hidden\"\n (click)=\"applied.emit()\">\n <span class=\"truncate\">{{ \"filters.apply\" | transloco }}</span>\n </button>\n }\n </div>\n }\n\n <ng-content />\n\n @if (hasMore() && searchedItemsLength() === 0) {\n <button\n type=\"button\"\n class=\"mt-1 flex w-full shrink-0 justify-center\"\n [attr.aria-label]=\"'loadMore' | transloco\"\n (click)=\"loadedMore.emit()\">\n {{ \"loadMore\" | transloco }}\n </button>\n }\n </div>\n</ng-template>\n\n@if (headless()) {\n <div class=\"flex min-h-0 flex-1 flex-col p-0.5\">\n <ng-container [ngTemplateOutlet]=\"bodySlot\" />\n </div>\n} @else {\n <details\n [attr.open]=\"expanded()\"\n [attr.name]=\"id()\"\n class=\"group flex min-h-0 flex-1 flex-col p-0.5 details-content:flex details-content:min-h-0 details-content:flex-col\"\n (toggle)=\"onToggle($event)\">\n <summary\n tabindex=\"-1\"\n [class.cursor-pointer]=\"collapsible() && !isEmpty()\"\n [class]=\"\n (isEmpty() ? 'text-(--font-neutral-muted) ' : '') + rowStateClass\n \"\n class=\"m-0 flex h-8 w-full shrink-0 scroll-mt-16 scroll-mb-3 items-center gap-1 pl-1 font-semibold select-none\"\n (click)=\"onHeaderClick($event)\">\n <ng-container [ngTemplateOutlet]=\"labelSlot\" />\n <ng-container [ngTemplateOutlet]=\"headerActionsSlot\" />\n </summary>\n <ng-container [ngTemplateOutlet]=\"bodySlot\" />\n </details>\n}\n",
25298
+ template: "<!-- `<details>`/`<summary>` stay native (open/close, the `name`-based exclusive accordion): a facet is\n a disclosure, not a grid row. They used to sit in an `@angular/aria` grid so ArrowUp/ArrowDown could\n jump from one facet header to the next, but a grid without headers reads as a layout table\n (RGAA 5.3). The `<summary>` itself is `tabindex=\"-1\"`: Tab walks the header's chevron, never the header row, and the\n chevron is the keyboard way to collapse. Select all, clear and apply are not in the header: they are in the body, in a\n bar under the search field. Label, header actions (the count and the chevron) and body are `<ng-template>`s: `<ng-content select=\"…\">` can only be\n declared once, and the body is projected content. -->\n\n<ng-template #searchToggleSlot>\n <button\n #searchToggle\n type=\"button\"\n variant=\"tertiary\"\n [iconOnly]=\"true\"\n size=\"sm\"\n class=\"shrink-0 cursor-pointer\"\n [attr.aria-expanded]=\"showSearch()\"\n [attr.aria-controls]=\"searchId\"\n [tooltip]=\"\n 'filters.searchInFacet'\n | transloco: { facet: (aggregation()?.display | syslang | transloco) }\n \"\n (click)=\"toggleSearch($event)\">\n <search-icon class=\"shrink-0\" />\n <span class=\"sr-only\">{{\n \"filters.searchInFacet\"\n | transloco: { facet: (aggregation()?.display | syslang | transloco) }\n }}</span>\n </button>\n</ng-template>\n\n<ng-template #labelSlot>\n <ng-content select=\"label\">\n @let icon = aggregation()?.icon;\n @if (icon) {\n <FaIcon [faClass]=\"icon\" class=\"mr-1 shrink-0\" />\n }\n <span class=\"grow truncate\">{{\n aggregation()?.display | syslang | transloco\n }}</span>\n </ng-content>\n</ng-template>\n\n<ng-template #headerActionsSlot>\n @if (showFiltersCount() && filtersCount() > 0) {\n <Badge variant=\"number\" fill=\"primary\" scheme=\"sage\" size=\"xs\" class=\"ml-1\">\n {{ filtersCount() }}\n </Badge>\n }\n @if (canSearch() && !isCollapsed()) {\n <!-- The magnifier opens the search field of the facet (and closes it): the field is not on screen until then. It is\n in the header, next to the chevron, and only while the facet is open — there is nothing to search in a closed\n one. Interactive content in a summary does not toggle the details by itself, and the click is stopped anyway. -->\n <ng-container [ngTemplateOutlet]=\"searchToggleSlot\" />\n }\n @if (collapsible()) {\n <!-- The `<summary>` is out of the tab order (`tabindex=\"-1\"`), so this button is the keyboard way to\n collapse the facet. Its click bubbles to the `<summary>`, whose handler does the toggle, and it\n exposes `aria-expanded`. -->\n <button\n type=\"button\"\n variant=\"tertiary\"\n [iconOnly]=\"true\"\n size=\"sm\"\n [attr.aria-expanded]=\"!isCollapsed()\"\n [tooltip]=\"'filters.toggle' | transloco\"\n class=\"shrink-0 cursor-pointer [&_svg]:transition-transform [&_svg]:duration-150 group-open:[&_svg]:rotate-90\">\n <chevron-right class=\"shrink-0\" />\n <span class=\"sr-only\">{{ \"filters.toggle\" | transloco }}</span>\n </button>\n }\n</ng-template>\n\n<ng-template #bodySlot>\n <div class=\"flex min-h-0 flex-1 flex-col\">\n @if (canSearch()) {\n <!-- The field is always in the DOM and folded to nothing until it is asked for: a grid row that goes from 0fr to 1fr is\n the one height animation that needs no measuring. `inert` takes the folded field out of the tab order and of the\n accessibility tree. The margins live in the inner box: a padding on the folded element itself would keep it\n from reaching zero.\n\n No `hotkey`: this field is one of many facet search boxes on the page, so it must not advertise a global shortcut.\n A placeholder is not a label (RGAA 11.1): the name says WHICH facet this box filters — the one thing that tells a\n dozen identical fields apart. SearchInput hands its class to its inner field, so a margin on it would count twice,\n which is one more reason for the padding on the box around it. -->\n <div\n [id]=\"searchId\"\n class=\"grid shrink-0 transition-[grid-template-rows,opacity] duration-200 ease-[cubic-bezier(0.32,0.72,0,1)] motion-reduce:transition-none\"\n [class]=\"\n showSearch()\n ? 'grid-rows-[1fr] opacity-100'\n : 'grid-rows-[0fr] opacity-0'\n \"\n [inert]=\"!showSearch()\">\n <!-- `-mx-1 px-1`: the box clips what is outside it, and the focus ring of the field is drawn outside the field,\n so it needs a few pixels of room on each side — taken back by the negative margin so nothing moves. -->\n <div class=\"-mx-1 min-h-0 overflow-hidden px-1\">\n <div [class]=\"headless() ? 'pt-0.5 pb-1' : 'pt-2 pb-1'\">\n <SearchInput\n [placeholder]=\"'search' | transloco\"\n [clearLabel]=\"'filters.clearSearch' | transloco\"\n [aria-label]=\"\n 'filters.searchInFacet'\n | transloco\n : { facet: (aggregation()?.display | syslang | transloco) }\n \"\n [(value)]=\"searchText\"\n (keydown.escape)=\"onSearchEscape($event)\">\n <ng-content select=\"[search-addon]\" />\n </SearchInput>\n </div>\n </div>\n </div>\n }\n\n @if (itemsLength() > 0 || hasFilters() || selection()) {\n <!-- The bar under the search field, in a popover and in the filters drawer alike: clear and apply, and nothing else, so\n both keep their full text in the little room there is. Clear is a button with a text, not an icon, and stays in\n place (disabled) when there is nothing to clear. Apply only shows once something is pending, as it always did, and\n sits at the same level. -->\n <div\n data-bar=\"actions\"\n class=\"mb-1 flex shrink-0 items-center justify-end gap-1\">\n @if (headless() && canSearch()) {\n <ng-container [ngTemplateOutlet]=\"searchToggleSlot\" />\n }\n <button\n type=\"button\"\n variant=\"tertiary\"\n size=\"sm\"\n class=\"shrink-0\"\n [disabled]=\"!hasFilters() && selectedCount() === 0\"\n [attr.aria-label]=\"'filters.clearFilters' | transloco\"\n (click)=\"cleared.emit()\">\n {{ \"filters.clearAll\" | transloco }}\n </button>\n @if (selection()) {\n <!-- No icon: the room is short, and the word says it. -->\n <button\n type=\"button\"\n variant=\"accent\"\n size=\"sm\"\n class=\"shrink-0 overflow-hidden\"\n (click)=\"applied.emit()\">\n <span class=\"truncate\">{{ \"filters.apply\" | transloco }}</span>\n </button>\n }\n </div>\n }\n\n @if (itemsLength() > 0) {\n <!-- Select all is the first row of the list, written like one: the box lines up with the boxes of the items it drives and\n carries its own text, which a bare box next to two buttons never did. The whole row is the label, so it is as easy\n to hit as an item. The count of checked items is part of that same label (\"Select all (3)\"), so the two can never\n overlap: when the room is short the label is cut with an ellipsis as a whole. It stays out of the scroller of the list, so it does not scroll away with the items. -->\n <div\n data-bar=\"select-all\"\n class=\"mb-1 flex shrink-0 items-center pr-3 pl-1.5 text-sm\">\n <checkbox\n class=\"min-w-0 flex-1 items-center py-1 [&_.checkbox-label]:truncate [&_.checkbox-text-block]:min-w-0\"\n [checked]=\"isAllSelected()\"\n [indeterminate]=\"selectedCount() > 0 && !isAllSelected()\"\n (checkedChange)=\"$event ? allSelected.emit() : allUnselected.emit()\">\n {{\n (isAllSelected() ? \"filters.unselectAll\" : \"filters.selectAll\")\n | transloco\n }}\n @if (selectedCount() > 0) {\n <span class=\"text-(--font-primary-muted)\"\n >({{ selectedCount() }})</span\n >\n }\n </checkbox>\n <span class=\"sr-only\" aria-live=\"polite\">{{\n \"filters.selectedCount\" | transloco: { count: selectedCount() }\n }}</span>\n </div>\n }\n\n <ng-content />\n\n @if (hasMore() && searchedItemsLength() === 0) {\n <button\n type=\"button\"\n class=\"mt-1 flex w-full shrink-0 justify-center\"\n [attr.aria-label]=\"'loadMore' | transloco\"\n (click)=\"loadedMore.emit()\">\n {{ \"loadMore\" | transloco }}\n </button>\n }\n </div>\n</ng-template>\n\n@if (headless()) {\n <div class=\"flex min-h-0 flex-1 flex-col p-0.5\">\n <ng-container [ngTemplateOutlet]=\"bodySlot\" />\n </div>\n} @else {\n <details\n [attr.open]=\"expanded()\"\n [attr.name]=\"id()\"\n class=\"group flex min-h-0 flex-1 flex-col p-0.5 details-content:flex details-content:min-h-0 details-content:flex-col\"\n (toggle)=\"onToggle($event)\">\n <summary\n tabindex=\"-1\"\n [class.cursor-pointer]=\"collapsible() && !isEmpty()\"\n [class]=\"\n (isEmpty() ? 'text-(--font-neutral-muted) ' : '') + rowStateClass\n \"\n class=\"m-0 flex h-8 w-full shrink-0 scroll-mt-16 scroll-mb-3 items-center gap-1 pl-1 font-semibold select-none\"\n (click)=\"onHeaderClick($event)\">\n <ng-container [ngTemplateOutlet]=\"labelSlot\" />\n <ng-container [ngTemplateOutlet]=\"headerActionsSlot\" />\n </summary>\n <ng-container [ngTemplateOutlet]=\"bodySlot\" />\n </details>\n}\n",
25267
25299
  styles: [":host{interpolate-size:allow-keywords}details::details-content{flex:1 1 auto;block-size:0;overflow:clip;overflow-clip-margin:.25rem;transition:block-size .2s cubic-bezier(.32,.72,0,1),content-visibility .2s allow-discrete}details[open]::details-content{block-size:auto}@media(prefers-reduced-motion:reduce){details::details-content{transition:none}}\n"]
25268
25300
  }]
25269
25301
  }],
@@ -35043,6 +35075,115 @@ i0.ɵɵngDeclareClassMetadata({
35043
35075
  }]
35044
35076
  }
35045
35077
  });
35078
+ var PopupContentOutlet = class PopupContentOutlet {
35079
+ container = inject(ViewContainerRef);
35080
+ injector = inject(Injector);
35081
+ popupContentOutlet = input.required(...ngDevMode ? [{ debugName: "popupContentOutlet" }] : /* istanbul ignore next */ []);
35082
+ popupContentContext = input.required(...ngDevMode ? [{ debugName: "popupContentContext" }] : /* istanbul ignore next */ []);
35083
+ constructor() {
35084
+ effect(() => {
35085
+ const template = this.popupContentOutlet();
35086
+ const context = this.popupContentContext();
35087
+ untracked(() => {
35088
+ this.container.clear();
35089
+ this.container.createEmbeddedView(template, context, { injector: this.injector });
35090
+ });
35091
+ });
35092
+ }
35093
+ static ɵfac = i0.ɵɵngDeclareFactory({
35094
+ minVersion: "12.0.0",
35095
+ version: "22.2.1",
35096
+ ngImport: i0,
35097
+ type: PopupContentOutlet,
35098
+ deps: [],
35099
+ target: i0.ɵɵFactoryTarget.Directive
35100
+ });
35101
+ static ɵdir = i0.ɵɵngDeclareDirective({
35102
+ minVersion: "17.1.0",
35103
+ version: "22.2.1",
35104
+ type: PopupContentOutlet,
35105
+ isStandalone: true,
35106
+ selector: "[popupContentOutlet]",
35107
+ inputs: {
35108
+ popupContentOutlet: {
35109
+ classPropertyName: "popupContentOutlet",
35110
+ publicName: "popupContentOutlet",
35111
+ isSignal: true,
35112
+ isRequired: true,
35113
+ transformFunction: null
35114
+ },
35115
+ popupContentContext: {
35116
+ classPropertyName: "popupContentContext",
35117
+ publicName: "popupContentContext",
35118
+ isSignal: true,
35119
+ isRequired: true,
35120
+ transformFunction: null
35121
+ }
35122
+ },
35123
+ ngImport: i0
35124
+ });
35125
+ };
35126
+ i0.ɵɵngDeclareClassMetadata({
35127
+ minVersion: "12.0.0",
35128
+ version: "22.2.1",
35129
+ ngImport: i0,
35130
+ type: PopupContentOutlet,
35131
+ decorators: [{
35132
+ type: Directive,
35133
+ args: [{ selector: "[popupContentOutlet]" }]
35134
+ }],
35135
+ ctorParameters: () => [],
35136
+ propDecorators: {
35137
+ popupContentOutlet: [{
35138
+ type: i0.Input,
35139
+ args: [{
35140
+ isSignal: true,
35141
+ alias: "popupContentOutlet",
35142
+ required: true
35143
+ }]
35144
+ }],
35145
+ popupContentContext: [{
35146
+ type: i0.Input,
35147
+ args: [{
35148
+ isSignal: true,
35149
+ alias: "popupContentContext",
35150
+ required: true
35151
+ }]
35152
+ }]
35153
+ }
35154
+ });
35155
+ var SearchBoxPopupDirective = class SearchBoxPopupDirective {
35156
+ template = inject(TemplateRef);
35157
+ static ngTemplateContextGuard(_dir, _ctx) {
35158
+ return true;
35159
+ }
35160
+ static ɵfac = i0.ɵɵngDeclareFactory({
35161
+ minVersion: "12.0.0",
35162
+ version: "22.2.1",
35163
+ ngImport: i0,
35164
+ type: SearchBoxPopupDirective,
35165
+ deps: [],
35166
+ target: i0.ɵɵFactoryTarget.Directive
35167
+ });
35168
+ static ɵdir = i0.ɵɵngDeclareDirective({
35169
+ minVersion: "14.0.0",
35170
+ version: "22.2.1",
35171
+ type: SearchBoxPopupDirective,
35172
+ isStandalone: true,
35173
+ selector: "ng-template[searchBoxPopup]",
35174
+ ngImport: i0
35175
+ });
35176
+ };
35177
+ i0.ɵɵngDeclareClassMetadata({
35178
+ minVersion: "12.0.0",
35179
+ version: "22.2.1",
35180
+ ngImport: i0,
35181
+ type: SearchBoxPopupDirective,
35182
+ decorators: [{
35183
+ type: Directive,
35184
+ args: [{ selector: "ng-template[searchBoxPopup]" }]
35185
+ }]
35186
+ });
35046
35187
  let nextHintId = 0;
35047
35188
  const SEARCH_BOX_CATEGORIES_SORT = new InjectionToken("Order by preference for the categories of the suggestions", { factory: () => [
35048
35189
  "full-text",
@@ -35076,10 +35217,20 @@ var SearchBoxComponent = class SearchBoxComponent {
35076
35217
  ...ngDevMode ? { debugName: "popupOffset" } : /* istanbul ignore next */ {},
35077
35218
  transform: numberAttribute
35078
35219
  });
35220
+ popupFitScreen = input(void 0, {
35221
+ ...ngDevMode ? { debugName: "popupFitScreen" } : /* istanbul ignore next */ {},
35222
+ transform: (value) => value === void 0 ? void 0 : booleanAttribute(value)
35223
+ });
35224
+ popupFlip = input(void 0, {
35225
+ ...ngDevMode ? { debugName: "popupFlip" } : /* istanbul ignore next */ {},
35226
+ transform: (value) => value === void 0 ? void 0 : booleanAttribute(value)
35227
+ });
35079
35228
  placeholderOverride = input(void 0, {
35080
35229
  ...ngDevMode ? { debugName: "placeholderOverride" } : /* istanbul ignore next */ {},
35081
35230
  alias: "placeholder"
35082
35231
  });
35232
+ suggestionsProvider = input(void 0, ...ngDevMode ? [{ debugName: "suggestionsProvider" }] : /* istanbul ignore next */ []);
35233
+ customPopup = contentChild(SearchBoxPopupDirective, ...ngDevMode ? [{ debugName: "customPopup" }] : /* istanbul ignore next */ []);
35083
35234
  searched = output();
35084
35235
  debounced = output();
35085
35236
  saved = output();
@@ -35121,9 +35272,12 @@ var SearchBoxComponent = class SearchBoxComponent {
35121
35272
  savedSearches = computed(() => this.userSettingsStore.savedSearches() ?? [], ...ngDevMode ? [{ debugName: "savedSearches" }] : /* istanbul ignore next */ []);
35122
35273
  savedTexts = computed(() => new Set(this.savedSearches().map((s) => s.display || s.label)), ...ngDevMode ? [{ debugName: "savedTexts" }] : /* istanbul ignore next */ []);
35123
35274
  inline = computed(() => this.popup() === "inline", ...ngDevMode ? [{ debugName: "inline" }] : /* istanbul ignore next */ []);
35275
+ fitScreen = computed(() => this.popupFitScreen() ?? (this.inline() && this.size() === "hero"), ...ngDevMode ? [{ debugName: "fitScreen" }] : /* istanbul ignore next */ []);
35276
+ flip = computed(() => this.popupFlip() ?? this.size() !== "hero", ...ngDevMode ? [{ debugName: "flip" }] : /* istanbul ignore next */ []);
35277
+ floating = computed(() => !this.inline() || this.fitScreen(), ...ngDevMode ? [{ debugName: "floating" }] : /* istanbul ignore next */ []);
35124
35278
  barClass = computed(() => this.size() === "hero" ? "w-full" : "w-full gap-(--spacing-3xs)! pe-(--spacing-3xs)", ...ngDevMode ? [{ debugName: "barClass" }] : /* istanbul ignore next */ []);
35125
- popupClass = computed(() => cn("flex flex-col transition-[opacity,translate] duration-200 ease-[cubic-bezier(0.32,0.72,0,1)] starting:-translate-y-1.5 starting:opacity-0 motion-reduce:transition-none", this.inline() ? "absolute inset-x-0 top-full z-20 mx-auto mt-(--spacing-2xs) w-[calc(100%-74px)] gap-(--spacing-3xs)" : "fixed z-20 gap-(--spacing-2xs) overflow-hidden rounded-(--radius-xl) border border-solid border-(--stroke-neutral-white) bg-(--bg-neutral-white) p-(--spacing-xs) shadow-(--shadow-2)"), ...ngDevMode ? [{ debugName: "popupClass" }] : /* istanbul ignore next */ []);
35126
- listClass = computed(() => cn("h-68 scroll-pt-8 overflow-auto overscroll-contain text-(--font-primary-base) focus-visible:outline-2 focus-visible:outline-solid focus-visible:-outline-offset-2 focus-visible:outline-(--stroke-focus)", this.inline() ? "bg-transparent" : "bg-(--bg-neutral-white)"), ...ngDevMode ? [{ debugName: "listClass" }] : /* istanbul ignore next */ []);
35279
+ popupClass = computed(() => cn("flex flex-col transition-[opacity,translate] duration-200 ease-[cubic-bezier(0.32,0.72,0,1)] starting:-translate-y-1.5 starting:opacity-0 motion-reduce:transition-none", this.inline() ? this.fitScreen() ? "fixed z-20 max-h-(--search-box-max-h) w-[calc(var(--search-box-w,100vw)-74px)] gap-(--spacing-3xs)" : "absolute inset-x-0 top-full z-20 mx-auto mt-(--spacing-2xs) w-[calc(100%-74px)] gap-(--spacing-3xs)" : "fixed z-20 gap-(--spacing-2xs) overflow-hidden rounded-(--radius-xl) border border-solid border-(--stroke-neutral-white) bg-(--bg-neutral-white) p-(--spacing-xs) shadow-(--shadow-2)", !this.inline() && this.fitScreen() && "max-h-(--search-box-max-h)"), ...ngDevMode ? [{ debugName: "popupClass" }] : /* istanbul ignore next */ []);
35280
+ listClass = computed(() => cn("h-68 scroll-pt-8 overflow-auto overscroll-contain text-(--font-primary-base) focus-visible:outline-2 focus-visible:outline-solid focus-visible:-outline-offset-2 focus-visible:outline-(--stroke-focus)", this.fitScreen() && "min-h-0 shrink", this.inline() ? "bg-transparent" : "bg-(--bg-neutral-white)"), ...ngDevMode ? [{ debugName: "listClass" }] : /* istanbul ignore next */ []);
35127
35281
  rowClass = computed(() => cn("group/row data-list-item flex min-h-9 w-full cursor-pointer items-center gap-(--spacing-2xs) rounded-(--radius-sm) px-(--spacing-2xs) py-(--spacing-3xs) text-left text-(length:--size-base) text-(--font-primary-muted) transition-[background-color] duration-100 ease-[ease] hover:bg-(--bg-primary-lighter) hover:outline-none focus-visible:bg-(--bg-primary-lighter) aria-selected:text-(--font-primary-dark) data-[active=true]:bg-(--bg-primary-lighter) motion-reduce:transition-none"), ...ngDevMode ? [{ debugName: "rowClass" }] : /* istanbul ignore next */ []);
35128
35282
  titleClass = computed(() => cn("sticky top-0 px-(--spacing-2xs) pt-(--spacing-xs) pb-(--spacing-3xs) text-(length:--size-xs) font-semibold tracking-wider text-(--font-primary-muted) uppercase", this.inline() ? "bg-(--layer-page-layer,var(--bg-neutral-base))" : "bg-(--bg-neutral-white)"), ...ngDevMode ? [{ debugName: "titleClass" }] : /* istanbul ignore next */ []);
35129
35283
  hasFilters = computed(() => {
@@ -35142,9 +35296,10 @@ var SearchBoxComponent = class SearchBoxComponent {
35142
35296
  params: () => ({
35143
35297
  text: this.text(),
35144
35298
  wasSearchClicked: this.wasSearchClicked(),
35145
- autocomplete: this.autocomplete()
35299
+ autocomplete: this.autocomplete(),
35300
+ provider: this.suggestionsProvider()
35146
35301
  }),
35147
- loader: async ({ params: { text, autocomplete } }) => this.fetchSuggestions({
35302
+ loader: async ({ params: { text, autocomplete, provider } }) => provider ? this.fetchFromProvider(provider, text) : this.fetchSuggestions({
35148
35303
  text,
35149
35304
  autocomplete
35150
35305
  })
@@ -35159,14 +35314,33 @@ var SearchBoxComponent = class SearchBoxComponent {
35159
35314
  }
35160
35315
  return isLoading ? this.previousSuggestions : [];
35161
35316
  }, ...ngDevMode ? [{ debugName: "suggestions" }] : /* istanbul ignore next */ []);
35317
+ popupTemplateContext = { $implicit: {
35318
+ text: this.text,
35319
+ typed: this.typed,
35320
+ suggestions: this.suggestions,
35321
+ loading: this.suggestionsResource.isLoading,
35322
+ savedSearches: this.savedSearches,
35323
+ navigatedSinceTyping: this.navigatedSinceTyping,
35324
+ commit: (text) => this.commitText(text),
35325
+ preview: (text) => this.previewSuggestion(text),
35326
+ openSaved: (saved) => this.openSaved(saved),
35327
+ isSaved: (text) => this.savedTexts().has(text),
35328
+ toggleSaved: (text) => this.toggleSavedText(text),
35329
+ collapse: () => this.collapse(),
35330
+ focusField: () => this.focusField()
35331
+ } };
35162
35332
  inputListenersAttached = false;
35163
35333
  constructor() {
35164
35334
  this.destroyRef.onDestroy(() => this.field().reset());
35165
35335
  injectFloatingPanel({
35166
- panel: () => this.inline() ? null : this.popupCard()?.nativeElement,
35336
+ panel: () => this.floating() ? this.popupCard()?.nativeElement : null,
35167
35337
  anchor: () => this.barElement()?.nativeElement,
35168
- offset: () => this.popupOffset(),
35169
- matchAnchorWidth: true
35338
+ placement: () => this.inline() ? "bottom" : "bottom-start",
35339
+ offset: () => this.inline() ? 8 : this.popupOffset(),
35340
+ flip: () => this.flip(),
35341
+ matchAnchorWidth: () => !this.inline(),
35342
+ anchorWidthVariable: "--search-box-w",
35343
+ maxHeightVariable: "--search-box-max-h"
35170
35344
  });
35171
35345
  this.eventManager.addEventListener(this.host.nativeElement, "click", () => this.wasSearchClicked.set(true));
35172
35346
  let firstText = true;
@@ -35213,7 +35387,15 @@ var SearchBoxComponent = class SearchBoxComponent {
35213
35387
  const onInput = () => this.navigatedSinceTyping.set(false);
35214
35388
  element.addEventListener("keydown", onKeydown);
35215
35389
  element.addEventListener("input", onInput);
35390
+ const activeObserver = new MutationObserver(() => {
35391
+ if (this.customPopup()) this.revealActiveOption();
35392
+ });
35393
+ activeObserver.observe(element, {
35394
+ attributes: true,
35395
+ attributeFilter: ["aria-activedescendant"]
35396
+ });
35216
35397
  this.destroyRef.onDestroy(() => {
35398
+ activeObserver.disconnect();
35217
35399
  element.removeEventListener("keydown", onKeydown);
35218
35400
  element.removeEventListener("input", onInput);
35219
35401
  });
@@ -35244,6 +35426,10 @@ var SearchBoxComponent = class SearchBoxComponent {
35244
35426
  if (this.host.nativeElement.contains(next)) return;
35245
35427
  this.collapse();
35246
35428
  }
35429
+ revealActiveOption() {
35430
+ const id = this.inputComponent()?.searchInput().nativeElement.getAttribute("aria-activedescendant");
35431
+ if (id) document.getElementById(id)?.scrollIntoView({ block: "nearest" });
35432
+ }
35247
35433
  collapse() {
35248
35434
  this.combobox()?.expanded.set(false);
35249
35435
  }
@@ -35272,9 +35458,12 @@ var SearchBoxComponent = class SearchBoxComponent {
35272
35458
  commitSuggestion(suggestion, event) {
35273
35459
  if (!suggestion.display) return;
35274
35460
  const text = suggestion.display;
35461
+ this.commitText(text, event.currentTarget?.getAttribute("data-text") || text);
35462
+ }
35463
+ commitText(text, searched = text) {
35275
35464
  this.searchInputText.set(text);
35276
35465
  this.collapse();
35277
- this.runSearch(event.currentTarget?.getAttribute("data-text") || text);
35466
+ this.runSearch(searched);
35278
35467
  }
35279
35468
  openSaved(saved) {
35280
35469
  const queryParams = savedSearchQueryParams(saved);
@@ -35406,6 +35595,14 @@ var SearchBoxComponent = class SearchBoxComponent {
35406
35595
  }
35407
35596
  return category;
35408
35597
  }
35598
+ async fetchFromProvider(provider, text) {
35599
+ try {
35600
+ return await provider(text);
35601
+ } catch (err) {
35602
+ error("Error getting suggestions from the suggestions provider", err);
35603
+ return [];
35604
+ }
35605
+ }
35409
35606
  fetchSuggestions = async ({ text, autocomplete = 3 }) => {
35410
35607
  const fromUserSettings = this.autocompleteService.getFromUserSettingsForText(text, autocomplete);
35411
35608
  if (!text) return fromUserSettings;
@@ -35483,6 +35680,20 @@ var SearchBoxComponent = class SearchBoxComponent {
35483
35680
  isRequired: false,
35484
35681
  transformFunction: null
35485
35682
  },
35683
+ popupFitScreen: {
35684
+ classPropertyName: "popupFitScreen",
35685
+ publicName: "popupFitScreen",
35686
+ isSignal: true,
35687
+ isRequired: false,
35688
+ transformFunction: null
35689
+ },
35690
+ popupFlip: {
35691
+ classPropertyName: "popupFlip",
35692
+ publicName: "popupFlip",
35693
+ isSignal: true,
35694
+ isRequired: false,
35695
+ transformFunction: null
35696
+ },
35486
35697
  placeholderOverride: {
35487
35698
  classPropertyName: "placeholderOverride",
35488
35699
  publicName: "placeholder",
@@ -35490,6 +35701,13 @@ var SearchBoxComponent = class SearchBoxComponent {
35490
35701
  isRequired: false,
35491
35702
  transformFunction: null
35492
35703
  },
35704
+ suggestionsProvider: {
35705
+ classPropertyName: "suggestionsProvider",
35706
+ publicName: "suggestionsProvider",
35707
+ isSignal: true,
35708
+ isRequired: false,
35709
+ transformFunction: null
35710
+ },
35493
35711
  searchInputText: {
35494
35712
  classPropertyName: "searchInputText",
35495
35713
  publicName: "searchInputText",
@@ -35514,6 +35732,13 @@ var SearchBoxComponent = class SearchBoxComponent {
35514
35732
  classAttribute: "relative block"
35515
35733
  },
35516
35734
  providers: [provideTranslocoScope("search-box"), provideTranslocoScope("searches")],
35735
+ queries: [{
35736
+ propertyName: "customPopup",
35737
+ first: true,
35738
+ predicate: SearchBoxPopupDirective,
35739
+ descendants: true,
35740
+ isSignal: true
35741
+ }],
35517
35742
  viewQueries: [
35518
35743
  {
35519
35744
  propertyName: "inputComponent",
@@ -35595,6 +35820,10 @@ var SearchBoxComponent = class SearchBoxComponent {
35595
35820
  page, where it takes the place of the filters) or a floating card (the results header). It fades and slides in
35596
35821
  once, when the popup opens (starting: gives the transition its first frame). -->
35597
35822
  <div #popupCard [class]="popupClass()" (mousedown)="$event.preventDefault()">
35823
+ @if (customPopup(); as custom) {
35824
+ <!-- The application's own content (searchBoxPopup): the card, its placement and its opening stay the search box's. -->
35825
+ <ng-container [popupContentOutlet]="custom.template" [popupContentContext]="popupTemplateContext" />
35826
+ } @else {
35598
35827
  <!-- The tabs hold no panel of their own: only one list exists at a time, since two listboxes would both
35599
35828
  register with the combobox. The div below is the one tabpanel, named by the selected tab. -->
35600
35829
  <Tabs
@@ -35618,7 +35847,9 @@ var SearchBoxComponent = class SearchBoxComponent {
35618
35847
  </TabList>
35619
35848
  </Tabs>
35620
35849
 
35621
- <div role="tabpanel" [attr.aria-label]="(tab() === 'saved' ? 'searchBox.tabs.saved' : 'searchBox.tabs.suggestions') | transloco">
35850
+ <!-- A flex column with min-h-0, so that the list inside can shrink and scroll when the popup is capped (popupFitScreen):
35851
+ a plain block would keep the height of its list as its minimum, and the card would only cut the bottom off. -->
35852
+ <div role="tabpanel" class="flex min-h-0 flex-col" [attr.aria-label]="(tab() === 'saved' ? 'searchBox.tabs.saved' : 'searchBox.tabs.suggestions') | transloco">
35622
35853
  @if (tab() === "saved") {
35623
35854
  <ul
35624
35855
  #savedList
@@ -35649,7 +35880,14 @@ var SearchBoxComponent = class SearchBoxComponent {
35649
35880
  (click)="removeSaved(saved, $event)">
35650
35881
  <star-icon solid class="size-(--icon-sm)" />
35651
35882
  </span>
35652
- <p class="min-w-0 flex-1 truncate text-(--font-primary-base)">{{ saved.display || saved.label }}</p>
35883
+ <p
35884
+ class="min-w-0 flex-1 truncate text-(--font-primary-base)"
35885
+ truncated
35886
+ #cutSaved="truncated"
35887
+ [tooltip]="saved.display || saved.label || ''"
35888
+ [tooltipDisabled]="!cutSaved.isTruncated()">
35889
+ {{ saved.display || saved.label }}
35890
+ </p>
35653
35891
  </li>
35654
35892
  } @empty {
35655
35893
  <!-- The empty-state rule of the list features: the feature's icon on a coloured tile, a title, one hint. -->
@@ -35720,7 +35958,12 @@ var SearchBoxComponent = class SearchBoxComponent {
35720
35958
  </span>
35721
35959
  </span>
35722
35960
 
35723
- <p class="min-w-0 flex-1 truncate text-(--font-primary-base)">
35961
+ <p
35962
+ class="min-w-0 flex-1 truncate text-(--font-primary-base)"
35963
+ truncated
35964
+ #cutSuggest="truncated"
35965
+ [tooltip]="suggest.display ?? ''"
35966
+ [tooltipDisabled]="!cutSuggest.isTruncated()">
35724
35967
  @for (chunk of suggest.display! | highlightWord: text() : 10; track $index) {
35725
35968
  <span [class]="{ 'font-semibold': chunk.match }">{{ chunk.text }}</span>
35726
35969
  }
@@ -35741,6 +35984,7 @@ var SearchBoxComponent = class SearchBoxComponent {
35741
35984
  </ul>
35742
35985
  }
35743
35986
  </div>
35987
+ }
35744
35988
  </div>
35745
35989
  </ng-template>
35746
35990
  }
@@ -35763,6 +36007,12 @@ var SearchBoxComponent = class SearchBoxComponent {
35763
36007
  ],
35764
36008
  exportAs: ["ngComponentOutlet"]
35765
36009
  },
36010
+ {
36011
+ kind: "directive",
36012
+ type: PopupContentOutlet,
36013
+ selector: "[popupContentOutlet]",
36014
+ inputs: ["popupContentOutlet", "popupContentContext"]
36015
+ },
35766
36016
  {
35767
36017
  kind: "directive",
35768
36018
  type: FormField,
@@ -35883,6 +36133,13 @@ var SearchBoxComponent = class SearchBoxComponent {
35883
36133
  ],
35884
36134
  exportAs: ["tooltip"]
35885
36135
  },
36136
+ {
36137
+ kind: "directive",
36138
+ type: TruncatedDirective,
36139
+ selector: "[truncated]",
36140
+ inputs: ["truncated"],
36141
+ exportAs: ["truncated"]
36142
+ },
35886
36143
  {
35887
36144
  kind: "component",
35888
36145
  type: SavedSearchPopover,
@@ -35914,6 +36171,7 @@ i0.ɵɵngDeclareClassMetadata({
35914
36171
  selector: "SearchBox, search-box",
35915
36172
  imports: [
35916
36173
  NgComponentOutlet,
36174
+ PopupContentOutlet,
35917
36175
  FormField,
35918
36176
  FormRoot,
35919
36177
  ComboboxPopup,
@@ -35928,6 +36186,7 @@ i0.ɵɵngDeclareClassMetadata({
35928
36186
  TabListComponent,
35929
36187
  TabComponent,
35930
36188
  TooltipDirective,
36189
+ TruncatedDirective,
35931
36190
  SavedSearchPopover
35932
36191
  ],
35933
36192
  providers: [provideTranslocoScope("search-box"), provideTranslocoScope("searches")],
@@ -35979,6 +36238,10 @@ i0.ɵɵngDeclareClassMetadata({
35979
36238
  page, where it takes the place of the filters) or a floating card (the results header). It fades and slides in
35980
36239
  once, when the popup opens (starting: gives the transition its first frame). -->
35981
36240
  <div #popupCard [class]="popupClass()" (mousedown)="$event.preventDefault()">
36241
+ @if (customPopup(); as custom) {
36242
+ <!-- The application's own content (searchBoxPopup): the card, its placement and its opening stay the search box's. -->
36243
+ <ng-container [popupContentOutlet]="custom.template" [popupContentContext]="popupTemplateContext" />
36244
+ } @else {
35982
36245
  <!-- The tabs hold no panel of their own: only one list exists at a time, since two listboxes would both
35983
36246
  register with the combobox. The div below is the one tabpanel, named by the selected tab. -->
35984
36247
  <Tabs
@@ -36002,7 +36265,9 @@ i0.ɵɵngDeclareClassMetadata({
36002
36265
  </TabList>
36003
36266
  </Tabs>
36004
36267
 
36005
- <div role="tabpanel" [attr.aria-label]="(tab() === 'saved' ? 'searchBox.tabs.saved' : 'searchBox.tabs.suggestions') | transloco">
36268
+ <!-- A flex column with min-h-0, so that the list inside can shrink and scroll when the popup is capped (popupFitScreen):
36269
+ a plain block would keep the height of its list as its minimum, and the card would only cut the bottom off. -->
36270
+ <div role="tabpanel" class="flex min-h-0 flex-col" [attr.aria-label]="(tab() === 'saved' ? 'searchBox.tabs.saved' : 'searchBox.tabs.suggestions') | transloco">
36006
36271
  @if (tab() === "saved") {
36007
36272
  <ul
36008
36273
  #savedList
@@ -36033,7 +36298,14 @@ i0.ɵɵngDeclareClassMetadata({
36033
36298
  (click)="removeSaved(saved, $event)">
36034
36299
  <star-icon solid class="size-(--icon-sm)" />
36035
36300
  </span>
36036
- <p class="min-w-0 flex-1 truncate text-(--font-primary-base)">{{ saved.display || saved.label }}</p>
36301
+ <p
36302
+ class="min-w-0 flex-1 truncate text-(--font-primary-base)"
36303
+ truncated
36304
+ #cutSaved="truncated"
36305
+ [tooltip]="saved.display || saved.label || ''"
36306
+ [tooltipDisabled]="!cutSaved.isTruncated()">
36307
+ {{ saved.display || saved.label }}
36308
+ </p>
36037
36309
  </li>
36038
36310
  } @empty {
36039
36311
  <!-- The empty-state rule of the list features: the feature's icon on a coloured tile, a title, one hint. -->
@@ -36104,7 +36376,12 @@ i0.ɵɵngDeclareClassMetadata({
36104
36376
  </span>
36105
36377
  </span>
36106
36378
 
36107
- <p class="min-w-0 flex-1 truncate text-(--font-primary-base)">
36379
+ <p
36380
+ class="min-w-0 flex-1 truncate text-(--font-primary-base)"
36381
+ truncated
36382
+ #cutSuggest="truncated"
36383
+ [tooltip]="suggest.display ?? ''"
36384
+ [tooltipDisabled]="!cutSuggest.isTruncated()">
36108
36385
  @for (chunk of suggest.display! | highlightWord: text() : 10; track $index) {
36109
36386
  <span [class]="{ 'font-semibold': chunk.match }">{{ chunk.text }}</span>
36110
36387
  }
@@ -36125,6 +36402,7 @@ i0.ɵɵngDeclareClassMetadata({
36125
36402
  </ul>
36126
36403
  }
36127
36404
  </div>
36405
+ }
36128
36406
  </div>
36129
36407
  </ng-template>
36130
36408
  }
@@ -36175,6 +36453,22 @@ i0.ɵɵngDeclareClassMetadata({
36175
36453
  required: false
36176
36454
  }]
36177
36455
  }],
36456
+ popupFitScreen: [{
36457
+ type: i0.Input,
36458
+ args: [{
36459
+ isSignal: true,
36460
+ alias: "popupFitScreen",
36461
+ required: false
36462
+ }]
36463
+ }],
36464
+ popupFlip: [{
36465
+ type: i0.Input,
36466
+ args: [{
36467
+ isSignal: true,
36468
+ alias: "popupFlip",
36469
+ required: false
36470
+ }]
36471
+ }],
36178
36472
  placeholderOverride: [{
36179
36473
  type: i0.Input,
36180
36474
  args: [{
@@ -36183,6 +36477,18 @@ i0.ɵɵngDeclareClassMetadata({
36183
36477
  required: false
36184
36478
  }]
36185
36479
  }],
36480
+ suggestionsProvider: [{
36481
+ type: i0.Input,
36482
+ args: [{
36483
+ isSignal: true,
36484
+ alias: "suggestionsProvider",
36485
+ required: false
36486
+ }]
36487
+ }],
36488
+ customPopup: [{
36489
+ type: i0.ContentChild,
36490
+ args: [i0.forwardRef(() => SearchBoxPopupDirective), { isSignal: true }]
36491
+ }],
36186
36492
  searched: [{
36187
36493
  type: i0.Output,
36188
36494
  args: ["searched"]
@@ -38861,6 +39167,6 @@ function provideSessionExpiry(options = {}) {
38861
39167
  const queryNameResolver = () => {
38862
39168
  return inject(AppStore).getDefaultQuery()?.name || "";
38863
39169
  };
38864
- export { AGGREGATIONS_NAMES, AGGREGATIONS_NAMES_PRESET_DEFAULT, APP_FEATURES, ATOMIC_CLIENT, ATOMIC_SCOPED_PROVIDERS, AddToCollection, AdvancedFiltersBodyComponent, AdvancedFiltersComponent, AdvancedSearch, AdvancedSearchTabs, AggregationComponent, AggregationDateComponent, AggregationDateRange, AggregationItemDirective, AggregationListComponent, AggregationPanelComponent, AggregationTreeComponent, AggregationsService, AggregationsStore, Alert, AlertDialog, AlertForm, AlertFormComponent, AlertsComponent, AppService, AppStore, ApplicationService, ApplicationStore, AppliedFiltersComponent, ArticleEntities, ArticleEntitiesTabPanel, ArticleExtracts, ArticleExtractsTabPanel, ArticleHighlights, ArticleLabels, ArticleLabelsTabPanel, ArticleMatchLocations, ArticleMatchLocationsTabPanel, ArticleSimilarDocuments, ArticleSimilarDocumentsTabPanel, AsideFiltersComponent, AuditFeedbackType, AuditService, AuthGuard, AuthPageComponent, AutocompleteService, BOOKMARKS_CONFIG, BOOKMARKS_OPTIONS, BackdropComponent, BackdropService, BookmarkButtonComponent, BookmarksComponent, COLLECTIONS_CONFIG, COLLECTIONS_OPTIONS, COMPONENTS_FOR_DOCUMENT_TYPE, ChangePasswordComponent, ChildMarkerDirective, CollectionsComponent, CollectionsDialog, ConverterSelectComponent, DeleteCollection, DeleteCollectionDialog, DidYouMeanComponent, DocumentLocatorComponent, EditLabels, ErrorComponent, Export, ExportDialog, ExportService, FILTERS_BREAKPOINT, FILTER_DATE_ALLOW_CUSTOM_RANGE, FORM_ALERT_CLASS, FORM_BARE_CLASS, FORM_ERROR_CLASS, FORM_FIELD_CLASS, FORM_FOOTER_CLASS, FORM_LABEL_CLASS, FORM_SURFACE_CLASS, FaIconComponent, FeatureFlags, FeatureFlagsDialogComponent, Feedback, FeedbackDialogComponent, FileSizePipe, FilterButtonComponent, FiltersBarComponent, FiltersPanelComponent, FloatingToolbarComponent, ForgotPasswordComponent, HIGHLIGHTS, HeatmapComponent, HighlightWordPipe, HistoryPanelComponent, HistoryTitleMarqueeDirective, InfinityScrollDirective, InlineWorker, JsonMethodPluginService, KeyboardShortcutsDialog, KeyboardShortcutsDialogComponent, KeyboardShortcutsListComponent, KeyboardShortcutsService, LabelService, LabelsEditDialog, ListPanelItemDirective, LoadingComponent, LocalizedNumberPipe, MarkdownPipe, MarkdownRendererService, MetadataComponent, MissingTermsComponent, MoreButtonComponent, MoreComponent, MultiSelectLabelsComponent, MultiSelectionToolbarComponent, NON_SEARCHABLE_COLUMNS, NON_SEARCHABLE_DEFAULTS, NavbarTabsComponent, NavigationService, NoResultComponent, OpenArticleOnCtrlEnterDirective, OperatorPipe, OverflowItemDirective, OverflowManagerDirective, OverflowStopDirective, OverrideUser, OverrideUserDialogComponent, PREVIEW_ASSISTANT_COMPONENT, PREVIEW_CONFIG, PagerComponent, PreviewActionsComponent, PreviewContentComponent, PreviewHeaderComponent, PreviewNavigator, PreviewService, PrincipalService, PrincipalStore, QueryParamsStore, QueryService, QuickFiltersComponent, QuickFiltersListComponent, RECENT_SEARCHES_CONFIG, RECENT_SEARCHES_OPTIONS, ROUTE_COMPONENTS, RecentSearchesComponent, ResetUserSettings, ResetUserSettingsDialogComponent, SAVED_SEARCHES_CONFIG, SAVED_SEARCHES_OPTIONS, SEARCH_BOX_CATEGORIES_SORT, SEARCH_BOX_CATEGORY_ICONS, STARTUP_DATA_SOURCE, SavedSearch, SavedSearchDialog, SavedSearchPopover, SavedSearchesComponent, SavedSearchesService, SearchBoxComponent, SearchFeedbackComponent, SearchInputFooter, SearchService, SelectArticleDirective, SelectionService, SelectionStore, Settings, SettingsAccountPanelComponent, SettingsAlertsPanelComponent, SettingsAppearancePanelComponent, SettingsDialogComponent, SettingsShortcutsPanelComponent, ShortcutDirective, ShowBookmarkDirective, SignInComponent, SignedOutComponent, SortSelectorComponent, SourceComponent, SourceIconPipe, SponsoredResultsComponent, SyslangPipe, THEMES, TagCloudComponent, TextChunkService, ThemeProviderDirective, ThemeSelectorComponent, ThemeStore, ThemeToggleComponent, TranslocoDateImpurePipe, UserOverrideService, UserProfileFormComponent, UserProfileService, UserSettingsPersistence, UserSettingsStore, WEIGHT_STEPS, WordCloudComponent, ZoomControlsComponent, __resetSignInMutexForTests, activateShortcutTarget, applyThemeToNativeElement, atomicClientProvider, auditInterceptorFn, authInterceptorFn, bodyInterceptorFn, bootstrapApp, buildHeatmap, buildQuery, buildTagCloud, candidatesFor, canonicalize, debouncedSignal, errorInterceptorFn, fieldErrorKey, fieldShowsError, filterKey, filterLeaves, filterValues, findAggregation, flagsFromWeekdays, focusWhenReady, galactikPrimitive, galactikSemantic, getCurrentPath, getCurrentQueryName, getQueryNameFromRoute, groupSearchesByDate, injectAdvancedFilters, injectAtomicClient, injectRouteNavigation, injectUserSettingsPatch, isAuthRoute, isSignInInFlight, itemLabel, layoutWordCloud, legacyFilterToFilter, makeWeightScale, multiSelectionToolbarVariants, paletteColor, processCssVars, provideAtomicClient, provideAtomicNotifications, provideAtomicScope, provideDocumentLang, provideKeyboardShortcuts, provideSessionExpiry, provideStartupAggregation, quantileScale, queryNameResolver, rebuildWithout, searchItemKey, seriesPalette, signIn, themeColorNameToCssVariable, themeColorsToCssVariables, timelinePalette, toAriaKeyshortcuts, toDisplayParts, toPercentages, toSeries, toastInterceptorFn, weekdaysFromFlags, withAggregationsFeatures, withAlertsFeatures, withAlpha, withAppFeatures, withApplicationFeatures, withAssistantFeatures, withBasketsFeatures, withBookmarkFeatures, withBootstrapApp, withExtractsFeatures, withFavoriteSearchesFeatures, withFetch, withMultiSelectionFeatures, withQueryParamsFeatures, withQuickFiltersFeatures, withRecentSearchesFeatures, withSavedSearchesFeatures, withSelectionFeatures, withThemeBodyHook, withThemes, withThemesFeatures, withUserSettingsFeatures };
39170
+ export { AGGREGATIONS_NAMES, AGGREGATIONS_NAMES_PRESET_DEFAULT, APP_FEATURES, ATOMIC_CLIENT, ATOMIC_SCOPED_PROVIDERS, AddToCollection, AdvancedFiltersBodyComponent, AdvancedFiltersComponent, AdvancedSearch, AdvancedSearchTabs, AggregationComponent, AggregationDateComponent, AggregationDateRange, AggregationItemDirective, AggregationListComponent, AggregationPanelComponent, AggregationTreeComponent, AggregationsService, AggregationsStore, Alert, AlertDialog, AlertForm, AlertFormComponent, AlertsComponent, AppService, AppStore, ApplicationService, ApplicationStore, AppliedFiltersComponent, ArticleEntities, ArticleEntitiesTabPanel, ArticleExtracts, ArticleExtractsTabPanel, ArticleHighlights, ArticleLabels, ArticleLabelsTabPanel, ArticleMatchLocations, ArticleMatchLocationsTabPanel, ArticleSimilarDocuments, ArticleSimilarDocumentsTabPanel, AsideFiltersComponent, AuditFeedbackType, AuditService, AuthGuard, AuthPageComponent, AutocompleteService, BOOKMARKS_CONFIG, BOOKMARKS_OPTIONS, BackdropComponent, BackdropService, BookmarkButtonComponent, BookmarksComponent, COLLECTIONS_CONFIG, COLLECTIONS_OPTIONS, COMPONENTS_FOR_DOCUMENT_TYPE, ChangePasswordComponent, ChildMarkerDirective, CollectionsComponent, CollectionsDialog, ConverterSelectComponent, DeleteCollection, DeleteCollectionDialog, DidYouMeanComponent, DocumentLocatorComponent, EditLabels, ErrorComponent, Export, ExportDialog, ExportService, FILTERS_BREAKPOINT, FILTER_DATE_ALLOW_CUSTOM_RANGE, FORM_ALERT_CLASS, FORM_BARE_CLASS, FORM_ERROR_CLASS, FORM_FIELD_CLASS, FORM_FOOTER_CLASS, FORM_LABEL_CLASS, FORM_SURFACE_CLASS, FaIconComponent, FeatureFlags, FeatureFlagsDialogComponent, Feedback, FeedbackDialogComponent, FileSizePipe, FilterButtonComponent, FiltersBarComponent, FiltersPanelComponent, FloatingToolbarComponent, ForgotPasswordComponent, HIGHLIGHTS, HeatmapComponent, HighlightWordPipe, HistoryPanelComponent, HistoryTitleMarqueeDirective, InfinityScrollDirective, InlineWorker, JsonMethodPluginService, KeyboardShortcutsDialog, KeyboardShortcutsDialogComponent, KeyboardShortcutsListComponent, KeyboardShortcutsService, LabelService, LabelsEditDialog, ListPanelItemDirective, LoadingComponent, LocalizedNumberPipe, MarkdownPipe, MarkdownRendererService, MetadataComponent, MissingTermsComponent, MoreButtonComponent, MoreComponent, MultiSelectLabelsComponent, MultiSelectionToolbarComponent, NON_SEARCHABLE_COLUMNS, NON_SEARCHABLE_DEFAULTS, NavbarTabsComponent, NavigationService, NoResultComponent, OpenArticleOnCtrlEnterDirective, OperatorPipe, OverflowItemDirective, OverflowManagerDirective, OverflowStopDirective, OverrideUser, OverrideUserDialogComponent, PREVIEW_ASSISTANT_COMPONENT, PREVIEW_CONFIG, PagerComponent, PreviewActionsComponent, PreviewContentComponent, PreviewHeaderComponent, PreviewNavigator, PreviewService, PrincipalService, PrincipalStore, QueryParamsStore, QueryService, QuickFiltersComponent, QuickFiltersListComponent, RECENT_SEARCHES_CONFIG, RECENT_SEARCHES_OPTIONS, ROUTE_COMPONENTS, RecentSearchesComponent, ResetUserSettings, ResetUserSettingsDialogComponent, SAVED_SEARCHES_CONFIG, SAVED_SEARCHES_OPTIONS, SEARCH_BOX_CATEGORIES_SORT, SEARCH_BOX_CATEGORY_ICONS, STARTUP_DATA_SOURCE, SavedSearch, SavedSearchDialog, SavedSearchPopover, SavedSearchesComponent, SavedSearchesService, SearchBoxComponent, SearchBoxPopupDirective, SearchFeedbackComponent, SearchInputFooter, SearchService, SelectArticleDirective, SelectionService, SelectionStore, Settings, SettingsAccountPanelComponent, SettingsAlertsPanelComponent, SettingsAppearancePanelComponent, SettingsDialogComponent, SettingsShortcutsPanelComponent, ShortcutDirective, ShowBookmarkDirective, SignInComponent, SignedOutComponent, SortSelectorComponent, SourceComponent, SourceIconPipe, SponsoredResultsComponent, SyslangPipe, THEMES, TagCloudComponent, TextChunkService, ThemeProviderDirective, ThemeSelectorComponent, ThemeStore, ThemeToggleComponent, TranslocoDateImpurePipe, UserOverrideService, UserProfileFormComponent, UserProfileService, UserSettingsPersistence, UserSettingsStore, WEIGHT_STEPS, WordCloudComponent, ZoomControlsComponent, __resetSignInMutexForTests, activateShortcutTarget, applyThemeToNativeElement, atomicClientProvider, auditInterceptorFn, authInterceptorFn, bodyInterceptorFn, bootstrapApp, buildHeatmap, buildQuery, buildTagCloud, candidatesFor, canonicalize, debouncedSignal, errorInterceptorFn, fieldErrorKey, fieldShowsError, filterKey, filterLeaves, filterValues, findAggregation, flagsFromWeekdays, focusWhenReady, galactikPrimitive, galactikSemantic, getCurrentPath, getCurrentQueryName, getQueryNameFromRoute, groupSearchesByDate, injectAdvancedFilters, injectAtomicClient, injectRouteNavigation, injectUserSettingsPatch, isAuthRoute, isSignInInFlight, itemLabel, layoutWordCloud, legacyFilterToFilter, makeWeightScale, multiSelectionToolbarVariants, paletteColor, processCssVars, provideAtomicClient, provideAtomicNotifications, provideAtomicScope, provideDocumentLang, provideKeyboardShortcuts, provideSessionExpiry, provideStartupAggregation, quantileScale, queryNameResolver, rebuildWithout, searchItemKey, seriesPalette, signIn, themeColorNameToCssVariable, themeColorsToCssVariables, timelinePalette, toAriaKeyshortcuts, toDisplayParts, toPercentages, toSeries, toastInterceptorFn, weekdaysFromFlags, withAggregationsFeatures, withAlertsFeatures, withAlpha, withAppFeatures, withApplicationFeatures, withAssistantFeatures, withBasketsFeatures, withBookmarkFeatures, withBootstrapApp, withExtractsFeatures, withFavoriteSearchesFeatures, withFetch, withMultiSelectionFeatures, withQueryParamsFeatures, withQuickFiltersFeatures, withRecentSearchesFeatures, withSavedSearchesFeatures, withSelectionFeatures, withThemeBodyHook, withThemes, withThemesFeatures, withUserSettingsFeatures };
38865
39171
 
38866
39172
  //# sourceMappingURL=sinequa-atomic-angular.mjs.map