@sinequa/atomic-angular 2.10.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.
@@ -1075,7 +1075,7 @@ export declare class MetadataComponent {
1075
1075
  }>;
1076
1076
  class: import("@angular/core").InputSignal<string | undefined>;
1077
1077
  variant: import("@angular/core").InputSignal<"primary" | "secondary" | null | undefined>;
1078
- size: import("@angular/core").InputSignal<"small" | "medium" | "md" | "sm" | "xs" | "xsmall" | null | undefined>;
1078
+ size: import("@angular/core").InputSignal<"small" | "medium" | "sm" | "md" | "xs" | "xsmall" | null | undefined>;
1079
1079
  scheme: import("@angular/core").InputSignal<"error" | "sage" | "almond" | "pink" | "grey" | "yellow" | "cherry" | "indigo" | "cyan" | "success" | "warning" | "info" | null | undefined>;
1080
1080
  metadata: import("@angular/core").InputSignal<(string & Record<never, never>) | KeyOf<Article>>;
1081
1081
  article: import("@angular/core").InputSignal<Partial<Article> | (string & Record<never, never>)>;
@@ -2046,6 +2046,21 @@ export declare class NavbarTabsComponent {
2046
2046
  * than "tabs" in that context (e.g. "result categories").
2047
2047
  */
2048
2048
  ariaLabel: import("@angular/core").InputSignal<string | undefined>;
2049
+ /**
2050
+ * Look of the tab strip, from galactik's `TabList`.
2051
+ *
2052
+ * - `primary` (default): the tabs sit in a bordered pill strip, the selected one filled;
2053
+ * - `secondary`: a flat row on a white background, the selected tab underlined;
2054
+ * - `inner`: the same underline on a transparent background — for a strip that lives inside a
2055
+ * page rather than on a bar of its own, such as the result categories under a search field.
2056
+ *
2057
+ * The two underline variants also get the larger tab of the design (44px, 14px semibold).
2058
+ *
2059
+ * @default "primary"
2060
+ */
2061
+ variant: import("@angular/core").InputSignal<"primary" | "secondary" | "inner">;
2062
+ /** The pill strip is the only variant whose tabs keep galactik's own, smaller size. */
2063
+ protected readonly isPill: import("@angular/core").Signal<boolean>;
2049
2064
  showCount: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2050
2065
  /**
2051
2066
  * When enabled (default), tab labels are never clipped: tabs that do not fit
@@ -2118,6 +2133,11 @@ export declare class NavbarTabsComponent {
2118
2133
  "required": false;
2119
2134
  "isSignal": true;
2120
2135
  };
2136
+ "variant": {
2137
+ "alias": "variant";
2138
+ "required": false;
2139
+ "isSignal": true;
2140
+ };
2121
2141
  "showCount": {
2122
2142
  "alias": "showCount";
2123
2143
  "required": false;
@@ -11952,8 +11972,8 @@ export declare class SignedOutComponent {
11952
11972
  static ɵcmp: i0.ɵɵComponentDeclaration<SignedOutComponent, "signed-out, SignedOut, signedout", never, {}, {}, never, never, true, never>;
11953
11973
  }
11954
11974
  export declare class BookmarkButtonComponent {
11955
- variant: import("@angular/core").InputSignal<"none" | "light-accent" | "accent" | "primary" | "secondary" | "tertiary" | null | undefined>;
11956
- size: import("@angular/core").InputSignal<"small" | "medium" | "large" | "md" | "sm" | "xs" | "xsmall" | "lg" | null | undefined>;
11975
+ variant: import("@angular/core").InputSignal<"none" | "primary" | "secondary" | "light-accent" | "accent" | "tertiary" | null | undefined>;
11976
+ size: import("@angular/core").InputSignal<"small" | "medium" | "large" | "sm" | "md" | "xs" | "xsmall" | "lg" | null | undefined>;
11957
11977
  /**
11958
11978
  * Tab index applied to the inner button.
11959
11979
  *
@@ -13044,7 +13064,11 @@ export declare class SearchFeedbackComponent {
13044
13064
  onClose: import("@angular/core").OutputEmitterRef<void>;
13045
13065
  private readonly injector;
13046
13066
  pages: import("@angular/core").InputSignal<any>;
13047
- variant: import("@angular/core").InputSignal<"none" | "light-accent" | "accent" | "primary" | "secondary" | "tertiary" | null | undefined>;
13067
+ variant: import("@angular/core").InputSignal<"none" | "primary" | "secondary" | "light-accent" | "accent" | "tertiary" | null | undefined>;
13068
+ /** Size of the trigger button. `sm` fits a row of result options. */
13069
+ size: import("@angular/core").InputSignal<"small" | "medium" | "large" | "sm" | "md" | "xs" | "xsmall" | "lg" | null | undefined>;
13070
+ /** Shows the close cross on the button. Turn it off where the button belongs to the page and is not a suggestion to dismiss. */
13071
+ dismissible: import("@angular/core").InputSignal<boolean>;
13048
13072
  readonly auditService: AuditService;
13049
13073
  protected readonly queryParamsStore: {
13050
13074
  name?: import("@angular/core").Signal<string | undefined> | undefined;
@@ -13183,6 +13207,16 @@ export declare class SearchFeedbackComponent {
13183
13207
  "required": false;
13184
13208
  "isSignal": true;
13185
13209
  };
13210
+ "size": {
13211
+ "alias": "size";
13212
+ "required": false;
13213
+ "isSignal": true;
13214
+ };
13215
+ "dismissible": {
13216
+ "alias": "dismissible";
13217
+ "required": false;
13218
+ "isSignal": true;
13219
+ };
13186
13220
  }, {
13187
13221
  "onClose": "onClose";
13188
13222
  }, never, never, true, never>;
@@ -15900,7 +15934,7 @@ export declare class AggregationComponent {
15900
15934
  *
15901
15935
  * @default "auto"
15902
15936
  */
15903
- type: import("@angular/core").InputSignal<"auto" | "list" | "tree" | "date">;
15937
+ type: import("@angular/core").InputSignal<"list" | "date" | "auto" | "tree">;
15904
15938
  /**
15905
15939
  * Whether the host removes itself from the layout (Tailwind's `hidden`, i.e.
15906
15940
  * `display: none`) when it resolves to zero items. When `false` (default), the
@@ -15952,7 +15986,7 @@ export declare class AggregationComponent {
15952
15986
  * The sub-component to render: the explicit `type` input, or the current
15953
15987
  * date/tree/list heuristic when `type` is `"auto"`.
15954
15988
  */
15955
- protected resolvedType: import("@angular/core").Signal<"list" | "tree" | "date">;
15989
+ protected resolvedType: import("@angular/core").Signal<"list" | "date" | "tree">;
15956
15990
  /** Whether a filter is currently applied on this aggregation. */
15957
15991
  private readonly hasFilters;
15958
15992
  /**
@@ -16125,7 +16159,7 @@ export declare class AggregationPanelComponent {
16125
16159
  * @default false
16126
16160
  */
16127
16161
  headless: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
16128
- /** How many items are checked (applied or not yet): the count in the tooltip of the select all checkbox of the bar under the search field. */
16162
+ /** How many items are checked (applied or not yet): the count written at the end of the "select all" row, above the items. */
16129
16163
  selectedCount: import("@angular/core").InputSignal<number>;
16130
16164
  searchText: import("@angular/core").ModelSignal<string>;
16131
16165
  itemsLength: import("@angular/core").InputSignal<number>;
@@ -16139,9 +16173,28 @@ export declare class AggregationPanelComponent {
16139
16173
  isCollapsed: import("@angular/core").WritableSignal<boolean>;
16140
16174
  expanded: import("@angular/core").Signal<"" | null>;
16141
16175
  private readonly searchBox;
16176
+ private readonly searchToggle;
16177
+ private readonly injector;
16142
16178
  /** The galactik popover (`[popover]` / `[dropdown]`) this panel is shown in, if any — resolved through the injector tree. */
16143
16179
  protected readonly isInPopover: boolean;
16144
- constructor();
16180
+ private static nextId;
16181
+ protected readonly searchId: string;
16182
+ private readonly searchRequested;
16183
+ /**
16184
+ * Whether the facet has a search field at all: the facet allows it (`searchable`, from the custom JSON or the
16185
+ * `searchable` input of the facet) and there is something to search in.
16186
+ */
16187
+ protected readonly canSearch: import("@angular/core").Signal<boolean>;
16188
+ /**
16189
+ * The search field is out of the way until the user asks for it with the magnifier: a field that is always there costs a
16190
+ * line per facet, and most of the time nobody searches. A text already in the field keeps it open — it is filtering the
16191
+ * values, and a filter you cannot see is not a filter you can undo.
16192
+ */
16193
+ protected readonly showSearch: import("@angular/core").Signal<boolean>;
16194
+ /** Opens the search field and puts the focus in it, or closes it, drops its text and gives the focus back to the magnifier. */
16195
+ protected toggleSearch(event?: Event): void;
16196
+ /** Escape in the field closes it, as it would a popover: the way back is the key the user already knows. */
16197
+ protected onSearchEscape(event: Event): void;
16145
16198
  onHeaderClick(event: Event): void;
16146
16199
  onToggle(event: Event): void;
16147
16200
  static ɵfac: i0.ɵɵFactoryDeclaration<AggregationPanelComponent, never>;
@@ -16322,6 +16375,19 @@ export declare function filterKey(leaf: LegacyFilter): string;
16322
16375
  */
16323
16376
  export declare class AppliedFiltersComponent {
16324
16377
  private readonly queryParamsStore;
16378
+ private static nextId;
16379
+ protected readonly listId: string;
16380
+ private readonly list;
16381
+ /** Whether the chips take more lines than `maxLines`: only then is there anything to fold. */
16382
+ protected readonly foldable: import("@angular/core").WritableSignal<boolean>;
16383
+ /** The list is unfolded. */
16384
+ protected readonly expanded: import("@angular/core").WritableSignal<boolean>;
16385
+ /** Height of `maxLines` lines of chips, and of all of them, in pixels — measured, as the chips wrap with the width. */
16386
+ private readonly foldedHeight;
16387
+ private readonly fullHeight;
16388
+ /** The height the list is given: none (it is as tall as its chips) until there is something to fold. */
16389
+ protected readonly listHeight: import("@angular/core").Signal<number | null>;
16390
+ protected toggle(): void;
16325
16391
  /**
16326
16392
  * The filters to display. Omit it to read the current query's own — the common case.
16327
16393
  *
@@ -16351,9 +16417,22 @@ export declare class AppliedFiltersComponent {
16351
16417
  /** Chip colour scheme, passed to galactik's `tag`. */
16352
16418
  readonly scheme: import("@angular/core").InputSignal<"error" | "sage" | "almond" | "pink" | "grey" | "yellow" | "cherry" | "indigo" | "cyan" | "success" | "warning" | "info" | null | undefined>;
16353
16419
  /** Chip size, passed to galactik's `tag`. */
16354
- readonly size: import("@angular/core").InputSignal<"small" | "medium" | "md" | "sm" | "xs" | "xsmall" | null | undefined>;
16420
+ readonly size: import("@angular/core").InputSignal<"small" | "medium" | "sm" | "md" | "xs" | "xsmall" | null | undefined>;
16355
16421
  /** Extra classes for each chip, merged by galactik's `tag`. */
16356
16422
  readonly chipClass: import("@angular/core").InputSignal<string>;
16423
+ /**
16424
+ * How many lines of chips are shown before the rest is folded behind a "show more" button. `0` never folds.
16425
+ *
16426
+ * @default 2
16427
+ */
16428
+ readonly maxLines: import("@angular/core").InputSignalWithTransform<number, unknown>;
16429
+ /**
16430
+ * Whether the "clear all" button ends the list of chips (shown from two chips on). Turn it off when the screen has a clear
16431
+ * button of its own.
16432
+ *
16433
+ * @default true
16434
+ */
16435
+ readonly showClearAll: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
16357
16436
  /** A chip was removed. */
16358
16437
  readonly removed: import("@angular/core").OutputEmitterRef<AppliedFilterChip>;
16359
16438
  /** Every chip was removed. */
@@ -16362,6 +16441,12 @@ export declare class AppliedFiltersComponent {
16362
16441
  readonly filtersChange: import("@angular/core").OutputEmitterRef<LegacyFilter[]>;
16363
16442
  /** Something changed, whichever way. Re-run the search on this and ignore the rest. */
16364
16443
  readonly changed: import("@angular/core").OutputEmitterRef<void>;
16444
+ constructor();
16445
+ /**
16446
+ * Reads how the chips wrap: the rows are the distinct tops of the chips, so the height of `maxLines` lines is the top of the
16447
+ * next row less the gap, and the whole list is its `scrollHeight`. The chips below the folded height are made `inert`.
16448
+ */
16449
+ private measure;
16365
16450
  /** One chip per applied value, expanded from the stored entries through their leaves. */
16366
16451
  readonly chips: import("@angular/core").Signal<AppliedFilterChip[]>;
16367
16452
  /**
@@ -16410,6 +16495,16 @@ export declare class AppliedFiltersComponent {
16410
16495
  "required": false;
16411
16496
  "isSignal": true;
16412
16497
  };
16498
+ "maxLines": {
16499
+ "alias": "maxLines";
16500
+ "required": false;
16501
+ "isSignal": true;
16502
+ };
16503
+ "showClearAll": {
16504
+ "alias": "showClearAll";
16505
+ "required": false;
16506
+ "isSignal": true;
16507
+ };
16413
16508
  }, {
16414
16509
  "removed": "removed";
16415
16510
  "cleared": "cleared";
@@ -16569,7 +16664,7 @@ export declare class FilterButtonComponent {
16569
16664
  * @default "sage"
16570
16665
  */
16571
16666
  scheme: import("@angular/core").InputSignal<FilterScheme>;
16572
- protected variant: import("@angular/core").WritableSignal<"none" | "light-accent" | "accent" | "primary" | "secondary" | "tertiary" | null | undefined>;
16667
+ protected variant: import("@angular/core").WritableSignal<"none" | "primary" | "secondary" | "light-accent" | "accent" | "tertiary" | null | undefined>;
16573
16668
  protected filter: import("@angular/core").WritableSignal<CFilterEx>;
16574
16669
  /** Unique id wiring the trigger's `popovertarget` to the `<div popover>` `id`. */
16575
16670
  protected readonly popoverId: string;
@@ -18686,6 +18781,80 @@ export declare class FiltersBarComponent {
18686
18781
  "onClearBasket": "onClearBasket";
18687
18782
  }, never, ["[filtersBarStart]"], true, never>;
18688
18783
  }
18784
+ type FiltersTab = "all" | "quick";
18785
+ /**
18786
+ * The filters panel: the facets of the search, and the quick filters of the user, in one card-sized column.
18787
+ *
18788
+ * "All" holds the facets (`<aside-filters>`, driven by the application's filters configuration) with a field that narrows them by
18789
+ * name, the count of documents, and a button that saves the filters applied right now as a quick filter (a card under the button
18790
+ * asks for its name). "Quick Filters" is the list of the `<quick-filters>` pill, inline (`<quick-filters-list>`): one line per quick filter, with the
18791
+ * count of its filters — hovering it shows them as tags — and a cross that deletes it. A click on a quick filter replaces **all** the
18792
+ * applied filters by its own and keeps the rest of the query, the text above all.
18793
+ *
18794
+ * The panel is the content only: it fills the height it is given and scrolls inside. Where it goes — a column next to the results, an
18795
+ * overlay, a sheet — and what surrounds it are the host's. The host closes it on `closed`.
18796
+ *
18797
+ * ```html
18798
+ * <filters-panel [documentCount]="result()?.rowCount ?? 0" (closed)="open.set(false)" />
18799
+ * ```
18800
+ */
18801
+ export declare class FiltersPanelComponent {
18802
+ /**
18803
+ * How many documents the search found: the count under the field, which is also what a quick filter would be saved over. The panel
18804
+ * does not run the search, the page does.
18805
+ */
18806
+ readonly documentCount: import("@angular/core").InputSignal<number>;
18807
+ /** The user closes the panel (the cross of its header). Closing is the host's: it decides how the panel is shown. */
18808
+ readonly closed: import("@angular/core").OutputEmitterRef<void>;
18809
+ private readonly appStore;
18810
+ private readonly aggregationsStore;
18811
+ private readonly queryParamsStore;
18812
+ private readonly userSettingsStore;
18813
+ private readonly transloco;
18814
+ private readonly injector;
18815
+ protected readonly nameId: string;
18816
+ protected readonly tab: import("@angular/core").WritableSignal<FiltersTab>;
18817
+ protected readonly query: import("@angular/core").WritableSignal<string>;
18818
+ protected readonly saving: import("@angular/core").WritableSignal<boolean>;
18819
+ protected readonly announcement: import("@angular/core").WritableSignal<string>;
18820
+ protected readonly name: import("@angular/core").WritableSignal<string>;
18821
+ /** How many values the query is filtered by: nothing to save as a quick filter when it is zero. */
18822
+ protected readonly appliedCount: import("@angular/core").Signal<number>;
18823
+ private readonly nameInput;
18824
+ private readonly saveButton;
18825
+ /**
18826
+ * The facets whose name contains the query, as the names `<aside-filters [aggregations]>` takes.
18827
+ * Empty query → the component's own configuration-driven list (the input is left empty).
18828
+ *
18829
+ * An explicit list bypasses the `position` and "hidden" rules of that configuration, so the same two
18830
+ * rules are applied here first.
18831
+ */
18832
+ protected readonly matching: import("@angular/core").Signal<string[]>;
18833
+ protected selectTab(values: readonly string[]): void;
18834
+ /** The leaf filters of an entry, flattening a nested and/or tree. */
18835
+ private leaves;
18836
+ /** How many values a leaf holds: an `in` list holds several, anything else one. */
18837
+ private valuesOf;
18838
+ /** Opens the card under the button and puts the focus in its field: it appears at the user's request, so the next key is the name. */
18839
+ protected startSaving(): void;
18840
+ /** Closes the card without saving, and gives the focus back to the button that opened it. */
18841
+ protected closeSaving(): void;
18842
+ /** Escape closes the card, not the whole filters panel the card is in. */
18843
+ protected onSaveEscape(event: Event): void;
18844
+ protected saveQuickFilter(event: Event): Promise<void>;
18845
+ /** The list applied a quick filter (it replaced the filters of the query by its own): the screen readers are told. */
18846
+ protected onQuickFilterApplied(quickFilter: QuickFilter): void;
18847
+ static ɵfac: i0.ɵɵFactoryDeclaration<FiltersPanelComponent, never>;
18848
+ static ɵcmp: i0.ɵɵComponentDeclaration<FiltersPanelComponent, "filters-panel, FiltersPanel, filterspanel", never, {
18849
+ "documentCount": {
18850
+ "alias": "documentCount";
18851
+ "required": false;
18852
+ "isSignal": true;
18853
+ };
18854
+ }, {
18855
+ "closed": "closed";
18856
+ }, never, never, true, never>;
18857
+ }
18689
18858
  /**
18690
18859
  * Injection token that indicates whether custom date ranges are allowed.
18691
18860
  *
@@ -19412,8 +19581,8 @@ export declare class HistoryPanelComponent {
19412
19581
  * The user's quick filters: named sets of filters that one click applies again. A pill, like the filters of the bar it is
19413
19582
  * meant to sit in front of (the `filtersBarStart` slot of `<filters-bar>`), that opens a popover with a search field and the
19414
19583
  * list. A click on a quick filter **replaces** the active filters by its own and closes the popover, and hovering its count of
19415
- * filters shows what it holds. Quick filters are made, renamed and deleted elsewhere (the filters of the results page): this
19416
- * is only where they are applied.
19584
+ * filters shows what it holds, and the cross at the end of a row deletes it. Quick filters are made elsewhere (the filters of
19585
+ * the results page): this is where they are applied and deleted.
19417
19586
  *
19418
19587
  * They live in the user settings (`UserSettingsStore.quickFilters`), so they follow the user from one page, and one device, to
19419
19588
  * the other.
@@ -19435,9 +19604,6 @@ export declare class QuickFiltersComponent {
19435
19604
  readonly offset: import("@angular/core").InputSignal<number>;
19436
19605
  /** Emitted with the quick filter a click has just applied. */
19437
19606
  readonly applied: import("@angular/core").OutputEmitterRef<QuickFilter>;
19438
- private readonly userSettingsStore;
19439
- private readonly queryParamsStore;
19440
- private readonly appStore;
19441
19607
  private readonly transloco;
19442
19608
  private readonly host;
19443
19609
  protected readonly popoverId: string;
@@ -19450,32 +19616,13 @@ export declare class QuickFiltersComponent {
19450
19616
  protected readonly resized: import("@angular/core").WritableSignal<boolean>;
19451
19617
  private readonly flippedAbove;
19452
19618
  protected readonly placement: import("@angular/core").Signal<Placement>;
19453
- /** The row whose hover card is showing: its quick filter, and the element the card hangs from. */
19454
- protected readonly details: import("@angular/core").WritableSignal<{
19455
- quickFilter: QuickFilter;
19456
- anchor: HTMLElement;
19457
- } | null>;
19458
- private readonly detailsCard;
19459
- private hideTimer;
19460
19619
  private readonly popover;
19461
19620
  protected readonly isOpen: import("@angular/core").Signal<boolean>;
19462
19621
  constructor();
19463
- protected readonly variant: import("@angular/core").Signal<"none" | "light-accent" | "accent" | "primary" | "secondary" | "tertiary" | null | undefined>;
19622
+ protected readonly variant: import("@angular/core").Signal<"none" | "primary" | "secondary" | "light-accent" | "accent" | "tertiary" | null | undefined>;
19464
19623
  protected readonly triggerClass: import("@angular/core").Signal<string>;
19465
- protected readonly quickFilters: import("@angular/core").Signal<QuickFilter[]>;
19466
- protected readonly query: import("@angular/core").WritableSignal<string>;
19467
- protected readonly filtered: import("@angular/core").Signal<QuickFilter[]>;
19468
- /** What was just done, for the screen readers. */
19624
+ /** What was just done, for the screen readers: kept here, as the list goes with the popover once a quick filter is applied. */
19469
19625
  protected readonly announcement: import("@angular/core").WritableSignal<string>;
19470
- /**
19471
- * What a quick filter holds, one chip per filter: the icon the application gave the aggregation of the filter in the
19472
- * "filters" custom JSON (the one its filter button shows) and the value. The icon says what is filtered on, so the name is
19473
- * left out; an aggregation without an icon keeps it (`Authors: John`), or the value alone would say nothing.
19474
- */
19475
- protected chips(quickFilter: QuickFilter): {
19476
- text: string;
19477
- icon?: string;
19478
- }[];
19479
19626
  protected onToggle(): void;
19480
19627
  /**
19481
19628
  * Gives the position back to Floating UI: a top edge that was moved is put back where the placement leaves it, and the
@@ -19484,21 +19631,9 @@ export declare class QuickFiltersComponent {
19484
19631
  private unpin;
19485
19632
  /** The user starts to resize: pins the popover, on the side Floating UI had put it. */
19486
19633
  protected onResizeStart(): void;
19487
- /** Shows what a quick filter holds, under its row. */
19488
- protected showDetails(quickFilter: QuickFilter, event: Event): void;
19489
- /** Hides the card a moment later, so the pointer can cross from the row to the card. */
19490
- protected scheduleHideDetails(): void;
19491
- protected cancelHideDetails(): void;
19492
- protected hideDetails(): void;
19493
- /** The popover is closed with nothing half done: no search, no name being typed. */
19494
- private reset;
19495
19634
  /** Closes the popover when the focus leaves the whole component. `null` (focus left the document) leaves it open. */
19496
19635
  protected closeOnFocusLeave(event: FocusEvent): void;
19497
- /** What the list holds as selected: nothing, ever — choosing a row applies it and the list starts again. */
19498
- protected readonly picked: import("@angular/core").WritableSignal<QuickFilter[]>;
19499
- /** A row was chosen in the list. */
19500
- protected pick(values: readonly QuickFilter[]): void;
19501
- /** A click on a quick filter: its filters replace the active ones. */
19636
+ /** The list applied a quick filter: the popover closes, and the page is told. */
19502
19637
  protected apply(quickFilter: QuickFilter): void;
19503
19638
  static ɵfac: i0.ɵɵFactoryDeclaration<QuickFiltersComponent, never>;
19504
19639
  static ɵcmp: i0.ɵɵComponentDeclaration<QuickFiltersComponent, "QuickFilters, quick-filters", never, {
@@ -19526,16 +19661,187 @@ export declare class QuickFiltersComponent {
19526
19661
  "applied": "applied";
19527
19662
  }, never, never, true, never>;
19528
19663
  }
19529
- /** Order of the categories of the suggestions, first to last. */
19530
- export declare const SEARCH_BOX_CATEGORIES_SORT: InjectionToken<string[]>;
19531
- /** The icon of each category of suggestion. */
19532
- export declare const SEARCH_BOX_CATEGORY_ICONS: InjectionToken<Record<string, Type<unknown>>>;
19533
- type Suggestion$1 = Partial<Suggestion> & {
19664
+ /**
19665
+ * The list of the user's quick filters, to be placed where the host wants it: inline (a tab of the filters panel) or in a popover
19666
+ * (the `<quick-filters>` pill). It is the content only; the host owns the container, and what happens once a quick filter is applied.
19667
+ *
19668
+ * One row per quick filter: its name and, under it, the count of its filters — hovering that line (or focusing the row) shows them as
19669
+ * chips in a card, whose cut-off texts get a tooltip. A click on a row **replaces** the active filters by its own (the rest of the query stays, the text above all) and the host
19670
+ * is told with `applied`. The cross at the end of the row (or `Del` when the row has the focus) deletes the quick filter from the
19671
+ * user's settings. Quick filters are made elsewhere: where the filters are saved as one.
19672
+ *
19673
+ * ```html
19674
+ * <quick-filters-list [searchable]="true" (applied)="popover.close()" />
19675
+ * ```
19676
+ */
19677
+ export declare class QuickFiltersListComponent {
19678
+ /** Shows a field that narrows the list by name. It only appears once there is something to narrow. */
19679
+ readonly searchable: import("@angular/core").InputSignal<boolean>;
19680
+ /** Shows the cross that deletes a quick filter, and lets `Del` do the same. */
19681
+ readonly deletable: import("@angular/core").InputSignal<boolean>;
19682
+ /** What the empty state says under its title, when the default does not fit where the list is. */
19683
+ readonly emptyHint: import("@angular/core").InputSignal<string | undefined>;
19684
+ /** Emitted with the quick filter a click has just applied: the host decides what follows (close a popover…). */
19685
+ readonly applied: import("@angular/core").OutputEmitterRef<QuickFilter>;
19686
+ /** Emitted with the quick filter that has just been deleted. */
19687
+ readonly deleted: import("@angular/core").OutputEmitterRef<QuickFilter>;
19688
+ private readonly userSettingsStore;
19689
+ private readonly queryParamsStore;
19690
+ private readonly appStore;
19691
+ private readonly transloco;
19692
+ private readonly host;
19693
+ private readonly injector;
19694
+ protected readonly deleteKeys: string[];
19695
+ protected readonly quickFilters: import("@angular/core").Signal<QuickFilter[]>;
19696
+ protected readonly query: import("@angular/core").WritableSignal<string>;
19697
+ protected readonly filtered: import("@angular/core").Signal<QuickFilter[]>;
19698
+ /** What was just done, for the screen readers. */
19699
+ protected readonly announcement: import("@angular/core").WritableSignal<string>;
19700
+ /** The row whose hover card is showing: its quick filter, and the element the card hangs from. */
19701
+ protected readonly details: import("@angular/core").WritableSignal<{
19702
+ quickFilter: QuickFilter;
19703
+ anchor: HTMLElement;
19704
+ } | null>;
19705
+ private readonly detailsCard;
19706
+ private hideTimer;
19707
+ private readonly deleting;
19708
+ constructor();
19709
+ /**
19710
+ * What a quick filter holds, one chip per filter: the icon the application gave the aggregation of the filter in the
19711
+ * "filters" custom JSON (the one its filter button shows) and the value. The icon says what is filtered on, so the name is
19712
+ * left out; an aggregation without an icon keeps it (`Authors: John`), or the value alone would say nothing.
19713
+ */
19714
+ protected chips(quickFilter: QuickFilter): {
19715
+ text: string;
19716
+ icon?: string;
19717
+ }[];
19718
+ /** Shows what a quick filter holds, under the line of its count of filters. */
19719
+ protected showDetails(quickFilter: QuickFilter, anchor: HTMLElement): void;
19720
+ /** Hides the card a moment later, so the pointer can cross from the row to the card. */
19721
+ protected scheduleHideDetails(): void;
19722
+ protected cancelHideDetails(): void;
19723
+ /** Escape takes the card away first (WCAG 1.4.13); only a second one reaches what the list is in (a panel, a popover). */
19724
+ protected onEscape(event: Event): void;
19725
+ /** What the list holds as selected: nothing, ever — choosing a row applies it and the list starts again. */
19726
+ protected readonly picked: import("@angular/core").WritableSignal<QuickFilter[]>;
19727
+ /** A row was chosen in the list. */
19728
+ protected pick(values: readonly QuickFilter[]): void;
19729
+ /**
19730
+ * A click on a quick filter: its filters replace ALL the applied ones — the whole `filters` of the query, not a merge with them.
19731
+ * Everything else the query holds stays, the text above all: `patch` only writes what it is given.
19732
+ */
19733
+ private apply;
19734
+ /**
19735
+ * Deletes a quick filter from the user's settings. The toast says it is done. A deleted row leaves the DOM with the focus: when the
19736
+ * focus was in the list it goes to the row that took its place, or to the list itself when it was the last, so it is never dropped
19737
+ * on the page.
19738
+ */
19739
+ protected remove(quickFilter: QuickFilter, index: number, event: Event): Promise<void>;
19740
+ static ɵfac: i0.ɵɵFactoryDeclaration<QuickFiltersListComponent, never>;
19741
+ static ɵcmp: i0.ɵɵComponentDeclaration<QuickFiltersListComponent, "QuickFiltersList, quick-filters-list", never, {
19742
+ "searchable": {
19743
+ "alias": "searchable";
19744
+ "required": false;
19745
+ "isSignal": true;
19746
+ };
19747
+ "deletable": {
19748
+ "alias": "deletable";
19749
+ "required": false;
19750
+ "isSignal": true;
19751
+ };
19752
+ "emptyHint": {
19753
+ "alias": "emptyHint";
19754
+ "required": false;
19755
+ "isSignal": true;
19756
+ };
19757
+ }, {
19758
+ "applied": "applied";
19759
+ "deleted": "deleted";
19760
+ }, never, never, true, never>;
19761
+ }
19762
+ /** A row of the suggestions popup: what the suggest queries return, or a title row ahead of a category. */
19763
+ export type SearchBoxSuggestion = Partial<Suggestion> & {
19534
19764
  $isDivider?: boolean;
19535
19765
  $isTitle?: boolean;
19536
19766
  /** The translated title of the category, on a title row. */
19537
19767
  $label?: string;
19538
19768
  };
19769
+ /**
19770
+ * Where the suggestions come from, in place of the application's suggest queries. Receives the text of the field once it
19771
+ * has settled (empty on an empty field) and returns the rows to show, in their final order: nothing is grouped or titled for it.
19772
+ */
19773
+ export type SearchBoxSuggestionsProvider = (text: string) => SearchBoxSuggestion[] | Promise<SearchBoxSuggestion[]>;
19774
+ /**
19775
+ * What `SearchBox` hands to a `searchBoxPopup` template. A single object, the same for the life of the component: the values
19776
+ * that change are signals.
19777
+ */
19778
+ export interface SearchBoxPopupContext {
19779
+ /** The text the suggestions are fetched for: the text of the field, once it has settled. */
19780
+ readonly text: Signal<string>;
19781
+ /** The text as it is in the field, before the debounce. */
19782
+ readonly typed: Signal<string>;
19783
+ /** The suggestions for `text`. While a new list loads, the previous one stays. */
19784
+ readonly suggestions: Signal<SearchBoxSuggestion[]>;
19785
+ /** Whether a list of suggestions is being fetched. */
19786
+ readonly loading: Signal<boolean>;
19787
+ /** The searches the user has saved. */
19788
+ readonly savedSearches: Signal<SearchItem[]>;
19789
+ /** Whether the user pressed an arrow key since the last typed character (a preview is only for the keyboard). */
19790
+ readonly navigatedSinceTyping: Signal<boolean>;
19791
+ /** Writes `text` in the field, closes the popup and runs the search. */
19792
+ commit(text: string): void;
19793
+ /** Shows `text` in the field without fetching the suggestions again: the URL-bar preview of the active row. */
19794
+ preview(text: string): void;
19795
+ /** Runs a saved search as it was saved (text, filters, tab) and closes the popup. */
19796
+ openSaved(saved: SearchItem): void;
19797
+ /** Whether `text` is one of the saved searches. */
19798
+ isSaved(text: string): boolean;
19799
+ /** Saves `text`, or removes it from the saved searches. Never runs it. */
19800
+ toggleSaved(text: string): void;
19801
+ /** Closes the popup. */
19802
+ collapse(): void;
19803
+ /** Gives the focus back to the field, where the user is typing. */
19804
+ focusField(): void;
19805
+ }
19806
+ /**
19807
+ * Replaces what the popup of a `SearchBox` shows (the tabs and their list) with the application's own template. The popup
19808
+ * itself — its placement, its `card` / `inline` look, its opening — stays the search box's.
19809
+ *
19810
+ * With `popupFitScreen` on the search box, the popup is capped by the room the screen leaves on the side it opens
19811
+ * (`max-height`): give the template's own list `min-h-0` and let it scroll, rather than a fixed height that would run off the screen.
19812
+ *
19813
+ * The template must carry the combobox widget itself: an `ngComboboxWidget` + `ngListbox` element with
19814
+ * `focusMode="activedescendant"`, so that the field keeps being announced as a combobox. The list is in the application's view, so the
19815
+ * search box does not drive it, apart from scrolling the active option into view while the arrows walk it. Call
19816
+ * `ctx.preview()` on `(valueChange)` while the keyboard navigates, and `ctx.commit()` on a click.
19817
+ *
19818
+ * ```html
19819
+ * <search-box>
19820
+ * <ng-template searchBoxPopup let-ctx>
19821
+ * <ul ngComboboxWidget ngListbox #lb="ngListbox" focusMode="activedescendant" [activeDescendant]="lb.activeDescendant()">
19822
+ * @for (s of ctx.suggestions(); track $index) {
19823
+ * <li ngOption [value]="s" [label]="s.display ?? ''" (click)="ctx.commit(s.display ?? '')">{{ s.display }}</li>
19824
+ * }
19825
+ * </ul>
19826
+ * </ng-template>
19827
+ * </search-box>
19828
+ * ```
19829
+ */
19830
+ export declare class SearchBoxPopupDirective {
19831
+ readonly template: TemplateRef<{
19832
+ $implicit: SearchBoxPopupContext;
19833
+ }>;
19834
+ static ngTemplateContextGuard(_dir: SearchBoxPopupDirective, _ctx: unknown): _ctx is {
19835
+ $implicit: SearchBoxPopupContext;
19836
+ };
19837
+ static ɵfac: i0.ɵɵFactoryDeclaration<SearchBoxPopupDirective, never>;
19838
+ static ɵdir: i0.ɵɵDirectiveDeclaration<SearchBoxPopupDirective, "ng-template[searchBoxPopup]", never, {}, {}, never, never, true, never>;
19839
+ }
19840
+ /** Order of the categories of the suggestions, first to last. */
19841
+ export declare const SEARCH_BOX_CATEGORIES_SORT: InjectionToken<string[]>;
19842
+ /** The icon of each category of suggestion. */
19843
+ export declare const SEARCH_BOX_CATEGORY_ICONS: InjectionToken<Record<string, Type<unknown>>>;
19844
+ type Suggestion$1 = SearchBoxSuggestion;
19539
19845
  /** Which list the popup shows. */
19540
19846
  export type SearchBoxTab = "suggestions" | "saved";
19541
19847
  /**
@@ -19580,8 +19886,30 @@ export declare class SearchBoxComponent {
19580
19886
  readonly popup: import("@angular/core").InputSignal<"card" | "inline">;
19581
19887
  /** Distance, in pixels, between the field and the `card` popup. The card is placed with Floating UI, like the other popups. */
19582
19888
  readonly popupOffset: import("@angular/core").InputSignalWithTransform<number, unknown>;
19889
+ /**
19890
+ * Makes the popup fit the screen, like the facet popovers: its height is capped by the room left on the side it opens, its
19891
+ * list scrolling inside (see `popupFlip` for the side). On by default for the `hero` size with an `inline` popup (a home page), off
19892
+ * otherwise: the `card` then keeps its fixed list height, and the `inline` popup stays in the flow under the field, with no Floating UI
19893
+ * at all (so no `popupFlip` either). Give it explicitly (`[popupFitScreen]="false"`) to override the default.
19894
+ */
19895
+ readonly popupFitScreen: import("@angular/core").InputSignalWithTransform<boolean | undefined, string | boolean | undefined>;
19896
+ /**
19897
+ * Whether the popup goes above the field when there is no room under it. On by default, as the `card` always did, except for the
19898
+ * `hero` size, where it is off. Off keeps the popup under the field: with `popupFitScreen`, its height then shrinks down to the
19899
+ * edge of the screen instead.
19900
+ * Ignored by an `inline` popup that is not `popupFitScreen`: it is in the flow and never flips.
19901
+ */
19902
+ readonly popupFlip: import("@angular/core").InputSignalWithTransform<boolean | undefined, string | boolean | undefined>;
19583
19903
  /** Replaces the translated placeholder. */
19584
19904
  readonly placeholderOverride: import("@angular/core").InputSignal<string | undefined>;
19905
+ /**
19906
+ * Where the suggestions come from, in place of the application's suggest queries (and the user's recent searches, saved
19907
+ * searches and bookmarks). Called with the text of the field once it has settled; the rows it returns are shown as they are,
19908
+ * without categories or titles added. A rejected promise leaves an empty list.
19909
+ */
19910
+ readonly suggestionsProvider: import("@angular/core").InputSignal<SearchBoxSuggestionsProvider | undefined>;
19911
+ /** The application's own popup content (`<ng-template searchBoxPopup>`), if any: it replaces the tabs and their lists. */
19912
+ private readonly customPopup;
19585
19913
  /** Emitted with the text each time the user validates a search (Enter, the send button, a picked suggestion). */
19586
19914
  readonly searched: import("@angular/core").OutputEmitterRef<string>;
19587
19915
  /** Emitted once the text typed has settled (300ms), which is when the suggestions are fetched. */
@@ -20134,6 +20462,12 @@ export declare class SearchBoxComponent {
20134
20462
  protected readonly savedSearches: import("@angular/core").Signal<SearchItem[]>;
20135
20463
  private readonly savedTexts;
20136
20464
  private readonly inline;
20465
+ /** Whether Floating UI places the popup: always the card, the inline block only when it must fit the screen. */
20466
+ /** `popupFitScreen` as given, or its default: on for the `hero` size with an `inline` popup, off otherwise. */
20467
+ private readonly fitScreen;
20468
+ /** `popupFlip` as given, or its default: off for the `hero` size (the popup stays under the field and shrinks), on otherwise. */
20469
+ private readonly flip;
20470
+ private readonly floating;
20137
20471
  /** The bar keeps the room of its own padding on the `hero` size, whose send button sets it. */
20138
20472
  protected readonly barClass: import("@angular/core").Signal<"w-full" | "w-full gap-(--spacing-3xs)! pe-(--spacing-3xs)">;
20139
20473
  protected readonly popupClass: import("@angular/core").Signal<string>;
@@ -20153,7 +20487,11 @@ export declare class SearchBoxComponent {
20153
20487
  /** The suggestions: what the suggest queries return, with the user's recent searches, saved searches and bookmarks. */
20154
20488
  private readonly suggestionsResource;
20155
20489
  private previousSuggestions;
20156
- protected readonly suggestions: import("@angular/core").Signal<Suggestion$1[]>;
20490
+ protected readonly suggestions: import("@angular/core").Signal<SearchBoxSuggestion[]>;
20491
+ /** What a `searchBoxPopup` template receives: one object for the life of the component, whose changing values are signals. */
20492
+ protected readonly popupTemplateContext: {
20493
+ $implicit: SearchBoxPopupContext;
20494
+ };
20157
20495
  private inputListenersAttached;
20158
20496
  constructor();
20159
20497
  /**
@@ -20167,6 +20505,8 @@ export declare class SearchBoxComponent {
20167
20505
  * leaves the popup alone, so an alt-tab does not discard what the user was reading.
20168
20506
  */
20169
20507
  protected collapseOnFocusLeave(event: FocusEvent): void;
20508
+ /** Scrolls the option the field names as active (`aria-activedescendant`) into view, so a truncated row never stays cut. */
20509
+ private revealActiveOption;
20170
20510
  /** Collapses the suggestions popup. */
20171
20511
  collapse(): void;
20172
20512
  /**
@@ -20192,6 +20532,8 @@ export declare class SearchBoxComponent {
20192
20532
  protected focusField(): void;
20193
20533
  /** Commits a clicked suggestion: writes it into the field and runs the search. */
20194
20534
  protected commitSuggestion(suggestion: Suggestion$1, event: Event): void;
20535
+ /** Writes a text into the field, closes the popup and runs the search (the text searched may differ from the one shown, see `data-text`). */
20536
+ private commitText;
20195
20537
  /**
20196
20538
  * Runs a saved search as it was saved: its text, its filters and its tab, not only its text. The popup closes first,
20197
20539
  * since the page it leads to replaces what sits under it.
@@ -20244,6 +20586,8 @@ export declare class SearchBoxComponent {
20244
20586
  protected getIconForCategory(category: string | undefined): Type<unknown>;
20245
20587
  /** The title of a category: the library's own string, then an application key of the same name, then the category itself. */
20246
20588
  private categoryLabel;
20589
+ /** The suggestions of the application's own provider. A failure is logged and leaves an empty list. */
20590
+ private fetchFromProvider;
20247
20591
  /**
20248
20592
  * Fetches the suggestions for a text: the user's own (recent and saved searches, bookmarks) with the suggest queries of
20249
20593
  * the application, ordered by category, with a title row ahead of each category.
@@ -20278,11 +20622,26 @@ export declare class SearchBoxComponent {
20278
20622
  "required": false;
20279
20623
  "isSignal": true;
20280
20624
  };
20625
+ "popupFitScreen": {
20626
+ "alias": "popupFitScreen";
20627
+ "required": false;
20628
+ "isSignal": true;
20629
+ };
20630
+ "popupFlip": {
20631
+ "alias": "popupFlip";
20632
+ "required": false;
20633
+ "isSignal": true;
20634
+ };
20281
20635
  "placeholderOverride": {
20282
20636
  "alias": "placeholder";
20283
20637
  "required": false;
20284
20638
  "isSignal": true;
20285
20639
  };
20640
+ "suggestionsProvider": {
20641
+ "alias": "suggestionsProvider";
20642
+ "required": false;
20643
+ "isSignal": true;
20644
+ };
20286
20645
  "searchInputText": {
20287
20646
  "alias": "searchInputText";
20288
20647
  "required": false;
@@ -20294,7 +20653,7 @@ export declare class SearchBoxComponent {
20294
20653
  "saved": "saved";
20295
20654
  "expandedChange": "expandedChange";
20296
20655
  "searchInputText": "searchInputTextChange";
20297
- }, never, ["[slot='trailing']"], true, never>;
20656
+ }, ["customPopup"], ["[slot='trailing']"], true, never>;
20298
20657
  }
20299
20658
  export declare const RECENT_SEARCHES_OPTIONS: {
20300
20659
  itemsPerPage: number;
@@ -22016,6 +22375,22 @@ export declare class FileSizePipe implements PipeTransform {
22016
22375
  static ɵfac: i0.ɵɵFactoryDeclaration<FileSizePipe, never>;
22017
22376
  static ɵpipe: i0.ɵɵPipeDeclaration<FileSizePipe, "fileSize", true>;
22018
22377
  }
22378
+ /**
22379
+ * Writes a number the way the interface language does: `1,060` in English, `1 060` in French, `1.060` in German.
22380
+ *
22381
+ * Not Angular's `number` pipe: that one follows `LOCALE_ID`, which an application fixes once for good, so it would keep grouping
22382
+ * digits the same way in another language. The language here is the one transloco holds, read as a signal so a template using the
22383
+ * pipe updates by itself when the user changes it (the pipe stays pure).
22384
+ *
22385
+ * `null` and `undefined` are written as `0`.
22386
+ */
22387
+ export declare class LocalizedNumberPipe implements PipeTransform {
22388
+ private readonly transloco;
22389
+ private readonly lang;
22390
+ transform(value: number | null | undefined): string;
22391
+ static ɵfac: i0.ɵɵFactoryDeclaration<LocalizedNumberPipe, never>;
22392
+ static ɵpipe: i0.ɵɵPipeDeclaration<LocalizedNumberPipe, "localizedNumber", true>;
22393
+ }
22019
22394
  /**
22020
22395
  * The `@sinequa/atomic` client the surrounding injector works with.
22021
22396
  *