@memberjunction/ng-search 6.2.0-edge.0 → 6.2.0-edge.2

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.
@@ -407,7 +407,15 @@ export class SearchOverlayComponent {
407
407
  searchService = inject(SearchService);
408
408
  destroy$ = new Subject();
409
409
  searchInput$ = new Subject();
410
- searchInputRef;
410
+ SearchInputRef;
411
+ /** @deprecated Use {@link SearchInputRef}. */
412
+ get searchInputRef() {
413
+ return this.SearchInputRef;
414
+ }
415
+ /** @deprecated Use {@link SearchInputRef}. */
416
+ set searchInputRef(value) {
417
+ this.SearchInputRef = value;
418
+ }
411
419
  // --- Configuration Inputs ---
412
420
  /** Placeholder text for the search input */
413
421
  Placeholder = 'Search across all your knowledge...';
@@ -420,10 +428,10 @@ export class SearchOverlayComponent {
420
428
  */
421
429
  MaxResults = 8;
422
430
  /** Whether the overlay is currently visible */
423
- _IsOpen = false;
431
+ _isOpen = false;
424
432
  set IsOpen(value) {
425
- const prev = this._IsOpen;
426
- this._IsOpen = value;
433
+ const prev = this._isOpen;
434
+ this._isOpen = value;
427
435
  if (value && !prev) {
428
436
  this.onOverlayOpened();
429
437
  }
@@ -432,7 +440,7 @@ export class SearchOverlayComponent {
432
440
  }
433
441
  }
434
442
  get IsOpen() {
435
- return this._IsOpen;
443
+ return this._isOpen;
436
444
  }
437
445
  /** Debounce time in ms before search fires */
438
446
  DebounceMs = 400;
@@ -535,25 +543,25 @@ export class SearchOverlayComponent {
535
543
  this.ToggleOverlay();
536
544
  return;
537
545
  }
538
- if (this._IsOpen) {
546
+ if (this._isOpen) {
539
547
  this.handleOverlayKeydown(event);
540
548
  }
541
549
  }
542
550
  /** Toggle the overlay open/closed */
543
551
  ToggleOverlay() {
544
- this.IsOpen = !this._IsOpen;
545
- this.IsOpenChange.emit(this._IsOpen);
552
+ this.IsOpen = !this._isOpen;
553
+ this.IsOpenChange.emit(this._isOpen);
546
554
  }
547
555
  /** Open the overlay */
548
556
  Open() {
549
- if (!this._IsOpen) {
557
+ if (!this._isOpen) {
550
558
  this.IsOpen = true;
551
559
  this.IsOpenChange.emit(true);
552
560
  }
553
561
  }
554
562
  /** Close the overlay */
555
563
  Close() {
556
- if (this._IsOpen) {
564
+ if (this._isOpen) {
557
565
  this.IsOpen = false;
558
566
  this.IsOpenChange.emit(false);
559
567
  }
@@ -667,7 +675,7 @@ export class SearchOverlayComponent {
667
675
  // activation — preventDefault here at document level would
668
676
  // silently swallow it, or worse, open the highlighted result.
669
677
  const active = document.activeElement;
670
- const inCombobox = active === this.searchInputRef?.nativeElement
678
+ const inCombobox = active === this.SearchInputRef?.nativeElement
671
679
  || (active?.classList.contains('result-item') ?? false);
672
680
  if (!inCombobox) {
673
681
  return;
@@ -756,7 +764,7 @@ export class SearchOverlayComponent {
756
764
  */
757
765
  OnRecentSelect(query) {
758
766
  this.OnQueryInput(query);
759
- this.searchInputRef?.nativeElement?.focus();
767
+ this.SearchInputRef?.nativeElement?.focus();
760
768
  }
761
769
  /** Recent-search rows are keyboard-activatable (Enter/Space = click). */
762
770
  OnRecentKeydown(event, query) {
@@ -910,7 +918,7 @@ export class SearchOverlayComponent {
910
918
  this.previousFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null;
911
919
  // Focus input after view updates
912
920
  Promise.resolve().then(() => {
913
- this.searchInputRef?.nativeElement?.focus();
921
+ this.SearchInputRef?.nativeElement?.focus();
914
922
  this.cdr.detectChanges();
915
923
  });
916
924
  }
@@ -922,24 +930,36 @@ export class SearchOverlayComponent {
922
930
  this.previousFocus = null;
923
931
  }
924
932
  /** Check if any filters are active (used by template) */
925
- hasActiveFilters() {
933
+ HasActiveFilters() {
926
934
  return Object.values(this.ActiveFilters).some(v => v.length > 0);
927
935
  }
936
+ /** @deprecated Use {@link HasActiveFilters}. */
937
+ hasActiveFilters() {
938
+ return this.HasActiveFilters();
939
+ }
928
940
  /** Check if a result is currently keyboard-highlighted */
929
- isResultHighlighted(result) {
930
- const flatIndex = this.getFlatIndex(result);
941
+ IsResultHighlighted(result) {
942
+ const flatIndex = this.GetFlatIndex(result);
931
943
  return flatIndex === this.HighlightedIndex;
932
944
  }
945
+ /** @deprecated Use {@link IsResultHighlighted}. */
946
+ isResultHighlighted(result) {
947
+ return this.IsResultHighlighted(result);
948
+ }
933
949
  /** Get the flat index of a result for keyboard navigation */
934
- getFlatIndex(result) {
950
+ GetFlatIndex(result) {
935
951
  return this.FlatResults.indexOf(result);
936
952
  }
953
+ /** @deprecated Use {@link GetFlatIndex}. */
954
+ getFlatIndex(result) {
955
+ return this.GetFlatIndex(result);
956
+ }
937
957
  static ɵfac = function SearchOverlayComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || SearchOverlayComponent)(); };
938
958
  static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: SearchOverlayComponent, selectors: [["mj-search-overlay"]], viewQuery: function SearchOverlayComponent_Query(rf, ctx) { if (rf & 1) {
939
959
  i0.ɵɵviewQuery(_c0, 5);
940
960
  } if (rf & 2) {
941
961
  let _t;
942
- i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.searchInputRef = _t.first);
962
+ i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.SearchInputRef = _t.first);
943
963
  } }, hostBindings: function SearchOverlayComponent_HostBindings(rf, ctx) { if (rf & 1) {
944
964
  i0.ɵɵlistener("keydown", function SearchOverlayComponent_keydown_HostBindingHandler($event) { return ctx.HandleGlobalKeydown($event); }, i0.ɵɵresolveDocument);
945
965
  } }, inputs: { Placeholder: "Placeholder", MaxResults: "MaxResults", IsOpen: "IsOpen", DebounceMs: "DebounceMs", IncludeSources: "IncludeSources", ShowFilters: "ShowFilters", AgentCtaText: "AgentCtaText", ShowAgentCta: "ShowAgentCta", EnableStreaming: "EnableStreaming", EnableGlobalShortcut: "EnableGlobalShortcut", ShowPromo: "ShowPromo", PromoText: "PromoText", PromoActionLabel: "PromoActionLabel" }, outputs: { IsOpenChange: "IsOpenChange", ResultSelected: "ResultSelected", FilterChanged: "FilterChanged", SearchExecuted: "SearchExecuted", AgentCtaClicked: "AgentCtaClicked", SeeAllRequested: "SeeAllRequested", PromoAccepted: "PromoAccepted", PromoDismissed: "PromoDismissed" }, standalone: false, decls: 1, vars: 1, consts: [["searchInput", ""], [1, "search-backdrop", 3, "click"], ["role", "dialog", "aria-modal", "true", "aria-label", "Search", 1, "search-spotlight", 3, "click", "keydown"], [1, "search-input-wrap"], [1, "fa-solid", "fa-magnifying-glass", "search-icon"], ["type", "text", "role", "combobox", "aria-controls", "search-overlay-listbox", "aria-autocomplete", "list", "autocomplete", "off", "spellcheck", "false", 1, "search-input", 3, "input", "placeholder", "value"], [1, "search-spinner"], [1, "search-shortcut-hint"], ["type", "button", "aria-label", "Close", "title", "Close", 1, "search-close-btn", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "search-results-area"], ["aria-live", "polite", 1, "streaming-status-strip"], [1, "search-filter-bar"], ["Variant", "no-results", "Title", "No results found", "Message", "Try different keywords or remove some filters"], [1, "search-recent"], [1, "search-promo"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "streaming-chip", "streaming-chip-pending"], [1, "streaming-chip", 3, "streaming-chip-error", "streaming-chip-completed"], [1, "fa-solid", "fa-circle-notch", "fa-spin"], [1, "streaming-chip"], [1, "fa-solid", "fa-check"], [1, "fa-solid", "fa-triangle-exclamation"], [1, "streaming-chip-name"], [1, "streaming-chip-time"], [1, "streaming-chip-count"], [1, "filter-clear-btn"], [1, "filter-chip", 3, "filter-chip-active"], [1, "filter-chip", 3, "click"], [3, "class"], [1, "filter-chip-count"], [1, "filter-clear-btn", 3, "click"], [1, "fa-solid", "fa-times"], ["ngProjectAs", "[actions]", 5, ["", "actions", ""], 1, "agent-cta-btn"], ["ngProjectAs", "[actions]", 5, ["", "actions", ""], 1, "agent-cta-btn", 3, "click"], [1, "fa-solid", "fa-robot"], ["Variant", "no-results", "Title", "Start typing to search across all your knowledge", "Size", "compact"], [1, "search-recent-header"], [1, "search-recent-title"], ["role", "button", "tabindex", "0", 1, "search-recent-item"], ["role", "button", "tabindex", "0", 1, "search-recent-item", 3, "click", "keydown"], [1, "fa-solid", "fa-clock", "search-recent-icon"], [1, "search-recent-count"], ["id", "search-overlay-listbox", "role", "listbox", "aria-label", "Search results"], ["role", "presentation", 1, "result-group"], [1, "search-footer"], [1, "search-footer-count"], [1, "search-footer-actions"], ["type", "button", 1, "see-all-btn", 3, "click"], [1, "fa-solid", "fa-arrow-right"], [1, "agent-cta-btn", "agent-cta-btn-small"], ["role", "presentation", 1, "result-group-header"], [1, "result-group-label"], [1, "result-group-count"], ["role", "option", 1, "result-item", 3, "result-item-highlighted"], ["role", "option", 1, "result-item", 3, "click", "focus", "mouseenter"], [1, "result-item-icon"], [1, "result-item-content"], [1, "result-item-title"], [1, "result-item-snippet"], [1, "result-item-tags"], [1, "result-item-score"], [1, "score-badge"], [1, "result-tag"], [1, "agent-cta-btn", "agent-cta-btn-small", 3, "click"], [1, "fa-solid", "fa-wand-magic-sparkles", "search-promo-icon"], [1, "search-promo-text"], ["type", "button", 1, "search-promo-action", 3, "click"], ["type", "button", "aria-label", "Dismiss", "title", "Dismiss", 1, "search-promo-dismiss", 3, "click"]], template: function SearchOverlayComponent_Template(rf, ctx) { if (rf & 1) {
@@ -951,7 +971,7 @@ export class SearchOverlayComponent {
951
971
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SearchOverlayComponent, [{
952
972
  type: Component,
953
973
  args: [{ standalone: false, selector: 'mj-search-overlay', template: "@if (IsOpen) {\n <!-- Backdrop -->\n <div class=\"search-backdrop\" (click)=\"OnBackdropClick()\"></div>\n\n <!-- Spotlight container -->\n <div class=\"search-spotlight\" role=\"dialog\" aria-modal=\"true\" aria-label=\"Search\"\n (click)=\"$event.stopPropagation()\" (keydown)=\"OnSpotlightKeydown($event)\">\n <!-- Search input area -->\n <div class=\"search-input-wrap\">\n <i class=\"fa-solid fa-magnifying-glass search-icon\"></i>\n <input\n #searchInput\n type=\"text\"\n class=\"search-input\"\n role=\"combobox\"\n aria-controls=\"search-overlay-listbox\"\n aria-autocomplete=\"list\"\n [attr.aria-expanded]=\"AllResults.length > 0\"\n [attr.aria-activedescendant]=\"ActiveDescendantId\"\n [placeholder]=\"Placeholder\"\n [value]=\"Query\"\n (input)=\"OnQueryInput($any($event.target).value)\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n @if (IsSearching) {\n <div class=\"search-spinner\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n </div>\n }\n <div class=\"search-shortcut-hint\">\n <kbd>ESC</kbd>\n </div>\n <button type=\"button\" class=\"search-close-btn\" aria-label=\"Close\" title=\"Close\" (click)=\"Close()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n\n <!-- Results area -->\n <div class=\"search-results-area\">\n @if (EnableStreaming && (IsSearching || StreamingProviders.length > 0)) {\n <!-- Streaming status strip \u2014 one chip per provider that has reported -->\n <div class=\"streaming-status-strip\" aria-live=\"polite\">\n @if (StreamingProviders.length === 0 && IsSearching) {\n <span class=\"streaming-chip streaming-chip-pending\">\n <i class=\"fa-solid fa-circle-notch fa-spin\"></i>\n <span>Searching\u2026</span>\n </span>\n }\n @for (p of StreamingProviders; track p.Name) {\n <span class=\"streaming-chip\"\n [class.streaming-chip-error]=\"p.State === 'Error'\"\n [class.streaming-chip-completed]=\"p.State === 'Completed'\">\n @if (p.State === 'Completed') {\n <i class=\"fa-solid fa-check\"></i>\n } @else {\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n }\n <span class=\"streaming-chip-name\">{{ p.Name }}</span>\n @if (p.State === 'Completed') {\n <span class=\"streaming-chip-count\">{{ p.Count }}</span>\n <span class=\"streaming-chip-time\">{{ FormatElapsedTime(p.ElapsedMs) }}</span>\n } @else if (p.ErrorMessage) {\n <span class=\"streaming-chip-time\">{{ p.ErrorMessage }}</span>\n }\n </span>\n }\n </div>\n }\n @if (ShowFilters && Filters.length > 0) {\n <!-- Filter chips -->\n <div class=\"search-filter-bar\">\n @for (filter of Filters; track filter.Category) {\n @for (option of filter.Options; track option.Value) {\n <button\n class=\"filter-chip\"\n [class.filter-chip-active]=\"IsFilterActive(filter.Category, option.Value)\"\n (click)=\"OnFilterToggle(filter.Category, option.Value)\"\n >\n @if (option.Icon) {\n <i [class]=\"option.Icon\"></i>\n }\n <span>{{ option.Label }}</span>\n <span class=\"filter-chip-count\">{{ option.Count }}</span>\n </button>\n }\n }\n @if (hasActiveFilters()) {\n <button class=\"filter-clear-btn\" (click)=\"ClearAllFilters()\">\n <i class=\"fa-solid fa-times\"></i> Clear\n </button>\n }\n </div>\n }\n\n @if (HasSearched && AllResults.length === 0 && !IsSearching) {\n <!-- No results -->\n <mj-empty-state\n Variant=\"no-results\"\n Title=\"No results found\"\n Message=\"Try different keywords or remove some filters\">\n @if (ShowAgentCta) {\n <button ngProjectAs=\"[actions]\" class=\"agent-cta-btn\" (click)=\"OnAgentCtaClick()\">\n <i class=\"fa-solid fa-robot\"></i>\n {{ AgentCtaText }}\n </button>\n }\n </mj-empty-state>\n }\n\n @if (!HasSearched && !IsSearching) {\n <!-- Recent searches -->\n <div class=\"search-recent\">\n @if (searchService.RecentSearches$.value.length > 0) {\n <div class=\"search-recent-header\">\n <span class=\"search-recent-title\">Recent Searches</span>\n </div>\n @for (recent of searchService.RecentSearches$.value; track recent.Query; let i = $index) {\n @if (i < 5) {\n <div class=\"search-recent-item\" role=\"button\" tabindex=\"0\"\n (click)=\"OnRecentSelect(recent.Query)\"\n (keydown)=\"OnRecentKeydown($event, recent.Query)\">\n <i class=\"fa-solid fa-clock search-recent-icon\"></i>\n <span>{{ recent.Query }}</span>\n <span class=\"search-recent-count\">{{ recent.ResultCount }} results</span>\n </div>\n }\n }\n } @else {\n <mj-empty-state\n Variant=\"no-results\"\n Title=\"Start typing to search across all your knowledge\"\n Size=\"compact\" />\n }\n </div>\n }\n\n @if (AllResults.length > 0) {\n <!-- Grouped results -->\n <div id=\"search-overlay-listbox\" role=\"listbox\" aria-label=\"Search results\">\n @for (group of ResultGroups; track group.SourceType) {\n <div class=\"result-group\" role=\"presentation\">\n <div class=\"result-group-header\" role=\"presentation\">\n <i [class]=\"group.Icon\"></i>\n <span class=\"result-group-label\">{{ group.Label }}</span>\n <span class=\"result-group-count\">{{ group.TotalCount }}</span>\n </div>\n @for (result of group.Results; track result.ID; let ri = $index) {\n <div\n class=\"result-item\"\n role=\"option\"\n [attr.id]=\"'so-opt-' + getFlatIndex(result)\"\n [attr.tabindex]=\"isResultHighlighted(result) ? 0 : -1\"\n [attr.aria-selected]=\"isResultHighlighted(result)\"\n [class.result-item-highlighted]=\"isResultHighlighted(result)\"\n (click)=\"OnResultClick(result, $event)\"\n (focus)=\"HighlightedIndex = getFlatIndex(result)\"\n (mouseenter)=\"HighlightedIndex = getFlatIndex(result)\"\n >\n <div class=\"result-item-icon\">\n <i [class]=\"result.SourceIcon\"></i>\n </div>\n <div class=\"result-item-content\">\n <div class=\"result-item-title\">{{ result.Title }}</div>\n <div class=\"result-item-snippet\">{{ result.Snippet }}</div>\n @if (result.Tags.length > 0) {\n <div class=\"result-item-tags\">\n @for (tag of result.Tags; track tag; let ti = $index) {\n @if (ti < 3) {\n <span class=\"result-tag\">{{ tag }}</span>\n }\n }\n </div>\n }\n </div>\n <div class=\"result-item-score\">\n <span class=\"score-badge\">{{ FormatScore(result.Score) }}</span>\n </div>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Footer -->\n <div class=\"search-footer\">\n <span class=\"search-footer-count\">\n {{ TotalCount }} results in {{ FormatElapsedTime(ElapsedMs) }}\n </span>\n <div class=\"search-footer-actions\">\n <button type=\"button\" class=\"see-all-btn\" (click)=\"OnSeeAllClick()\">\n See all results\n <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n @if (ShowAgentCta) {\n <button class=\"agent-cta-btn agent-cta-btn-small\" (click)=\"OnAgentCtaClick()\">\n <i class=\"fa-solid fa-robot\"></i>\n {{ AgentCtaText }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Host-supplied promo strip (e.g. command palette nudge) -->\n @if (ShowPromo && PromoText) {\n <div class=\"search-promo\">\n <i class=\"fa-solid fa-wand-magic-sparkles search-promo-icon\"></i>\n <span class=\"search-promo-text\">{{ PromoText }}</span>\n <button type=\"button\" class=\"search-promo-action\" (click)=\"OnPromoAccept()\">{{ PromoActionLabel }}</button>\n <button type=\"button\" class=\"search-promo-dismiss\" aria-label=\"Dismiss\" title=\"Dismiss\" (click)=\"OnPromoDismiss()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n }\n </div>\n}\n", styles: ["/* Search Overlay - Command Palette / Spotlight Style */\n\n.search-backdrop {\n position: fixed;\n inset: 0;\n background: var(--mj-bg-overlay);\n backdrop-filter: blur(8px);\n z-index: 99998;\n animation: backdropFadeIn 0.2s ease;\n}\n\n@keyframes backdropFadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n.search-spotlight {\n position: fixed;\n top: 12%;\n left: 50%;\n transform: translateX(-50%);\n width: 680px;\n max-width: calc(100vw - 2rem);\n max-height: 70vh;\n z-index: 99999;\n display: flex;\n flex-direction: column;\n border-radius: var(--mj-radius-xl);\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-default);\n box-shadow: 0 25px 60px rgba(0, 0, 0, 0.3);\n overflow: hidden;\n animation: spotlightIn 0.25s ease;\n}\n\n@keyframes spotlightIn {\n from {\n opacity: 0;\n transform: translateX(-50%) translateY(-10px) scale(0.98);\n }\n to {\n opacity: 1;\n transform: translateX(-50%) translateY(0) scale(1);\n }\n}\n\n/* Search Input */\n.search-input-wrap {\n display: flex;\n align-items: center;\n padding: 0.75rem 1rem;\n border-bottom: 1px solid var(--mj-border-default);\n gap: 0.75rem;\n}\n\n.search-icon {\n color: var(--mj-brand-primary);\n font-size: 1.1rem;\n flex-shrink: 0;\n}\n\n.search-input {\n flex: 1;\n border: none;\n background: transparent;\n font-size: 1.1rem;\n color: var(--mj-text-primary);\n outline: none;\n font-family: inherit;\n}\n\n.search-input::placeholder {\n color: var(--mj-text-muted);\n}\n\n.search-spinner {\n color: var(--mj-brand-primary);\n font-size: 1rem;\n}\n\n.search-shortcut-hint kbd {\n display: inline-block;\n padding: 0.15rem 0.5rem;\n border-radius: 4px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n font-size: 0.75rem;\n font-family: inherit;\n}\n\n.search-close-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n padding: 0;\n border: none;\n border-radius: var(--mj-radius-full);\n background: transparent;\n color: var(--mj-text-muted);\n font-size: var(--mj-text-sm);\n cursor: pointer;\n transition: var(--mj-transition-colors);\n flex-shrink: 0;\n}\n\n.search-close-btn:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-primary);\n}\n\n/* Results Area */\n.search-results-area {\n overflow-y: auto;\n max-height: calc(70vh - 56px);\n}\n\n/* Filter Bar */\n.search-filter-bar {\n display: flex;\n flex-wrap: wrap;\n gap: 0.4rem;\n padding: 0.6rem 1rem;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.streaming-status-strip {\n display: flex;\n flex-wrap: wrap;\n gap: 0.4rem;\n padding: 0.5rem 1rem;\n border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.streaming-chip {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.2rem 0.55rem;\n border-radius: 9999px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.74rem;\n}\n\n.streaming-chip-pending {\n color: var(--mj-text-muted);\n}\n\n.streaming-chip-completed {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n border-color: var(--mj-status-success-border);\n color: var(--mj-status-success-text);\n}\n\n.streaming-chip-error {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-color: var(--mj-status-error-border);\n color: var(--mj-status-error-text);\n}\n\n.streaming-chip-name {\n font-weight: 500;\n}\n\n.streaming-chip-count {\n opacity: 0.7;\n}\n\n.streaming-chip-time {\n opacity: 0.6;\n font-size: 0.7rem;\n}\n\n.filter-chip {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.25rem 0.6rem;\n border-radius: 9999px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.78rem;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n\n.filter-chip:hover {\n border-color: var(--mj-brand-primary);\n color: var(--mj-text-primary);\n}\n\n.filter-chip-active {\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n\n.filter-chip-count {\n opacity: 0.6;\n font-size: 0.72rem;\n}\n\n.filter-clear-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n padding: 0.25rem 0.6rem;\n border-radius: 9999px;\n border: none;\n background: transparent;\n color: var(--mj-text-muted);\n font-size: 0.78rem;\n cursor: pointer;\n}\n\n.filter-clear-btn:hover {\n color: var(--mj-status-error);\n}\n\n/* Recent Searches */\n.search-recent {\n padding: 0.5rem 0;\n}\n\n.search-recent-header {\n padding: 0.5rem 1rem;\n}\n\n.search-recent-title {\n font-size: 0.75rem;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n font-weight: 600;\n}\n\n.search-recent-item {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.5rem 1rem;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 0.9rem;\n transition: background 0.1s ease;\n}\n\n.search-recent-item:hover {\n background: var(--mj-bg-surface-hover);\n}\n\n.search-recent-icon {\n font-size: 0.8rem;\n color: var(--mj-text-muted);\n}\n\n.search-recent-count {\n margin-left: auto;\n font-size: 0.75rem;\n color: var(--mj-text-muted);\n}\n\n/* Result Groups */\n.result-group {\n padding: 0.25rem 0;\n}\n\n.result-group-header {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 1rem;\n color: var(--mj-text-muted);\n font-size: 0.75rem;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n font-weight: 600;\n}\n\n.result-group-label {\n flex: 1;\n}\n\n.result-group-count {\n font-size: 0.72rem;\n color: var(--mj-text-disabled);\n}\n\n/* Result Items */\n.result-item {\n display: flex;\n align-items: flex-start;\n gap: 0.75rem;\n padding: 0.6rem 1rem;\n cursor: pointer;\n transition: background 0.1s ease;\n}\n\n.result-item:hover,\n.result-item-highlighted {\n background: var(--mj-bg-surface-hover);\n}\n\n/* Rows are focus stops (roving tabindex): the highlight background tracks focus,\n so suppress the default outline but keep a ring for keyboard :focus-visible. */\n.result-item:focus {\n outline: none;\n}\n.result-item:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: -2px;\n}\n.search-recent-item:focus-visible {\n outline: 2px solid var(--mj-border-focus);\n outline-offset: -2px;\n}\n\n.result-item-icon {\n width: 2rem;\n height: 2rem;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 8px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-brand-primary);\n font-size: 0.85rem;\n flex-shrink: 0;\n margin-top: 0.1rem;\n}\n\n.result-item-content {\n flex: 1;\n min-width: 0;\n}\n\n.result-item-title {\n color: var(--mj-text-primary);\n font-weight: 500;\n font-size: 0.9rem;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.result-item-snippet {\n color: var(--mj-text-muted);\n font-size: 0.8rem;\n line-height: 1.4;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n margin-top: 0.15rem;\n}\n\n.result-item-tags {\n display: flex;\n gap: 0.3rem;\n margin-top: 0.3rem;\n}\n\n.result-tag {\n display: inline-block;\n padding: 0.1rem 0.4rem;\n border-radius: 4px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-muted);\n font-size: 0.7rem;\n}\n\n.result-item-score {\n flex-shrink: 0;\n margin-top: 0.2rem;\n}\n\n.score-badge {\n display: inline-block;\n padding: 0.15rem 0.45rem;\n border-radius: 9999px;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n color: var(--mj-brand-primary);\n font-size: 0.72rem;\n font-weight: 600;\n}\n\n/* Footer */\n.search-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.5rem 1rem;\n border-top: 1px solid var(--mj-border-subtle);\n}\n\n.search-footer-count {\n color: var(--mj-text-muted);\n font-size: 0.78rem;\n}\n\n.search-footer-actions {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n}\n\n/* \"See all results\" \u2014 hand-off to the full Search Results workspace.\n Padding/font-size mirror the sibling .agent-cta-btn-small so the footer\n buttons read as one row. */\n.see-all-btn {\n display: inline-flex;\n align-items: center;\n gap: var(--mj-space-1-5);\n padding: 0.35rem 0.8rem;\n border-radius: var(--mj-radius-md);\n border: 1px solid var(--mj-border-default);\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 0.78rem;\n font-weight: var(--mj-font-medium);\n cursor: pointer;\n transition: var(--mj-transition-colors);\n}\n\n.see-all-btn:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n}\n\n/* Agent CTA Button */\n.agent-cta-btn {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.6rem 1.2rem;\n border-radius: 8px;\n border: none;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n font-size: 0.85rem;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.15s ease;\n}\n\n.agent-cta-btn:hover {\n background: var(--mj-brand-primary-hover);\n}\n\n.agent-cta-btn-small {\n padding: 0.35rem 0.8rem;\n font-size: 0.78rem;\n}\n\n/* Mobile responsive */\n@media (max-width: 640px) {\n .search-spotlight {\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n transform: none;\n width: 100%;\n max-width: 100%;\n height: 100dvh;\n max-height: 100dvh;\n border-radius: 0;\n animation: none; /* spotlightIn animates a translateX(-50%) that no longer applies */\n }\n\n /* Full-height sheet: results absorb all remaining space (container is flex-column). */\n .search-results-area {\n flex: 1;\n min-height: 0;\n max-height: none;\n }\n\n /* Filter chips: single scrollable row with breathing room \u2014 desktop spacing\n reads cramped and tall at phone widths. */\n .search-filter-bar {\n overflow-x: auto;\n flex-wrap: nowrap;\n -webkit-overflow-scrolling: touch;\n gap: 0.5rem;\n padding: 0.5rem 0.75rem;\n align-items: center;\n }\n\n .search-filter-bar .filter-chip,\n .search-filter-bar .filter-clear-btn {\n flex-shrink: 0; /* no squishing inside the scroll row */\n padding: 0.25rem 0.7rem;\n line-height: 1.2;\n font-size: 0.75rem;\n }\n\n /* Keyboard hint is meaningless on touch (parity with the palette). */\n .search-shortcut-hint {\n display: none;\n }\n\n /* Touch-friendly hit areas: the \u2715 close and the promo controls are primary\n interactive elements on a full-height touch sheet \u2014 a mis-hit on a tiny\n dismiss that lands on \"Turn on\" is the worst failure mode. */\n .search-close-btn {\n width: 40px;\n height: 40px;\n font-size: var(--mj-text-base);\n }\n .search-promo {\n gap: var(--mj-space-3);\n }\n .search-promo-action {\n padding: 0.6rem 1rem;\n }\n .search-promo-dismiss {\n width: 40px;\n height: 40px;\n font-size: var(--mj-text-sm);\n }\n}\n\n/* Host-supplied promo strip \u2014 a quiet whisper pinned to the overlay's bottom\n edge, never a banner. */\n.search-promo {\n display: flex;\n align-items: center;\n gap: var(--mj-space-2);\n padding: var(--mj-space-2) var(--mj-space-4);\n border-top: 1px solid var(--mj-border-subtle);\n background: var(--mj-bg-surface-card);\n font-size: 0.78rem;\n color: var(--mj-text-muted);\n}\n\n.search-promo-icon {\n color: var(--mj-brand-primary);\n flex-shrink: 0;\n}\n\n.search-promo-text {\n flex: 1;\n min-width: 0;\n}\n\n.search-promo-action {\n flex-shrink: 0;\n padding: 0.2rem 0.6rem;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md);\n background: transparent;\n color: var(--mj-brand-primary);\n font-size: 0.75rem;\n font-weight: var(--mj-font-medium);\n cursor: pointer;\n transition: var(--mj-transition-colors);\n}\n\n.search-promo-action:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 8%, var(--mj-bg-surface));\n border-color: var(--mj-brand-primary);\n}\n\n.search-promo-dismiss {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 22px;\n height: 22px;\n padding: 0;\n border: none;\n border-radius: var(--mj-radius-full);\n background: transparent;\n color: var(--mj-text-disabled);\n font-size: 0.75rem;\n cursor: pointer;\n transition: var(--mj-transition-colors);\n flex-shrink: 0;\n}\n\n.search-promo-dismiss:hover {\n background: var(--mj-bg-surface-hover);\n color: var(--mj-text-secondary);\n}\n"] }]
954
- }], null, { searchInputRef: [{
974
+ }], null, { SearchInputRef: [{
955
975
  type: ViewChild,
956
976
  args: ['searchInput']
957
977
  }], Placeholder: [{
@@ -1 +1 @@
1
- {"version":3,"file":"search-overlay.component.js","sourceRoot":"","sources":["../../src/lib/search-overlay.component.ts","../../src/lib/search-overlay.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Search Overlay Component\n *\n * A floating search overlay inspired by command palette / Spotlight style.\n * Triggered by Cmd+K (Mac) or Ctrl+K (Windows), appears as a centered\n * floating panel with backdrop blur, search input, and grouped results.\n *\n * Supports keyboard navigation (up/down/enter/escape), filter facets,\n * and responsive mobile layout.\n */\n\nimport {\n Component,\n EventEmitter,\n HostListener,\n Input,\n OnDestroy,\n OnInit,\n Output,\n ChangeDetectorRef,\n ElementRef,\n ViewChild,\n inject\n} from '@angular/core';\nimport { Subject, Subscription } from 'rxjs';\nimport { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';\nimport { SearchService } from './search.service';\nimport {\n SearchResultItem,\n SearchResultGroup,\n SearchFilter,\n SearchRequest,\n SearchResultSelectedEvent,\n SearchFilterChangeEvent,\n SearchExecutedEvent,\n} from './search-types';\n\n/**\n * Per-provider streaming status displayed above the results list while a streaming\n * search is in flight. One entry per provider that has reported back. Populated\n * progressively as `streamScopedSearch` emits 'provider' events.\n */\nexport interface StreamingProviderStatus {\n /** Provider name from the SearchEngine (e.g. 'Vector', 'FullText') */\n Name: string;\n /** Result count contributed by this provider */\n Count: number;\n /** Wall-clock latency for this provider's leg, in milliseconds */\n ElapsedMs: number;\n /** Reported state for this provider */\n State: 'Completed' | 'Error';\n /** Last error message if State is 'Error' */\n ErrorMessage?: string;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-search-overlay',\n templateUrl: './search-overlay.component.html',\n styleUrls: ['./search-overlay.component.css']\n})\nexport class SearchOverlayComponent implements OnInit, OnDestroy {\n private cdr = inject(ChangeDetectorRef);\n protected searchService = inject(SearchService);\n private destroy$ = new Subject<void>();\n private searchInput$ = new Subject<string>();\n\n @ViewChild('searchInput') searchInputRef!: ElementRef<HTMLInputElement>;\n\n // --- Configuration Inputs ---\n\n /** Placeholder text for the search input */\n @Input() Placeholder = 'Search across all your knowledge...';\n\n /**\n * Maximum number of results to fetch and display. Deliberately small — the\n * overlay is a quick-jump surface; \"See all results\" hands off to the full\n * Search Results workspace for anything deeper. 8 matches the omnibar\n * palette's RESULT count (it fetches 9 rows = 8 results + its see-all row;\n * this overlay's see-all is a footer button, not a row).\n */\n @Input() MaxResults = 8;\n\n /** Whether the overlay is currently visible */\n private _IsOpen = false;\n\n @Input()\n set IsOpen(value: boolean) {\n const prev = this._IsOpen;\n this._IsOpen = value;\n if (value && !prev) {\n this.onOverlayOpened();\n }\n if (!value && prev) {\n this.onOverlayClosed();\n }\n }\n get IsOpen(): boolean {\n return this._IsOpen;\n }\n\n /** Debounce time in ms before search fires */\n @Input() DebounceMs = 400;\n\n /** Which search sources to include */\n @Input() IncludeSources: ('vector' | 'fulltext' | 'entity')[] = ['vector', 'fulltext', 'entity'];\n\n /** Whether to show filter facets */\n @Input() ShowFilters = true;\n\n /** Text for the agent CTA button */\n @Input() AgentCtaText = 'Ask Knowledge Agent';\n\n /** Whether to show the agent CTA */\n @Input() ShowAgentCta = true;\n\n /**\n * When true, the overlay subscribes to `SearchService.StreamSearch` instead of awaiting\n * `ExecuteSearch`. Results render progressively as each provider reports back. The\n * per-provider status chip strip becomes visible while the stream is in flight.\n * Defaults to false to preserve the request-response UX that shipped in Phase 1.\n */\n @Input() EnableStreaming = false;\n\n /**\n * When false, the overlay does NOT claim the global Ctrl/Cmd+K chord. For hosts\n * (e.g. the Explorer shell) that own that shortcut themselves and open the\n * overlay programmatically — two listeners on the same chord would double-toggle.\n * Escape/arrow handling while open is unaffected.\n */\n @Input() EnableGlobalShortcut = true;\n\n /**\n * Optional promo strip pinned to the overlay's bottom edge — a host-supplied\n * nudge (e.g. Explorer advertising its command palette). The component is\n * deliberately ignorant of WHAT is being promoted; the host provides the\n * copy and handles both outcomes.\n */\n @Input() ShowPromo = false;\n\n /** Promo copy (one sentence). Required when ShowPromo is true. */\n @Input() PromoText = '';\n\n /** Label for the promo's accept action. */\n @Input() PromoActionLabel = 'Turn on';\n\n // --- Outputs ---\n\n @Output() IsOpenChange = new EventEmitter<boolean>();\n @Output() ResultSelected = new EventEmitter<SearchResultSelectedEvent>();\n @Output() FilterChanged = new EventEmitter<SearchFilterChangeEvent>();\n @Output() SearchExecuted = new EventEmitter<SearchExecutedEvent>();\n @Output() AgentCtaClicked = new EventEmitter<string>();\n /**\n * Emitted when the user clicks \"See all results\" — carries the current query.\n * Hosts (e.g. the Explorer shell) open the full Search Results workspace,\n * which has scopes, relevance controls, and richer result actions than this\n * capped quick-jump overlay. The overlay closes itself after emitting.\n */\n @Output() SeeAllRequested = new EventEmitter<string>();\n /** Promo accept — carries the current query so the host can hand it off. */\n @Output() PromoAccepted = new EventEmitter<string>();\n /** Promo dismissed — the host should persist this and stop showing it. */\n @Output() PromoDismissed = new EventEmitter<void>();\n\n // --- Component State ---\n\n public Query = '';\n public IsSearching = false;\n public ResultGroups: SearchResultGroup[] = [];\n public AllResults: SearchResultItem[] = [];\n public Filters: SearchFilter[] = [];\n public ActiveFilters: Record<string, string[]> = {};\n public TotalCount = 0;\n public ElapsedMs = 0;\n public HighlightedIndex = -1;\n public HasSearched = false;\n private searchVersion = 0;\n\n /**\n * Per-provider status entries shown above the results list while a streaming search\n * is in flight. One entry per provider that has reported back. Empty when the user\n * is not running a streaming search (or when `EnableStreaming` is false).\n */\n public StreamingProviders: StreamingProviderStatus[] = [];\n\n /** Active stream subscription so we can cancel on a new search or destroy. */\n private currentStream: Subscription | null = null;\n\n /** Element focused before the overlay opened — restored on close (a11y). */\n private previousFocus: HTMLElement | null = null;\n\n /** All results flattened for keyboard navigation */\n public get FlatResults(): SearchResultItem[] {\n return this.AllResults;\n }\n\n /** id of the highlighted option, announced via aria-activedescendant. */\n public get ActiveDescendantId(): string | null {\n return this.HighlightedIndex >= 0 && this.HighlightedIndex < this.FlatResults.length\n ? `so-opt-${this.HighlightedIndex}`\n : null;\n }\n\n ngOnInit(): void {\n this.setupSearchDebounce();\n this.subscribeToSearchState();\n }\n\n ngOnDestroy(): void {\n this.currentStream?.unsubscribe();\n this.currentStream = null;\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // --- Keyboard shortcuts ---\n\n @HostListener('document:keydown', ['$event'])\n HandleGlobalKeydown(event: KeyboardEvent): void {\n if (this.EnableGlobalShortcut && this.isToggleShortcut(event)) {\n event.preventDefault();\n this.ToggleOverlay();\n return;\n }\n if (this._IsOpen) {\n this.handleOverlayKeydown(event);\n }\n }\n\n /** Toggle the overlay open/closed */\n public ToggleOverlay(): void {\n this.IsOpen = !this._IsOpen;\n this.IsOpenChange.emit(this._IsOpen);\n }\n\n /** Open the overlay */\n public Open(): void {\n if (!this._IsOpen) {\n this.IsOpen = true;\n this.IsOpenChange.emit(true);\n }\n }\n\n /** Close the overlay */\n public Close(): void {\n if (this._IsOpen) {\n this.IsOpen = false;\n this.IsOpenChange.emit(false);\n }\n }\n\n /** Handle query input changes */\n public OnQueryInput(value: string): void {\n this.Query = value;\n this.searchInput$.next(value);\n }\n\n /** Handle clicking a result */\n public OnResultClick(result: SearchResultItem, event: MouseEvent): void {\n this.ResultSelected.emit({\n Result: result,\n OpenInNewTab: event.metaKey || event.ctrlKey\n });\n this.Close();\n }\n\n /** Handle selecting the highlighted result */\n public SelectHighlighted(): void {\n if (this.HighlightedIndex >= 0 && this.HighlightedIndex < this.FlatResults.length) {\n this.ResultSelected.emit({\n Result: this.FlatResults[this.HighlightedIndex],\n OpenInNewTab: false\n });\n this.Close();\n }\n }\n\n /** Handle filter option toggle */\n public OnFilterToggle(category: string, value: string): void {\n const current = this.ActiveFilters[category] ?? [];\n const index = current.indexOf(value);\n if (index >= 0) {\n current.splice(index, 1);\n } else {\n current.push(value);\n }\n this.ActiveFilters[category] = current;\n this.FilterChanged.emit({ Category: category, SelectedValues: current });\n this.executeSearch();\n }\n\n /** Clear all active filters */\n public ClearAllFilters(): void {\n this.ActiveFilters = {};\n this.executeSearch();\n }\n\n /** Handle clicking the agent CTA */\n public OnAgentCtaClick(): void {\n this.AgentCtaClicked.emit(this.Query);\n this.Close();\n }\n\n /** Promo accept: emit the current query and close — the host takes over. */\n public OnPromoAccept(): void {\n this.PromoAccepted.emit(this.Query.trim());\n this.Close();\n }\n\n /** Promo dismiss: the host persists the dismissal; hide it immediately. */\n public OnPromoDismiss(): void {\n this.ShowPromo = false;\n this.PromoDismissed.emit();\n }\n\n /** Handle clicking \"See all results\" — hand off to the full Search workspace */\n public OnSeeAllClick(): void {\n const query = this.Query.trim();\n if (query.length > 0) {\n this.SeeAllRequested.emit(query);\n }\n this.Close();\n }\n\n /** Handle clicking the backdrop to close */\n public OnBackdropClick(): void {\n this.Close();\n }\n\n /** Check if a filter option is active */\n public IsFilterActive(category: string, value: string): boolean {\n return (this.ActiveFilters[category] ?? []).includes(value);\n }\n\n /** Get a score display value (percentage) */\n public FormatScore(score: number): string {\n return `${Math.round(score * 100)}%`;\n }\n\n /** Format elapsed time display */\n public FormatElapsedTime(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n }\n return `${(ms / 1000).toFixed(1)}s`;\n }\n\n // --- Private Methods ---\n\n private isToggleShortcut(event: KeyboardEvent): boolean {\n return (event.metaKey || event.ctrlKey) && event.key === 'k';\n }\n\n private handleOverlayKeydown(event: KeyboardEvent): void {\n switch (event.key) {\n case 'Escape':\n event.preventDefault();\n this.Close();\n break;\n case 'ArrowDown':\n event.preventDefault();\n this.moveHighlight(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n this.moveHighlight(-1);\n break;\n case 'Enter': {\n // Only claim Enter when it belongs to the combobox model (typing in\n // the input / a focused result row). A focused BUTTON (close,\n // see-all, filter chip, promo) must keep its native Enter\n // activation — preventDefault here at document level would\n // silently swallow it, or worse, open the highlighted result.\n const active = document.activeElement as HTMLElement | null;\n const inCombobox = active === this.searchInputRef?.nativeElement\n || (active?.classList.contains('result-item') ?? false);\n if (!inCombobox) {\n return;\n }\n event.preventDefault();\n this.SelectHighlighted();\n break;\n }\n }\n }\n\n private moveHighlight(direction: number): void {\n const maxIndex = this.FlatResults.length - 1;\n if (maxIndex < 0) return;\n\n // If a result row currently holds DOM focus (roving tabindex), keep focus\n // travelling with the highlight; from the input, only the highlight moves.\n const rowHadFocus = document.activeElement instanceof HTMLElement\n && document.activeElement.classList.contains('result-item');\n\n this.HighlightedIndex += direction;\n if (this.HighlightedIndex < 0) {\n this.HighlightedIndex = maxIndex;\n } else if (this.HighlightedIndex > maxIndex) {\n this.HighlightedIndex = 0;\n }\n this.cdr.detectChanges();\n\n // Keyboard-driven moves keep the highlighted row visible. Mouse hover sets\n // HighlightedIndex directly in the template and deliberately does NOT\n // scroll — auto-scrolling under the pointer fights the user's hand.\n const row = document.getElementById(`so-opt-${this.HighlightedIndex}`);\n row?.scrollIntoView({ block: 'nearest' });\n if (rowHadFocus) {\n row?.focus();\n }\n }\n\n /**\n * Tab behavior inside the dialog:\n * - On a result row, Tab / Shift+Tab step through the RESULTS themselves\n * (mirrors ArrowDown/Up) until walking off either end of the list — then\n * focus continues to the footer actions / back to the earlier controls.\n * - Everywhere else, Tab wraps within the dialog (focus trap): input → close\n * → filter chips → results → footer actions → back to the input.\n * Escape is handled by the document-level keydown.\n */\n public OnSpotlightKeydown(event: KeyboardEvent): void {\n if (event.key !== 'Tab') {\n return;\n }\n const activeEl = document.activeElement as HTMLElement | null;\n if (activeEl?.classList.contains('result-item')) {\n const last = this.FlatResults.length - 1;\n if (!event.shiftKey && this.HighlightedIndex < last) {\n event.preventDefault();\n this.moveHighlight(1); // row has focus, so focus travels with it\n return;\n }\n if (event.shiftKey && this.HighlightedIndex > 0) {\n event.preventDefault();\n this.moveHighlight(-1);\n return;\n }\n // At either end: fall through so Tab leaves the list naturally.\n }\n const root = (event.currentTarget as HTMLElement) ?? null;\n if (!root) {\n return;\n }\n const focusables = Array.from(\n root.querySelectorAll<HTMLElement>('input, button, .result-item[tabindex=\"0\"], .search-recent-item[tabindex=\"0\"]')\n ).filter((el) => el.offsetParent !== null);\n if (focusables.length === 0) {\n return;\n }\n const active = document.activeElement as HTMLElement | null;\n if (!event.shiftKey && active === focusables[focusables.length - 1]) {\n event.preventDefault();\n focusables[0].focus();\n } else if (event.shiftKey && active === focusables[0]) {\n event.preventDefault();\n focusables[focusables.length - 1].focus();\n }\n }\n\n /**\n * Recent-search row activated (click or Enter/Space). Re-runs the search AND\n * refocuses the input — the activated row leaves the DOM when recents are\n * replaced by results, which would otherwise drop focus to <body>.\n */\n public OnRecentSelect(query: string): void {\n this.OnQueryInput(query);\n this.searchInputRef?.nativeElement?.focus();\n }\n\n /** Recent-search rows are keyboard-activatable (Enter/Space = click). */\n public OnRecentKeydown(event: KeyboardEvent, query: string): void {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n this.OnRecentSelect(query);\n }\n }\n\n private setupSearchDebounce(): void {\n this.searchInput$\n .pipe(\n debounceTime(this.DebounceMs),\n distinctUntilChanged(),\n takeUntil(this.destroy$)\n )\n .subscribe(() => this.executeSearch());\n }\n\n private subscribeToSearchState(): void {\n this.searchService.IsSearching$\n .pipe(takeUntil(this.destroy$))\n .subscribe(val => {\n this.IsSearching = val;\n this.cdr.detectChanges();\n });\n }\n\n private async executeSearch(): Promise<void> {\n const query = this.Query.trim();\n if (!query) {\n this.clearResults();\n return;\n }\n\n const version = ++this.searchVersion;\n\n const request: SearchRequest = {\n Query: query,\n MaxResults: this.MaxResults,\n ActiveFilters: this.ActiveFilters,\n IncludeSources: this.IncludeSources,\n };\n\n if (this.EnableStreaming) {\n this.executeStreamingSearch(query, request, version);\n return;\n }\n\n const response = await this.searchService.ExecuteSearch(request);\n\n // Discard results if a newer search was triggered while this one was in-flight\n if (version !== this.searchVersion) {\n return;\n }\n\n this.AllResults = response.Results;\n this.ResultGroups = response.Groups;\n this.Filters = response.Filters;\n this.TotalCount = response.TotalCount;\n this.ElapsedMs = response.ElapsedMs;\n this.HasSearched = true;\n this.HighlightedIndex = response.Results.length > 0 ? 0 : -1;\n\n this.SearchExecuted.emit({\n Query: query,\n Filters: this.ActiveFilters,\n ResultCount: response.TotalCount,\n ElapsedMs: response.ElapsedMs,\n });\n\n this.cdr.detectChanges();\n }\n\n /**\n * Streaming variant of executeSearch — subscribes to `SearchService.StreamSearch` and\n * progressively updates the result list as each provider reports back. The 'final'\n * event carries the canonical fused/reranked list, which replaces the partials.\n *\n * Cancellation: a new search invocation tears down the in-flight stream via\n * `searchVersion` and `currentStream.unsubscribe()`.\n */\n private executeStreamingSearch(query: string, request: SearchRequest, version: number): void {\n // Tear down any prior stream so we don't get cross-talk between consecutive queries.\n this.currentStream?.unsubscribe();\n this.currentStream = null;\n\n // Reset visible state for a fresh stream.\n this.StreamingProviders = [];\n this.AllResults = [];\n this.ResultGroups = [];\n this.TotalCount = 0;\n this.ElapsedMs = 0;\n this.HasSearched = true;\n this.HighlightedIndex = -1;\n this.cdr.detectChanges();\n\n this.currentStream = this.searchService.StreamSearch(request).subscribe({\n next: (event) => {\n if (version !== this.searchVersion) return;\n\n if (event.Phase === 'provider' && event.ProviderName) {\n const count = event.Results?.length ?? 0;\n this.StreamingProviders = [\n ...this.StreamingProviders,\n {\n Name: event.ProviderName,\n Count: count,\n ElapsedMs: event.ElapsedMs ?? 0,\n State: 'Completed',\n },\n ];\n if (event.Results && event.Results.length > 0) {\n // Append partials so the user sees the list grow as providers return.\n this.AllResults = [...this.AllResults, ...event.Results];\n this.ResultGroups = this.searchService.GroupResults(this.AllResults);\n this.TotalCount = this.AllResults.length;\n if (this.HighlightedIndex < 0) {\n this.HighlightedIndex = 0;\n }\n }\n } else if (event.Phase === 'final' && event.Results) {\n // Replace the appended partials with the canonical fused/reranked list.\n this.AllResults = event.Results;\n this.ResultGroups = this.searchService.GroupResults(this.AllResults);\n this.Filters = this.searchService.BuildFilters(this.AllResults);\n this.TotalCount = event.Results.length;\n this.ElapsedMs = event.ElapsedMs ?? this.ElapsedMs;\n this.HighlightedIndex = event.Results.length > 0 ? 0 : -1;\n }\n\n this.cdr.detectChanges();\n },\n error: (err: Error) => {\n if (version !== this.searchVersion) return;\n this.StreamingProviders = [\n ...this.StreamingProviders,\n { Name: 'stream', Count: 0, ElapsedMs: 0, State: 'Error', ErrorMessage: err.message },\n ];\n this.cdr.detectChanges();\n },\n complete: () => {\n if (version !== this.searchVersion) return;\n this.SearchExecuted.emit({\n Query: query,\n Filters: this.ActiveFilters,\n ResultCount: this.TotalCount,\n ElapsedMs: this.ElapsedMs,\n });\n this.cdr.detectChanges();\n },\n });\n }\n\n private clearResults(): void {\n this.AllResults = [];\n this.ResultGroups = [];\n this.Filters = [];\n this.TotalCount = 0;\n this.ElapsedMs = 0;\n this.HasSearched = false;\n this.HighlightedIndex = -1;\n this.cdr.detectChanges();\n }\n\n private onOverlayOpened(): void {\n // Remember what had focus so Close() can hand it back (a11y: the overlay\n // is a modal dialog — focus must return to the summoning control).\n this.previousFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null;\n // Focus input after view updates\n Promise.resolve().then(() => {\n this.searchInputRef?.nativeElement?.focus();\n this.cdr.detectChanges();\n });\n }\n\n private onOverlayClosed(): void {\n this.HighlightedIndex = -1;\n if (this.previousFocus?.isConnected) {\n this.previousFocus.focus();\n }\n this.previousFocus = null;\n }\n\n /** Check if any filters are active (used by template) */\n public hasActiveFilters(): boolean {\n return Object.values(this.ActiveFilters).some(v => v.length > 0);\n }\n\n /** Check if a result is currently keyboard-highlighted */\n public isResultHighlighted(result: SearchResultItem): boolean {\n const flatIndex = this.getFlatIndex(result);\n return flatIndex === this.HighlightedIndex;\n }\n\n /** Get the flat index of a result for keyboard navigation */\n public getFlatIndex(result: SearchResultItem): number {\n return this.FlatResults.indexOf(result);\n }\n}\n","@if (IsOpen) {\n <!-- Backdrop -->\n <div class=\"search-backdrop\" (click)=\"OnBackdropClick()\"></div>\n\n <!-- Spotlight container -->\n <div class=\"search-spotlight\" role=\"dialog\" aria-modal=\"true\" aria-label=\"Search\"\n (click)=\"$event.stopPropagation()\" (keydown)=\"OnSpotlightKeydown($event)\">\n <!-- Search input area -->\n <div class=\"search-input-wrap\">\n <i class=\"fa-solid fa-magnifying-glass search-icon\"></i>\n <input\n #searchInput\n type=\"text\"\n class=\"search-input\"\n role=\"combobox\"\n aria-controls=\"search-overlay-listbox\"\n aria-autocomplete=\"list\"\n [attr.aria-expanded]=\"AllResults.length > 0\"\n [attr.aria-activedescendant]=\"ActiveDescendantId\"\n [placeholder]=\"Placeholder\"\n [value]=\"Query\"\n (input)=\"OnQueryInput($any($event.target).value)\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n @if (IsSearching) {\n <div class=\"search-spinner\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n </div>\n }\n <div class=\"search-shortcut-hint\">\n <kbd>ESC</kbd>\n </div>\n <button type=\"button\" class=\"search-close-btn\" aria-label=\"Close\" title=\"Close\" (click)=\"Close()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n\n <!-- Results area -->\n <div class=\"search-results-area\">\n @if (EnableStreaming && (IsSearching || StreamingProviders.length > 0)) {\n <!-- Streaming status strip — one chip per provider that has reported -->\n <div class=\"streaming-status-strip\" aria-live=\"polite\">\n @if (StreamingProviders.length === 0 && IsSearching) {\n <span class=\"streaming-chip streaming-chip-pending\">\n <i class=\"fa-solid fa-circle-notch fa-spin\"></i>\n <span>Searching…</span>\n </span>\n }\n @for (p of StreamingProviders; track p.Name) {\n <span class=\"streaming-chip\"\n [class.streaming-chip-error]=\"p.State === 'Error'\"\n [class.streaming-chip-completed]=\"p.State === 'Completed'\">\n @if (p.State === 'Completed') {\n <i class=\"fa-solid fa-check\"></i>\n } @else {\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n }\n <span class=\"streaming-chip-name\">{{ p.Name }}</span>\n @if (p.State === 'Completed') {\n <span class=\"streaming-chip-count\">{{ p.Count }}</span>\n <span class=\"streaming-chip-time\">{{ FormatElapsedTime(p.ElapsedMs) }}</span>\n } @else if (p.ErrorMessage) {\n <span class=\"streaming-chip-time\">{{ p.ErrorMessage }}</span>\n }\n </span>\n }\n </div>\n }\n @if (ShowFilters && Filters.length > 0) {\n <!-- Filter chips -->\n <div class=\"search-filter-bar\">\n @for (filter of Filters; track filter.Category) {\n @for (option of filter.Options; track option.Value) {\n <button\n class=\"filter-chip\"\n [class.filter-chip-active]=\"IsFilterActive(filter.Category, option.Value)\"\n (click)=\"OnFilterToggle(filter.Category, option.Value)\"\n >\n @if (option.Icon) {\n <i [class]=\"option.Icon\"></i>\n }\n <span>{{ option.Label }}</span>\n <span class=\"filter-chip-count\">{{ option.Count }}</span>\n </button>\n }\n }\n @if (hasActiveFilters()) {\n <button class=\"filter-clear-btn\" (click)=\"ClearAllFilters()\">\n <i class=\"fa-solid fa-times\"></i> Clear\n </button>\n }\n </div>\n }\n\n @if (HasSearched && AllResults.length === 0 && !IsSearching) {\n <!-- No results -->\n <mj-empty-state\n Variant=\"no-results\"\n Title=\"No results found\"\n Message=\"Try different keywords or remove some filters\">\n @if (ShowAgentCta) {\n <button ngProjectAs=\"[actions]\" class=\"agent-cta-btn\" (click)=\"OnAgentCtaClick()\">\n <i class=\"fa-solid fa-robot\"></i>\n {{ AgentCtaText }}\n </button>\n }\n </mj-empty-state>\n }\n\n @if (!HasSearched && !IsSearching) {\n <!-- Recent searches -->\n <div class=\"search-recent\">\n @if (searchService.RecentSearches$.value.length > 0) {\n <div class=\"search-recent-header\">\n <span class=\"search-recent-title\">Recent Searches</span>\n </div>\n @for (recent of searchService.RecentSearches$.value; track recent.Query; let i = $index) {\n @if (i < 5) {\n <div class=\"search-recent-item\" role=\"button\" tabindex=\"0\"\n (click)=\"OnRecentSelect(recent.Query)\"\n (keydown)=\"OnRecentKeydown($event, recent.Query)\">\n <i class=\"fa-solid fa-clock search-recent-icon\"></i>\n <span>{{ recent.Query }}</span>\n <span class=\"search-recent-count\">{{ recent.ResultCount }} results</span>\n </div>\n }\n }\n } @else {\n <mj-empty-state\n Variant=\"no-results\"\n Title=\"Start typing to search across all your knowledge\"\n Size=\"compact\" />\n }\n </div>\n }\n\n @if (AllResults.length > 0) {\n <!-- Grouped results -->\n <div id=\"search-overlay-listbox\" role=\"listbox\" aria-label=\"Search results\">\n @for (group of ResultGroups; track group.SourceType) {\n <div class=\"result-group\" role=\"presentation\">\n <div class=\"result-group-header\" role=\"presentation\">\n <i [class]=\"group.Icon\"></i>\n <span class=\"result-group-label\">{{ group.Label }}</span>\n <span class=\"result-group-count\">{{ group.TotalCount }}</span>\n </div>\n @for (result of group.Results; track result.ID; let ri = $index) {\n <div\n class=\"result-item\"\n role=\"option\"\n [attr.id]=\"'so-opt-' + getFlatIndex(result)\"\n [attr.tabindex]=\"isResultHighlighted(result) ? 0 : -1\"\n [attr.aria-selected]=\"isResultHighlighted(result)\"\n [class.result-item-highlighted]=\"isResultHighlighted(result)\"\n (click)=\"OnResultClick(result, $event)\"\n (focus)=\"HighlightedIndex = getFlatIndex(result)\"\n (mouseenter)=\"HighlightedIndex = getFlatIndex(result)\"\n >\n <div class=\"result-item-icon\">\n <i [class]=\"result.SourceIcon\"></i>\n </div>\n <div class=\"result-item-content\">\n <div class=\"result-item-title\">{{ result.Title }}</div>\n <div class=\"result-item-snippet\">{{ result.Snippet }}</div>\n @if (result.Tags.length > 0) {\n <div class=\"result-item-tags\">\n @for (tag of result.Tags; track tag; let ti = $index) {\n @if (ti < 3) {\n <span class=\"result-tag\">{{ tag }}</span>\n }\n }\n </div>\n }\n </div>\n <div class=\"result-item-score\">\n <span class=\"score-badge\">{{ FormatScore(result.Score) }}</span>\n </div>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Footer -->\n <div class=\"search-footer\">\n <span class=\"search-footer-count\">\n {{ TotalCount }} results in {{ FormatElapsedTime(ElapsedMs) }}\n </span>\n <div class=\"search-footer-actions\">\n <button type=\"button\" class=\"see-all-btn\" (click)=\"OnSeeAllClick()\">\n See all results\n <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n @if (ShowAgentCta) {\n <button class=\"agent-cta-btn agent-cta-btn-small\" (click)=\"OnAgentCtaClick()\">\n <i class=\"fa-solid fa-robot\"></i>\n {{ AgentCtaText }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Host-supplied promo strip (e.g. command palette nudge) -->\n @if (ShowPromo && PromoText) {\n <div class=\"search-promo\">\n <i class=\"fa-solid fa-wand-magic-sparkles search-promo-icon\"></i>\n <span class=\"search-promo-text\">{{ PromoText }}</span>\n <button type=\"button\" class=\"search-promo-action\" (click)=\"OnPromoAccept()\">{{ PromoActionLabel }}</button>\n <button type=\"button\" class=\"search-promo-dismiss\" aria-label=\"Dismiss\" title=\"Dismiss\" (click)=\"OnPromoDismiss()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n }\n </div>\n}\n"]}
1
+ {"version":3,"file":"search-overlay.component.js","sourceRoot":"","sources":["../../src/lib/search-overlay.component.ts","../../src/lib/search-overlay.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Search Overlay Component\n *\n * A floating search overlay inspired by command palette / Spotlight style.\n * Triggered by Cmd+K (Mac) or Ctrl+K (Windows), appears as a centered\n * floating panel with backdrop blur, search input, and grouped results.\n *\n * Supports keyboard navigation (up/down/enter/escape), filter facets,\n * and responsive mobile layout.\n */\n\nimport {\n Component,\n EventEmitter,\n HostListener,\n Input,\n OnDestroy,\n OnInit,\n Output,\n ChangeDetectorRef,\n ElementRef,\n ViewChild,\n inject\n} from '@angular/core';\nimport { Subject, Subscription } from 'rxjs';\nimport { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';\nimport { SearchService } from './search.service';\nimport {\n SearchResultItem,\n SearchResultGroup,\n SearchFilter,\n SearchRequest,\n SearchResultSelectedEvent,\n SearchFilterChangeEvent,\n SearchExecutedEvent,\n} from './search-types';\n\n/**\n * Per-provider streaming status displayed above the results list while a streaming\n * search is in flight. One entry per provider that has reported back. Populated\n * progressively as `streamScopedSearch` emits 'provider' events.\n */\nexport interface StreamingProviderStatus {\n /** Provider name from the SearchEngine (e.g. 'Vector', 'FullText') */\n Name: string;\n /** Result count contributed by this provider */\n Count: number;\n /** Wall-clock latency for this provider's leg, in milliseconds */\n ElapsedMs: number;\n /** Reported state for this provider */\n State: 'Completed' | 'Error';\n /** Last error message if State is 'Error' */\n ErrorMessage?: string;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-search-overlay',\n templateUrl: './search-overlay.component.html',\n styleUrls: ['./search-overlay.component.css']\n})\nexport class SearchOverlayComponent implements OnInit, OnDestroy {\n private cdr = inject(ChangeDetectorRef);\n protected searchService = inject(SearchService);\n private destroy$ = new Subject<void>();\n private searchInput$ = new Subject<string>();\n\n @ViewChild('searchInput') SearchInputRef!: ElementRef<HTMLInputElement>;\n\n /** @deprecated Use {@link SearchInputRef}. */\n get searchInputRef(): ElementRef<HTMLInputElement> {\n return this.SearchInputRef;\n }\n /** @deprecated Use {@link SearchInputRef}. */\n set searchInputRef(value: ElementRef<HTMLInputElement>) {\n this.SearchInputRef = value;\n }\n\n // --- Configuration Inputs ---\n\n /** Placeholder text for the search input */\n @Input() Placeholder = 'Search across all your knowledge...';\n\n /**\n * Maximum number of results to fetch and display. Deliberately small — the\n * overlay is a quick-jump surface; \"See all results\" hands off to the full\n * Search Results workspace for anything deeper. 8 matches the omnibar\n * palette's RESULT count (it fetches 9 rows = 8 results + its see-all row;\n * this overlay's see-all is a footer button, not a row).\n */\n @Input() MaxResults = 8;\n\n /** Whether the overlay is currently visible */\n private _isOpen = false;\n\n @Input()\n set IsOpen(value: boolean) {\n const prev = this._isOpen;\n this._isOpen = value;\n if (value && !prev) {\n this.onOverlayOpened();\n }\n if (!value && prev) {\n this.onOverlayClosed();\n }\n }\n get IsOpen(): boolean {\n return this._isOpen;\n }\n\n /** Debounce time in ms before search fires */\n @Input() DebounceMs = 400;\n\n /** Which search sources to include */\n @Input() IncludeSources: ('vector' | 'fulltext' | 'entity')[] = ['vector', 'fulltext', 'entity'];\n\n /** Whether to show filter facets */\n @Input() ShowFilters = true;\n\n /** Text for the agent CTA button */\n @Input() AgentCtaText = 'Ask Knowledge Agent';\n\n /** Whether to show the agent CTA */\n @Input() ShowAgentCta = true;\n\n /**\n * When true, the overlay subscribes to `SearchService.StreamSearch` instead of awaiting\n * `ExecuteSearch`. Results render progressively as each provider reports back. The\n * per-provider status chip strip becomes visible while the stream is in flight.\n * Defaults to false to preserve the request-response UX that shipped in Phase 1.\n */\n @Input() EnableStreaming = false;\n\n /**\n * When false, the overlay does NOT claim the global Ctrl/Cmd+K chord. For hosts\n * (e.g. the Explorer shell) that own that shortcut themselves and open the\n * overlay programmatically — two listeners on the same chord would double-toggle.\n * Escape/arrow handling while open is unaffected.\n */\n @Input() EnableGlobalShortcut = true;\n\n /**\n * Optional promo strip pinned to the overlay's bottom edge — a host-supplied\n * nudge (e.g. Explorer advertising its command palette). The component is\n * deliberately ignorant of WHAT is being promoted; the host provides the\n * copy and handles both outcomes.\n */\n @Input() ShowPromo = false;\n\n /** Promo copy (one sentence). Required when ShowPromo is true. */\n @Input() PromoText = '';\n\n /** Label for the promo's accept action. */\n @Input() PromoActionLabel = 'Turn on';\n\n // --- Outputs ---\n\n @Output() IsOpenChange = new EventEmitter<boolean>();\n @Output() ResultSelected = new EventEmitter<SearchResultSelectedEvent>();\n @Output() FilterChanged = new EventEmitter<SearchFilterChangeEvent>();\n @Output() SearchExecuted = new EventEmitter<SearchExecutedEvent>();\n @Output() AgentCtaClicked = new EventEmitter<string>();\n /**\n * Emitted when the user clicks \"See all results\" — carries the current query.\n * Hosts (e.g. the Explorer shell) open the full Search Results workspace,\n * which has scopes, relevance controls, and richer result actions than this\n * capped quick-jump overlay. The overlay closes itself after emitting.\n */\n @Output() SeeAllRequested = new EventEmitter<string>();\n /** Promo accept — carries the current query so the host can hand it off. */\n @Output() PromoAccepted = new EventEmitter<string>();\n /** Promo dismissed — the host should persist this and stop showing it. */\n @Output() PromoDismissed = new EventEmitter<void>();\n\n // --- Component State ---\n\n public Query = '';\n public IsSearching = false;\n public ResultGroups: SearchResultGroup[] = [];\n public AllResults: SearchResultItem[] = [];\n public Filters: SearchFilter[] = [];\n public ActiveFilters: Record<string, string[]> = {};\n public TotalCount = 0;\n public ElapsedMs = 0;\n public HighlightedIndex = -1;\n public HasSearched = false;\n private searchVersion = 0;\n\n /**\n * Per-provider status entries shown above the results list while a streaming search\n * is in flight. One entry per provider that has reported back. Empty when the user\n * is not running a streaming search (or when `EnableStreaming` is false).\n */\n public StreamingProviders: StreamingProviderStatus[] = [];\n\n /** Active stream subscription so we can cancel on a new search or destroy. */\n private currentStream: Subscription | null = null;\n\n /** Element focused before the overlay opened — restored on close (a11y). */\n private previousFocus: HTMLElement | null = null;\n\n /** All results flattened for keyboard navigation */\n public get FlatResults(): SearchResultItem[] {\n return this.AllResults;\n }\n\n /** id of the highlighted option, announced via aria-activedescendant. */\n public get ActiveDescendantId(): string | null {\n return this.HighlightedIndex >= 0 && this.HighlightedIndex < this.FlatResults.length\n ? `so-opt-${this.HighlightedIndex}`\n : null;\n }\n\n ngOnInit(): void {\n this.setupSearchDebounce();\n this.subscribeToSearchState();\n }\n\n ngOnDestroy(): void {\n this.currentStream?.unsubscribe();\n this.currentStream = null;\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // --- Keyboard shortcuts ---\n\n @HostListener('document:keydown', ['$event'])\n HandleGlobalKeydown(event: KeyboardEvent): void {\n if (this.EnableGlobalShortcut && this.isToggleShortcut(event)) {\n event.preventDefault();\n this.ToggleOverlay();\n return;\n }\n if (this._isOpen) {\n this.handleOverlayKeydown(event);\n }\n }\n\n /** Toggle the overlay open/closed */\n public ToggleOverlay(): void {\n this.IsOpen = !this._isOpen;\n this.IsOpenChange.emit(this._isOpen);\n }\n\n /** Open the overlay */\n public Open(): void {\n if (!this._isOpen) {\n this.IsOpen = true;\n this.IsOpenChange.emit(true);\n }\n }\n\n /** Close the overlay */\n public Close(): void {\n if (this._isOpen) {\n this.IsOpen = false;\n this.IsOpenChange.emit(false);\n }\n }\n\n /** Handle query input changes */\n public OnQueryInput(value: string): void {\n this.Query = value;\n this.searchInput$.next(value);\n }\n\n /** Handle clicking a result */\n public OnResultClick(result: SearchResultItem, event: MouseEvent): void {\n this.ResultSelected.emit({\n Result: result,\n OpenInNewTab: event.metaKey || event.ctrlKey\n });\n this.Close();\n }\n\n /** Handle selecting the highlighted result */\n public SelectHighlighted(): void {\n if (this.HighlightedIndex >= 0 && this.HighlightedIndex < this.FlatResults.length) {\n this.ResultSelected.emit({\n Result: this.FlatResults[this.HighlightedIndex],\n OpenInNewTab: false\n });\n this.Close();\n }\n }\n\n /** Handle filter option toggle */\n public OnFilterToggle(category: string, value: string): void {\n const current = this.ActiveFilters[category] ?? [];\n const index = current.indexOf(value);\n if (index >= 0) {\n current.splice(index, 1);\n } else {\n current.push(value);\n }\n this.ActiveFilters[category] = current;\n this.FilterChanged.emit({ Category: category, SelectedValues: current });\n this.executeSearch();\n }\n\n /** Clear all active filters */\n public ClearAllFilters(): void {\n this.ActiveFilters = {};\n this.executeSearch();\n }\n\n /** Handle clicking the agent CTA */\n public OnAgentCtaClick(): void {\n this.AgentCtaClicked.emit(this.Query);\n this.Close();\n }\n\n /** Promo accept: emit the current query and close — the host takes over. */\n public OnPromoAccept(): void {\n this.PromoAccepted.emit(this.Query.trim());\n this.Close();\n }\n\n /** Promo dismiss: the host persists the dismissal; hide it immediately. */\n public OnPromoDismiss(): void {\n this.ShowPromo = false;\n this.PromoDismissed.emit();\n }\n\n /** Handle clicking \"See all results\" — hand off to the full Search workspace */\n public OnSeeAllClick(): void {\n const query = this.Query.trim();\n if (query.length > 0) {\n this.SeeAllRequested.emit(query);\n }\n this.Close();\n }\n\n /** Handle clicking the backdrop to close */\n public OnBackdropClick(): void {\n this.Close();\n }\n\n /** Check if a filter option is active */\n public IsFilterActive(category: string, value: string): boolean {\n return (this.ActiveFilters[category] ?? []).includes(value);\n }\n\n /** Get a score display value (percentage) */\n public FormatScore(score: number): string {\n return `${Math.round(score * 100)}%`;\n }\n\n /** Format elapsed time display */\n public FormatElapsedTime(ms: number): string {\n if (ms < 1000) {\n return `${ms}ms`;\n }\n return `${(ms / 1000).toFixed(1)}s`;\n }\n\n // --- Private Methods ---\n\n private isToggleShortcut(event: KeyboardEvent): boolean {\n return (event.metaKey || event.ctrlKey) && event.key === 'k';\n }\n\n private handleOverlayKeydown(event: KeyboardEvent): void {\n switch (event.key) {\n case 'Escape':\n event.preventDefault();\n this.Close();\n break;\n case 'ArrowDown':\n event.preventDefault();\n this.moveHighlight(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n this.moveHighlight(-1);\n break;\n case 'Enter': {\n // Only claim Enter when it belongs to the combobox model (typing in\n // the input / a focused result row). A focused BUTTON (close,\n // see-all, filter chip, promo) must keep its native Enter\n // activation — preventDefault here at document level would\n // silently swallow it, or worse, open the highlighted result.\n const active = document.activeElement as HTMLElement | null;\n const inCombobox = active === this.SearchInputRef?.nativeElement\n || (active?.classList.contains('result-item') ?? false);\n if (!inCombobox) {\n return;\n }\n event.preventDefault();\n this.SelectHighlighted();\n break;\n }\n }\n }\n\n private moveHighlight(direction: number): void {\n const maxIndex = this.FlatResults.length - 1;\n if (maxIndex < 0) return;\n\n // If a result row currently holds DOM focus (roving tabindex), keep focus\n // travelling with the highlight; from the input, only the highlight moves.\n const rowHadFocus = document.activeElement instanceof HTMLElement\n && document.activeElement.classList.contains('result-item');\n\n this.HighlightedIndex += direction;\n if (this.HighlightedIndex < 0) {\n this.HighlightedIndex = maxIndex;\n } else if (this.HighlightedIndex > maxIndex) {\n this.HighlightedIndex = 0;\n }\n this.cdr.detectChanges();\n\n // Keyboard-driven moves keep the highlighted row visible. Mouse hover sets\n // HighlightedIndex directly in the template and deliberately does NOT\n // scroll — auto-scrolling under the pointer fights the user's hand.\n const row = document.getElementById(`so-opt-${this.HighlightedIndex}`);\n row?.scrollIntoView({ block: 'nearest' });\n if (rowHadFocus) {\n row?.focus();\n }\n }\n\n /**\n * Tab behavior inside the dialog:\n * - On a result row, Tab / Shift+Tab step through the RESULTS themselves\n * (mirrors ArrowDown/Up) until walking off either end of the list — then\n * focus continues to the footer actions / back to the earlier controls.\n * - Everywhere else, Tab wraps within the dialog (focus trap): input → close\n * → filter chips → results → footer actions → back to the input.\n * Escape is handled by the document-level keydown.\n */\n public OnSpotlightKeydown(event: KeyboardEvent): void {\n if (event.key !== 'Tab') {\n return;\n }\n const activeEl = document.activeElement as HTMLElement | null;\n if (activeEl?.classList.contains('result-item')) {\n const last = this.FlatResults.length - 1;\n if (!event.shiftKey && this.HighlightedIndex < last) {\n event.preventDefault();\n this.moveHighlight(1); // row has focus, so focus travels with it\n return;\n }\n if (event.shiftKey && this.HighlightedIndex > 0) {\n event.preventDefault();\n this.moveHighlight(-1);\n return;\n }\n // At either end: fall through so Tab leaves the list naturally.\n }\n const root = (event.currentTarget as HTMLElement) ?? null;\n if (!root) {\n return;\n }\n const focusables = Array.from(\n root.querySelectorAll<HTMLElement>('input, button, .result-item[tabindex=\"0\"], .search-recent-item[tabindex=\"0\"]')\n ).filter((el) => el.offsetParent !== null);\n if (focusables.length === 0) {\n return;\n }\n const active = document.activeElement as HTMLElement | null;\n if (!event.shiftKey && active === focusables[focusables.length - 1]) {\n event.preventDefault();\n focusables[0].focus();\n } else if (event.shiftKey && active === focusables[0]) {\n event.preventDefault();\n focusables[focusables.length - 1].focus();\n }\n }\n\n /**\n * Recent-search row activated (click or Enter/Space). Re-runs the search AND\n * refocuses the input — the activated row leaves the DOM when recents are\n * replaced by results, which would otherwise drop focus to <body>.\n */\n public OnRecentSelect(query: string): void {\n this.OnQueryInput(query);\n this.SearchInputRef?.nativeElement?.focus();\n }\n\n /** Recent-search rows are keyboard-activatable (Enter/Space = click). */\n public OnRecentKeydown(event: KeyboardEvent, query: string): void {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n this.OnRecentSelect(query);\n }\n }\n\n private setupSearchDebounce(): void {\n this.searchInput$\n .pipe(\n debounceTime(this.DebounceMs),\n distinctUntilChanged(),\n takeUntil(this.destroy$)\n )\n .subscribe(() => this.executeSearch());\n }\n\n private subscribeToSearchState(): void {\n this.searchService.IsSearching$\n .pipe(takeUntil(this.destroy$))\n .subscribe(val => {\n this.IsSearching = val;\n this.cdr.detectChanges();\n });\n }\n\n private async executeSearch(): Promise<void> {\n const query = this.Query.trim();\n if (!query) {\n this.clearResults();\n return;\n }\n\n const version = ++this.searchVersion;\n\n const request: SearchRequest = {\n Query: query,\n MaxResults: this.MaxResults,\n ActiveFilters: this.ActiveFilters,\n IncludeSources: this.IncludeSources,\n };\n\n if (this.EnableStreaming) {\n this.executeStreamingSearch(query, request, version);\n return;\n }\n\n const response = await this.searchService.ExecuteSearch(request);\n\n // Discard results if a newer search was triggered while this one was in-flight\n if (version !== this.searchVersion) {\n return;\n }\n\n this.AllResults = response.Results;\n this.ResultGroups = response.Groups;\n this.Filters = response.Filters;\n this.TotalCount = response.TotalCount;\n this.ElapsedMs = response.ElapsedMs;\n this.HasSearched = true;\n this.HighlightedIndex = response.Results.length > 0 ? 0 : -1;\n\n this.SearchExecuted.emit({\n Query: query,\n Filters: this.ActiveFilters,\n ResultCount: response.TotalCount,\n ElapsedMs: response.ElapsedMs,\n });\n\n this.cdr.detectChanges();\n }\n\n /**\n * Streaming variant of executeSearch — subscribes to `SearchService.StreamSearch` and\n * progressively updates the result list as each provider reports back. The 'final'\n * event carries the canonical fused/reranked list, which replaces the partials.\n *\n * Cancellation: a new search invocation tears down the in-flight stream via\n * `searchVersion` and `currentStream.unsubscribe()`.\n */\n private executeStreamingSearch(query: string, request: SearchRequest, version: number): void {\n // Tear down any prior stream so we don't get cross-talk between consecutive queries.\n this.currentStream?.unsubscribe();\n this.currentStream = null;\n\n // Reset visible state for a fresh stream.\n this.StreamingProviders = [];\n this.AllResults = [];\n this.ResultGroups = [];\n this.TotalCount = 0;\n this.ElapsedMs = 0;\n this.HasSearched = true;\n this.HighlightedIndex = -1;\n this.cdr.detectChanges();\n\n this.currentStream = this.searchService.StreamSearch(request).subscribe({\n next: (event) => {\n if (version !== this.searchVersion) return;\n\n if (event.Phase === 'provider' && event.ProviderName) {\n const count = event.Results?.length ?? 0;\n this.StreamingProviders = [\n ...this.StreamingProviders,\n {\n Name: event.ProviderName,\n Count: count,\n ElapsedMs: event.ElapsedMs ?? 0,\n State: 'Completed',\n },\n ];\n if (event.Results && event.Results.length > 0) {\n // Append partials so the user sees the list grow as providers return.\n this.AllResults = [...this.AllResults, ...event.Results];\n this.ResultGroups = this.searchService.GroupResults(this.AllResults);\n this.TotalCount = this.AllResults.length;\n if (this.HighlightedIndex < 0) {\n this.HighlightedIndex = 0;\n }\n }\n } else if (event.Phase === 'final' && event.Results) {\n // Replace the appended partials with the canonical fused/reranked list.\n this.AllResults = event.Results;\n this.ResultGroups = this.searchService.GroupResults(this.AllResults);\n this.Filters = this.searchService.BuildFilters(this.AllResults);\n this.TotalCount = event.Results.length;\n this.ElapsedMs = event.ElapsedMs ?? this.ElapsedMs;\n this.HighlightedIndex = event.Results.length > 0 ? 0 : -1;\n }\n\n this.cdr.detectChanges();\n },\n error: (err: Error) => {\n if (version !== this.searchVersion) return;\n this.StreamingProviders = [\n ...this.StreamingProviders,\n { Name: 'stream', Count: 0, ElapsedMs: 0, State: 'Error', ErrorMessage: err.message },\n ];\n this.cdr.detectChanges();\n },\n complete: () => {\n if (version !== this.searchVersion) return;\n this.SearchExecuted.emit({\n Query: query,\n Filters: this.ActiveFilters,\n ResultCount: this.TotalCount,\n ElapsedMs: this.ElapsedMs,\n });\n this.cdr.detectChanges();\n },\n });\n }\n\n private clearResults(): void {\n this.AllResults = [];\n this.ResultGroups = [];\n this.Filters = [];\n this.TotalCount = 0;\n this.ElapsedMs = 0;\n this.HasSearched = false;\n this.HighlightedIndex = -1;\n this.cdr.detectChanges();\n }\n\n private onOverlayOpened(): void {\n // Remember what had focus so Close() can hand it back (a11y: the overlay\n // is a modal dialog — focus must return to the summoning control).\n this.previousFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null;\n // Focus input after view updates\n Promise.resolve().then(() => {\n this.SearchInputRef?.nativeElement?.focus();\n this.cdr.detectChanges();\n });\n }\n\n private onOverlayClosed(): void {\n this.HighlightedIndex = -1;\n if (this.previousFocus?.isConnected) {\n this.previousFocus.focus();\n }\n this.previousFocus = null;\n }\n\n /** Check if any filters are active (used by template) */\n public HasActiveFilters(): boolean {\n return Object.values(this.ActiveFilters).some(v => v.length > 0);\n }\n\n /** @deprecated Use {@link HasActiveFilters}. */\n public hasActiveFilters(): boolean {\n return this.HasActiveFilters();\n }\n\n /** Check if a result is currently keyboard-highlighted */\n public IsResultHighlighted(result: SearchResultItem): boolean {\n const flatIndex = this.GetFlatIndex(result);\n return flatIndex === this.HighlightedIndex;\n }\n\n /** @deprecated Use {@link IsResultHighlighted}. */\n public isResultHighlighted(result: SearchResultItem): boolean {\n return this.IsResultHighlighted(result);\n }\n\n /** Get the flat index of a result for keyboard navigation */\n public GetFlatIndex(result: SearchResultItem): number {\n return this.FlatResults.indexOf(result);\n }\n\n /** @deprecated Use {@link GetFlatIndex}. */\n public getFlatIndex(result: SearchResultItem): number {\n return this.GetFlatIndex(result);\n }\n}\n","@if (IsOpen) {\n <!-- Backdrop -->\n <div class=\"search-backdrop\" (click)=\"OnBackdropClick()\"></div>\n\n <!-- Spotlight container -->\n <div class=\"search-spotlight\" role=\"dialog\" aria-modal=\"true\" aria-label=\"Search\"\n (click)=\"$event.stopPropagation()\" (keydown)=\"OnSpotlightKeydown($event)\">\n <!-- Search input area -->\n <div class=\"search-input-wrap\">\n <i class=\"fa-solid fa-magnifying-glass search-icon\"></i>\n <input\n #searchInput\n type=\"text\"\n class=\"search-input\"\n role=\"combobox\"\n aria-controls=\"search-overlay-listbox\"\n aria-autocomplete=\"list\"\n [attr.aria-expanded]=\"AllResults.length > 0\"\n [attr.aria-activedescendant]=\"ActiveDescendantId\"\n [placeholder]=\"Placeholder\"\n [value]=\"Query\"\n (input)=\"OnQueryInput($any($event.target).value)\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n @if (IsSearching) {\n <div class=\"search-spinner\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n </div>\n }\n <div class=\"search-shortcut-hint\">\n <kbd>ESC</kbd>\n </div>\n <button type=\"button\" class=\"search-close-btn\" aria-label=\"Close\" title=\"Close\" (click)=\"Close()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n\n <!-- Results area -->\n <div class=\"search-results-area\">\n @if (EnableStreaming && (IsSearching || StreamingProviders.length > 0)) {\n <!-- Streaming status strip — one chip per provider that has reported -->\n <div class=\"streaming-status-strip\" aria-live=\"polite\">\n @if (StreamingProviders.length === 0 && IsSearching) {\n <span class=\"streaming-chip streaming-chip-pending\">\n <i class=\"fa-solid fa-circle-notch fa-spin\"></i>\n <span>Searching…</span>\n </span>\n }\n @for (p of StreamingProviders; track p.Name) {\n <span class=\"streaming-chip\"\n [class.streaming-chip-error]=\"p.State === 'Error'\"\n [class.streaming-chip-completed]=\"p.State === 'Completed'\">\n @if (p.State === 'Completed') {\n <i class=\"fa-solid fa-check\"></i>\n } @else {\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n }\n <span class=\"streaming-chip-name\">{{ p.Name }}</span>\n @if (p.State === 'Completed') {\n <span class=\"streaming-chip-count\">{{ p.Count }}</span>\n <span class=\"streaming-chip-time\">{{ FormatElapsedTime(p.ElapsedMs) }}</span>\n } @else if (p.ErrorMessage) {\n <span class=\"streaming-chip-time\">{{ p.ErrorMessage }}</span>\n }\n </span>\n }\n </div>\n }\n @if (ShowFilters && Filters.length > 0) {\n <!-- Filter chips -->\n <div class=\"search-filter-bar\">\n @for (filter of Filters; track filter.Category) {\n @for (option of filter.Options; track option.Value) {\n <button\n class=\"filter-chip\"\n [class.filter-chip-active]=\"IsFilterActive(filter.Category, option.Value)\"\n (click)=\"OnFilterToggle(filter.Category, option.Value)\"\n >\n @if (option.Icon) {\n <i [class]=\"option.Icon\"></i>\n }\n <span>{{ option.Label }}</span>\n <span class=\"filter-chip-count\">{{ option.Count }}</span>\n </button>\n }\n }\n @if (hasActiveFilters()) {\n <button class=\"filter-clear-btn\" (click)=\"ClearAllFilters()\">\n <i class=\"fa-solid fa-times\"></i> Clear\n </button>\n }\n </div>\n }\n\n @if (HasSearched && AllResults.length === 0 && !IsSearching) {\n <!-- No results -->\n <mj-empty-state\n Variant=\"no-results\"\n Title=\"No results found\"\n Message=\"Try different keywords or remove some filters\">\n @if (ShowAgentCta) {\n <button ngProjectAs=\"[actions]\" class=\"agent-cta-btn\" (click)=\"OnAgentCtaClick()\">\n <i class=\"fa-solid fa-robot\"></i>\n {{ AgentCtaText }}\n </button>\n }\n </mj-empty-state>\n }\n\n @if (!HasSearched && !IsSearching) {\n <!-- Recent searches -->\n <div class=\"search-recent\">\n @if (searchService.RecentSearches$.value.length > 0) {\n <div class=\"search-recent-header\">\n <span class=\"search-recent-title\">Recent Searches</span>\n </div>\n @for (recent of searchService.RecentSearches$.value; track recent.Query; let i = $index) {\n @if (i < 5) {\n <div class=\"search-recent-item\" role=\"button\" tabindex=\"0\"\n (click)=\"OnRecentSelect(recent.Query)\"\n (keydown)=\"OnRecentKeydown($event, recent.Query)\">\n <i class=\"fa-solid fa-clock search-recent-icon\"></i>\n <span>{{ recent.Query }}</span>\n <span class=\"search-recent-count\">{{ recent.ResultCount }} results</span>\n </div>\n }\n }\n } @else {\n <mj-empty-state\n Variant=\"no-results\"\n Title=\"Start typing to search across all your knowledge\"\n Size=\"compact\" />\n }\n </div>\n }\n\n @if (AllResults.length > 0) {\n <!-- Grouped results -->\n <div id=\"search-overlay-listbox\" role=\"listbox\" aria-label=\"Search results\">\n @for (group of ResultGroups; track group.SourceType) {\n <div class=\"result-group\" role=\"presentation\">\n <div class=\"result-group-header\" role=\"presentation\">\n <i [class]=\"group.Icon\"></i>\n <span class=\"result-group-label\">{{ group.Label }}</span>\n <span class=\"result-group-count\">{{ group.TotalCount }}</span>\n </div>\n @for (result of group.Results; track result.ID; let ri = $index) {\n <div\n class=\"result-item\"\n role=\"option\"\n [attr.id]=\"'so-opt-' + getFlatIndex(result)\"\n [attr.tabindex]=\"isResultHighlighted(result) ? 0 : -1\"\n [attr.aria-selected]=\"isResultHighlighted(result)\"\n [class.result-item-highlighted]=\"isResultHighlighted(result)\"\n (click)=\"OnResultClick(result, $event)\"\n (focus)=\"HighlightedIndex = getFlatIndex(result)\"\n (mouseenter)=\"HighlightedIndex = getFlatIndex(result)\"\n >\n <div class=\"result-item-icon\">\n <i [class]=\"result.SourceIcon\"></i>\n </div>\n <div class=\"result-item-content\">\n <div class=\"result-item-title\">{{ result.Title }}</div>\n <div class=\"result-item-snippet\">{{ result.Snippet }}</div>\n @if (result.Tags.length > 0) {\n <div class=\"result-item-tags\">\n @for (tag of result.Tags; track tag; let ti = $index) {\n @if (ti < 3) {\n <span class=\"result-tag\">{{ tag }}</span>\n }\n }\n </div>\n }\n </div>\n <div class=\"result-item-score\">\n <span class=\"score-badge\">{{ FormatScore(result.Score) }}</span>\n </div>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Footer -->\n <div class=\"search-footer\">\n <span class=\"search-footer-count\">\n {{ TotalCount }} results in {{ FormatElapsedTime(ElapsedMs) }}\n </span>\n <div class=\"search-footer-actions\">\n <button type=\"button\" class=\"see-all-btn\" (click)=\"OnSeeAllClick()\">\n See all results\n <i class=\"fa-solid fa-arrow-right\"></i>\n </button>\n @if (ShowAgentCta) {\n <button class=\"agent-cta-btn agent-cta-btn-small\" (click)=\"OnAgentCtaClick()\">\n <i class=\"fa-solid fa-robot\"></i>\n {{ AgentCtaText }}\n </button>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Host-supplied promo strip (e.g. command palette nudge) -->\n @if (ShowPromo && PromoText) {\n <div class=\"search-promo\">\n <i class=\"fa-solid fa-wand-magic-sparkles search-promo-icon\"></i>\n <span class=\"search-promo-text\">{{ PromoText }}</span>\n <button type=\"button\" class=\"search-promo-action\" (click)=\"OnPromoAccept()\">{{ PromoActionLabel }}</button>\n <button type=\"button\" class=\"search-promo-dismiss\" aria-label=\"Dismiss\" title=\"Dismiss\" (click)=\"OnPromoDismiss()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n }\n </div>\n}\n"]}
@@ -83,14 +83,22 @@ export declare class SearchSuggestComponent implements OnInit {
83
83
  handling knows when the highlight has walked off the end of the list. */
84
84
  get NavigableItemCount(): number;
85
85
  /** Whether to show recent searches section */
86
+ get ShowRecentSection(): boolean;
87
+ /** @deprecated Use {@link ShowRecentSection}. */
86
88
  get showRecentSection(): boolean;
87
89
  /** Whether to show preview results section */
90
+ get ShowPreviewSection(): boolean;
91
+ /** @deprecated Use {@link ShowPreviewSection}. */
88
92
  get showPreviewSection(): boolean;
89
93
  /** Whether to show the recently-opened-records section (idle state only) */
94
+ get ShowRecentRecordsSection(): boolean;
95
+ /** @deprecated Use {@link ShowRecentRecordsSection}. */
90
96
  get showRecentRecordsSection(): boolean;
91
97
  /** Visible recently opened records (capped at 3) */
92
98
  get VisibleRecentRecords(): RecentRecordItem[];
93
99
  /** Whether to show the "See all N results" footer */
100
+ get ShowSeeAllFooter(): boolean;
101
+ /** @deprecated Use {@link ShowSeeAllFooter}. */
94
102
  get showSeeAllFooter(): boolean;
95
103
  /** Visible recent searches (capped at 5) */
96
104
  get VisibleRecentSearches(): RecentSearch[];
@@ -1 +1 @@
1
- {"version":3,"file":"search-suggest.component.d.ts","sourceRoot":"","sources":["../../src/lib/search-suggest.component.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search-suggest.component.d.ts","sourceRoot":"","sources":["../../src/lib/search-suggest.component.ts"],"names":[],"mappings":"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"}