@memberjunction/ng-search 5.46.0 → 5.48.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.
@@ -9,7 +9,7 @@ import { EventEmitter, OnDestroy, OnInit } from '@angular/core';
9
9
  import { SearchService, RecentSearch } from './search.service';
10
10
  import { SearchInputComponent } from './search-input.component';
11
11
  import { SearchSuggestComponent } from './search-suggest.component';
12
- import { SearchResultItem, SearchScopeInfo } from './search-types';
12
+ import { SearchResultItem, SearchScopeInfo, RecentRecordItem } from './search-types';
13
13
  import * as i0 from "@angular/core";
14
14
  export declare class SearchCompositeComponent implements OnInit, OnDestroy {
15
15
  private cdr;
@@ -39,18 +39,31 @@ export declare class SearchCompositeComponent implements OnInit, OnDestroy {
39
39
  * stays hidden and the UX is identical to the pre-scope unscoped behavior.
40
40
  */
41
41
  EnableScopeSelector: boolean;
42
+ /** Promo row pass-throughs — see SearchSuggestComponent for semantics. */
43
+ ShowPromo: boolean;
44
+ PromoText: string;
45
+ PromoActionLabel: string;
42
46
  /** Emitted when a result is selected from the preview dropdown */
43
47
  ResultSelected: EventEmitter<SearchResultItem>;
44
48
  /** Emitted when the user presses Enter or selects a recent search (full search) */
45
49
  SearchSubmitted: EventEmitter<string>;
46
50
  /** Emitted when the user clicks "See all N results" */
47
51
  SeeAllRequested: EventEmitter<string>;
52
+ /** Promo pass-throughs (accept carries the current query). */
53
+ PromoAccepted: EventEmitter<string>;
54
+ PromoDismissed: EventEmitter<void>;
55
+ /** Emitted when the user selects a recently opened record from the dropdown */
56
+ RecentRecordSelected: EventEmitter<RecentRecordItem>;
48
57
  Query: string;
49
58
  IsSuggestOpen: boolean;
50
59
  /** The current min relevance percent from the suggest dropdown filter */
60
+ /** Programmatically focus the search input (e.g. a host-owned Ctrl/Cmd+K chord). */
61
+ Focus(): void;
51
62
  get MinRelevancePercent(): number;
52
63
  PreviewResults: SearchResultItem[];
53
64
  RecentSearches: RecentSearch[];
65
+ /** Recently opened records for the dropdown's idle state (max 3 shown). */
66
+ RecentRecords: RecentRecordItem[];
54
67
  PreviewTotalCount: number;
55
68
  IsPreviewLoading: boolean;
56
69
  private previewSearchVersion;
@@ -96,12 +109,16 @@ export declare class SearchCompositeComponent implements OnInit, OnDestroy {
96
109
  */
97
110
  OnScopeSelectionChange(scopeIDs: string[]): void;
98
111
  private openSuggest;
112
+ /** Load/refresh the recently-opened-records list (fail-soft, fire-and-forget). */
113
+ private refreshRecentRecords;
114
+ /** Recently-opened-record selection from the dropdown → bubble to the host. */
115
+ OnRecentRecordSelected(record: RecentRecordItem): void;
99
116
  private closeSuggest;
100
117
  private subscribeToRecentSearches;
101
118
  private subscribeToScopes;
102
119
  private executePreviewSearch;
103
120
  private clearPreviewResults;
104
121
  static ɵfac: i0.ɵɵFactoryDeclaration<SearchCompositeComponent, never>;
105
- static ɵcmp: i0.ɵɵComponentDeclaration<SearchCompositeComponent, "mj-search-composite", never, { "Placeholder": { "alias": "Placeholder"; "required": false; }; "ShowShortcutHint": { "alias": "ShowShortcutHint"; "required": false; }; "DebounceMs": { "alias": "DebounceMs"; "required": false; }; "MinQueryLength": { "alias": "MinQueryLength"; "required": false; }; "MaxPreviewResults": { "alias": "MaxPreviewResults"; "required": false; }; "EnablePreview": { "alias": "EnablePreview"; "required": false; }; "EnableRecent": { "alias": "EnableRecent"; "required": false; }; "EnableScopeSelector": { "alias": "EnableScopeSelector"; "required": false; }; }, { "ResultSelected": "ResultSelected"; "SearchSubmitted": "SearchSubmitted"; "SeeAllRequested": "SeeAllRequested"; }, never, never, false, never>;
122
+ static ɵcmp: i0.ɵɵComponentDeclaration<SearchCompositeComponent, "mj-search-composite", never, { "Placeholder": { "alias": "Placeholder"; "required": false; }; "ShowShortcutHint": { "alias": "ShowShortcutHint"; "required": false; }; "DebounceMs": { "alias": "DebounceMs"; "required": false; }; "MinQueryLength": { "alias": "MinQueryLength"; "required": false; }; "MaxPreviewResults": { "alias": "MaxPreviewResults"; "required": false; }; "EnablePreview": { "alias": "EnablePreview"; "required": false; }; "EnableRecent": { "alias": "EnableRecent"; "required": false; }; "EnableScopeSelector": { "alias": "EnableScopeSelector"; "required": false; }; "ShowPromo": { "alias": "ShowPromo"; "required": false; }; "PromoText": { "alias": "PromoText"; "required": false; }; "PromoActionLabel": { "alias": "PromoActionLabel"; "required": false; }; }, { "ResultSelected": "ResultSelected"; "SearchSubmitted": "SearchSubmitted"; "SeeAllRequested": "SeeAllRequested"; "PromoAccepted": "PromoAccepted"; "PromoDismissed": "PromoDismissed"; "RecentRecordSelected": "RecentRecordSelected"; }, never, never, false, never>;
106
123
  }
107
124
  //# sourceMappingURL=search-composite.component.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"search-composite.component.d.ts","sourceRoot":"","sources":["../../src/lib/search-composite.component.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAGH,YAAY,EAGZ,SAAS,EACT,MAAM,EAKT,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;;AAEnE,qBAMa,wBAAyB,YAAW,MAAM,EAAE,SAAS;IAC9D,OAAO,CAAC,GAAG,CAA6B;IACxC,OAAO,CAAC,UAAU,CAAsB;IACxC,SAAS,CAAC,aAAa,gBAAyB;IAChD,OAAO,CAAC,QAAQ,CAAuB;IAEb,cAAc,EAAG,oBAAoB,CAAC;IACpC,gBAAgB,EAAG,sBAAsB,CAAC;IAItE,4CAA4C;IACnC,WAAW,SAAe;IAEnC,0DAA0D;IACjD,gBAAgB,UAAQ;IAEjC,sDAAsD;IAC7C,UAAU,SAAO;IAE1B,8DAA8D;IACrD,cAAc,SAAK;IAE5B,gEAAgE;IACvD,iBAAiB,SAAK;IAE/B,sDAAsD;IAC7C,aAAa,UAAQ;IAE9B,gDAAgD;IACvC,YAAY,UAAQ;IAE7B;;;;;OAKG;IACM,mBAAmB,UAAQ;IAIpC,kEAAkE;IACxD,cAAc,iCAAwC;IAEhE,mFAAmF;IACzE,eAAe,uBAA8B;IAEvD,uDAAuD;IAC7C,eAAe,uBAA8B;IAIhD,KAAK,SAAM;IACX,aAAa,UAAS;IAE7B,yEAAyE;IACzE,IAAW,mBAAmB,IAAI,MAAM,CAEvC;IACM,cAAc,EAAE,gBAAgB,EAAE,CAAM;IACxC,cAAc,EAAE,YAAY,EAAE,CAAM;IACpC,iBAAiB,SAAK;IACtB,gBAAgB,UAAS;IAChC,OAAO,CAAC,oBAAoB,CAAK;IAEjC;;;OAGG;IACI,eAAe,EAAE,eAAe,EAAE,CAAM;IAE/C,qFAAqF;IAC9E,SAAS,EAAE,OAAO,CAAS;IAElC;;;;OAIG;IACI,gBAAgB,EAAE,MAAM,EAAE,CAAM;IAEvC,QAAQ,IAAI,IAAI;IAShB,WAAW,IAAI,IAAI;IAQnB,mBAAmB,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAU5C,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAuBzC,oDAAoD;IAC7C,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAYzC,sCAAsC;IAC/B,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAazC,yBAAyB;IAClB,cAAc,IAAI,IAAI;IAI7B,uCAAuC;IAChC,cAAc,IAAI,IAAI;IAM7B,2BAA2B;IACpB,cAAc,IAAI,IAAI;IAM7B,oDAAoD;IAC7C,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI;IAKvD,qCAAqC;IAC9B,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAM5C,6BAA6B;IACtB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK7C,qCAAqC;IAC9B,sBAAsB,IAAI,IAAI;IAIrC;;;;OAIG;IACI,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI;IAMvD,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,yBAAyB;IASjC,OAAO,CAAC,iBAAiB;YAkBX,oBAAoB;IAyBlC,OAAO,CAAC,mBAAmB;yCArRlB,wBAAwB;2CAAxB,wBAAwB;CA0RpC"}
1
+ {"version":3,"file":"search-composite.component.d.ts","sourceRoot":"","sources":["../../src/lib/search-composite.component.ts"],"names":[],"mappings":"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"}
@@ -53,6 +53,10 @@ export class SearchCompositeComponent {
53
53
  * stays hidden and the UX is identical to the pre-scope unscoped behavior.
54
54
  */
55
55
  EnableScopeSelector = true;
56
+ /** Promo row pass-throughs — see SearchSuggestComponent for semantics. */
57
+ ShowPromo = false;
58
+ PromoText = '';
59
+ PromoActionLabel = 'Turn on';
56
60
  // --- Outputs ---
57
61
  /** Emitted when a result is selected from the preview dropdown */
58
62
  ResultSelected = new EventEmitter();
@@ -60,15 +64,26 @@ export class SearchCompositeComponent {
60
64
  SearchSubmitted = new EventEmitter();
61
65
  /** Emitted when the user clicks "See all N results" */
62
66
  SeeAllRequested = new EventEmitter();
67
+ /** Promo pass-throughs (accept carries the current query). */
68
+ PromoAccepted = new EventEmitter();
69
+ PromoDismissed = new EventEmitter();
70
+ /** Emitted when the user selects a recently opened record from the dropdown */
71
+ RecentRecordSelected = new EventEmitter();
63
72
  // --- Internal state ---
64
73
  Query = '';
65
74
  IsSuggestOpen = false;
66
75
  /** The current min relevance percent from the suggest dropdown filter */
76
+ /** Programmatically focus the search input (e.g. a host-owned Ctrl/Cmd+K chord). */
77
+ Focus() {
78
+ this.searchInputRef?.Focus();
79
+ }
67
80
  get MinRelevancePercent() {
68
81
  return this.searchSuggestRef?.MinRelevancePercent ?? 0;
69
82
  }
70
83
  PreviewResults = [];
71
84
  RecentSearches = [];
85
+ /** Recently opened records for the dropdown's idle state (max 3 shown). */
86
+ RecentRecords = [];
72
87
  PreviewTotalCount = 0;
73
88
  IsPreviewLoading = false;
74
89
  previewSearchVersion = 0;
@@ -88,6 +103,7 @@ export class SearchCompositeComponent {
88
103
  ngOnInit() {
89
104
  this.subscribeToRecentSearches();
90
105
  this.searchService.LoadRecentSearches(); // fire-and-forget — loads from UserInfoEngine
106
+ this.refreshRecentRecords(); // fire-and-forget — recently opened records
91
107
  if (this.EnableScopeSelector) {
92
108
  this.subscribeToScopes();
93
109
  this.searchService.LoadScopes(); // fire-and-forget — populates Scopes$
@@ -123,6 +139,28 @@ export class SearchCompositeComponent {
123
139
  this.searchSuggestRef.SelectHighlighted();
124
140
  }
125
141
  break;
142
+ case 'Tab': {
143
+ // Tab walks the dropdown suggestions (mirrors ArrowDown/Up) before
144
+ // leaving the widget — same model as the palette and overlay. DOM
145
+ // focus stays in the input (combobox pattern); only the highlight
146
+ // moves. Once the highlight walks off either end, Tab proceeds
147
+ // naturally (forward → the promo row / next control; backward →
148
+ // out of the bar).
149
+ const suggest = this.searchSuggestRef;
150
+ const count = suggest?.NavigableItemCount ?? 0;
151
+ if (!suggest || count === 0) {
152
+ break;
153
+ }
154
+ if (!event.shiftKey && suggest.HighlightedIndex < count - 1) {
155
+ event.preventDefault();
156
+ suggest.NavigateDown();
157
+ }
158
+ else if (event.shiftKey && suggest.HighlightedIndex > 0) {
159
+ event.preventDefault();
160
+ suggest.NavigateUp();
161
+ }
162
+ break;
163
+ }
126
164
  }
127
165
  }
128
166
  // --- Event handlers from child components ---
@@ -167,6 +205,15 @@ export class SearchCompositeComponent {
167
205
  }
168
206
  /** Handle result selection from suggest dropdown */
169
207
  OnResultSelected(result) {
208
+ // Direct navigation bypasses ExecuteSearch (which is what normally records
209
+ // recents), so record the query here — the same compensation the omnibar
210
+ // palette applies in its Execute(). Enter/see-all paths don't need this:
211
+ // they land on the results page, whose full search records with the real
212
+ // count (addToRecentSearches dedups by query, so no double entries).
213
+ const typed = this.Query.trim();
214
+ if (typed.length > 0) {
215
+ this.searchService.RecordRecentSearch(typed, this.PreviewTotalCount);
216
+ }
170
217
  this.ResultSelected.emit(result);
171
218
  this.closeSuggest();
172
219
  }
@@ -197,8 +244,24 @@ export class SearchCompositeComponent {
197
244
  openSuggest() {
198
245
  this.IsSuggestOpen = true;
199
246
  this.searchSuggestRef?.ResetHighlight();
247
+ // Refresh in the background so a record opened since the last dropdown
248
+ // appears; name resolution is memoized in the service, so repeat opens
249
+ // are cheap.
250
+ this.refreshRecentRecords();
200
251
  this.cdr.detectChanges();
201
252
  }
253
+ /** Load/refresh the recently-opened-records list (fail-soft, fire-and-forget). */
254
+ refreshRecentRecords() {
255
+ void this.searchService.GetRecentlyOpenedRecords(3).then((records) => {
256
+ this.RecentRecords = records;
257
+ this.cdr.detectChanges();
258
+ });
259
+ }
260
+ /** Recently-opened-record selection from the dropdown → bubble to the host. */
261
+ OnRecentRecordSelected(record) {
262
+ this.RecentRecordSelected.emit(record);
263
+ this.closeSuggest();
264
+ }
202
265
  closeSuggest() {
203
266
  this.IsSuggestOpen = false;
204
267
  this.searchSuggestRef?.ResetHighlight();
@@ -268,7 +331,7 @@ export class SearchCompositeComponent {
268
331
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.searchSuggestRef = _t.first);
269
332
  } }, hostBindings: function SearchCompositeComponent_HostBindings(rf, ctx) { if (rf & 1) {
270
333
  i0.ɵɵlistener("mousedown", function SearchCompositeComponent_mousedown_HostBindingHandler($event) { return ctx.OnDocumentMousedown($event); }, i0.ɵɵresolveDocument)("keydown", function SearchCompositeComponent_keydown_HostBindingHandler($event) { return ctx.OnHostKeydown($event); });
271
- } }, inputs: { Placeholder: "Placeholder", ShowShortcutHint: "ShowShortcutHint", DebounceMs: "DebounceMs", MinQueryLength: "MinQueryLength", MaxPreviewResults: "MaxPreviewResults", EnablePreview: "EnablePreview", EnableRecent: "EnableRecent", EnableScopeSelector: "EnableScopeSelector" }, outputs: { ResultSelected: "ResultSelected", SearchSubmitted: "SearchSubmitted", SeeAllRequested: "SeeAllRequested" }, standalone: false, decls: 6, vars: 14, consts: [["searchInput", ""], ["searchSuggest", ""], [1, "search-composite-wrap"], [1, "search-composite-scope", 3, "SelectedScopeIDs"], [3, "QueryChange", "QuerySubmit", "InputFocused", "InputEscaped", "InputCleared", "Placeholder", "Query", "ShowShortcutHint", "DebounceMs"], [3, "ResultSelected", "RecentSelected", "SeeAllRequested", "ClearRecentRequested", "IsOpen", "PreviewResults", "RecentSearches", "TotalCount", "IsLoading", "Query", "MinQueryLength", "MaxPreviewResults", "ShowRecent"], [1, "search-composite-scope", 3, "SelectionChange", "SelectedScopeIDs"]], template: function SearchCompositeComponent_Template(rf, ctx) { if (rf & 1) {
334
+ } }, inputs: { Placeholder: "Placeholder", ShowShortcutHint: "ShowShortcutHint", DebounceMs: "DebounceMs", MinQueryLength: "MinQueryLength", MaxPreviewResults: "MaxPreviewResults", EnablePreview: "EnablePreview", EnableRecent: "EnableRecent", EnableScopeSelector: "EnableScopeSelector", ShowPromo: "ShowPromo", PromoText: "PromoText", PromoActionLabel: "PromoActionLabel" }, outputs: { ResultSelected: "ResultSelected", SearchSubmitted: "SearchSubmitted", SeeAllRequested: "SeeAllRequested", PromoAccepted: "PromoAccepted", PromoDismissed: "PromoDismissed", RecentRecordSelected: "RecentRecordSelected" }, standalone: false, decls: 6, vars: 18, consts: [["searchInput", ""], ["searchSuggest", ""], [1, "search-composite-wrap"], [1, "search-composite-scope", 3, "SelectedScopeIDs"], [3, "QueryChange", "QuerySubmit", "InputFocused", "InputEscaped", "InputCleared", "Placeholder", "Query", "ShowShortcutHint", "DebounceMs"], [3, "ResultSelected", "RecentSelected", "SeeAllRequested", "ClearRecentRequested", "RecentRecordSelected", "PromoAccepted", "PromoDismissed", "IsOpen", "PreviewResults", "RecentSearches", "TotalCount", "IsLoading", "Query", "MinQueryLength", "MaxPreviewResults", "ShowRecent", "RecentRecords", "ShowPromo", "PromoText", "PromoActionLabel"], [1, "search-composite-scope", 3, "SelectionChange", "SelectedScopeIDs"]], template: function SearchCompositeComponent_Template(rf, ctx) { if (rf & 1) {
272
335
  const _r1 = i0.ɵɵgetCurrentView();
273
336
  i0.ɵɵelementStart(0, "div", 2);
274
337
  i0.ɵɵconditionalCreate(1, SearchCompositeComponent_Conditional_1_Template, 1, 1, "mj-search-scope-selector", 3);
@@ -276,7 +339,7 @@ export class SearchCompositeComponent {
276
339
  i0.ɵɵlistener("QueryChange", function SearchCompositeComponent_Template_mj_search_input_QueryChange_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnQueryChange($event)); })("QuerySubmit", function SearchCompositeComponent_Template_mj_search_input_QuerySubmit_2_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnQuerySubmit($event)); })("InputFocused", function SearchCompositeComponent_Template_mj_search_input_InputFocused_2_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnInputFocused()); })("InputEscaped", function SearchCompositeComponent_Template_mj_search_input_InputEscaped_2_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnInputEscaped()); })("InputCleared", function SearchCompositeComponent_Template_mj_search_input_InputCleared_2_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnInputCleared()); });
277
340
  i0.ɵɵelementEnd();
278
341
  i0.ɵɵelementStart(4, "mj-search-suggest", 5, 1);
279
- i0.ɵɵlistener("ResultSelected", function SearchCompositeComponent_Template_mj_search_suggest_ResultSelected_4_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnResultSelected($event)); })("RecentSelected", function SearchCompositeComponent_Template_mj_search_suggest_RecentSelected_4_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnRecentSelected($event)); })("SeeAllRequested", function SearchCompositeComponent_Template_mj_search_suggest_SeeAllRequested_4_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnSeeAllRequested($event)); })("ClearRecentRequested", function SearchCompositeComponent_Template_mj_search_suggest_ClearRecentRequested_4_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnClearRecentRequested()); });
342
+ i0.ɵɵlistener("ResultSelected", function SearchCompositeComponent_Template_mj_search_suggest_ResultSelected_4_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnResultSelected($event)); })("RecentSelected", function SearchCompositeComponent_Template_mj_search_suggest_RecentSelected_4_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnRecentSelected($event)); })("SeeAllRequested", function SearchCompositeComponent_Template_mj_search_suggest_SeeAllRequested_4_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnSeeAllRequested($event)); })("ClearRecentRequested", function SearchCompositeComponent_Template_mj_search_suggest_ClearRecentRequested_4_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnClearRecentRequested()); })("RecentRecordSelected", function SearchCompositeComponent_Template_mj_search_suggest_RecentRecordSelected_4_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.OnRecentRecordSelected($event)); })("PromoAccepted", function SearchCompositeComponent_Template_mj_search_suggest_PromoAccepted_4_listener($event) { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.PromoAccepted.emit($event)); })("PromoDismissed", function SearchCompositeComponent_Template_mj_search_suggest_PromoDismissed_4_listener() { i0.ɵɵrestoreView(_r1); return i0.ɵɵresetView(ctx.PromoDismissed.emit()); });
280
343
  i0.ɵɵelementEnd()();
281
344
  } if (rf & 2) {
282
345
  i0.ɵɵadvance();
@@ -284,12 +347,12 @@ export class SearchCompositeComponent {
284
347
  i0.ɵɵadvance();
285
348
  i0.ɵɵproperty("Placeholder", ctx.Placeholder)("Query", ctx.Query)("ShowShortcutHint", ctx.ShowShortcutHint)("DebounceMs", ctx.DebounceMs);
286
349
  i0.ɵɵadvance(2);
287
- i0.ɵɵproperty("IsOpen", ctx.IsSuggestOpen)("PreviewResults", ctx.PreviewResults)("RecentSearches", ctx.RecentSearches)("TotalCount", ctx.PreviewTotalCount)("IsLoading", ctx.IsPreviewLoading)("Query", ctx.Query)("MinQueryLength", ctx.MinQueryLength)("MaxPreviewResults", ctx.MaxPreviewResults)("ShowRecent", ctx.EnableRecent);
350
+ i0.ɵɵproperty("IsOpen", ctx.IsSuggestOpen)("PreviewResults", ctx.PreviewResults)("RecentSearches", ctx.RecentSearches)("TotalCount", ctx.PreviewTotalCount)("IsLoading", ctx.IsPreviewLoading)("Query", ctx.Query)("MinQueryLength", ctx.MinQueryLength)("MaxPreviewResults", ctx.MaxPreviewResults)("ShowRecent", ctx.EnableRecent)("RecentRecords", ctx.RecentRecords)("ShowPromo", ctx.ShowPromo)("PromoText", ctx.PromoText)("PromoActionLabel", ctx.PromoActionLabel);
288
351
  } }, dependencies: [i1.SearchInputComponent, i2.SearchSuggestComponent, i3.SearchScopeSelectorComponent], styles: ["\n\n\n.search-composite-wrap[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n align-items: stretch;\n gap: 8px;\n width: 100%;\n}\n\n.search-composite-scope[_ngcontent-%COMP%] {\n flex-shrink: 0;\n display: inline-flex;\n align-items: stretch;\n}\n\n.search-composite-wrap[_ngcontent-%COMP%] > mj-search-input[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.search-composite-wrap[_ngcontent-%COMP%] > mj-search-suggest[_ngcontent-%COMP%] {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n}"] });
289
352
  }
290
353
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SearchCompositeComponent, [{
291
354
  type: Component,
292
- args: [{ standalone: false, selector: 'mj-search-composite', template: "<div class=\"search-composite-wrap\">\n @if (EnableScopeSelector && HasScopes) {\n <mj-search-scope-selector\n class=\"search-composite-scope\"\n [SelectedScopeIDs]=\"SelectedScopeIDs\"\n (SelectionChange)=\"OnScopeSelectionChange($any($event))\">\n </mj-search-scope-selector>\n }\n\n <mj-search-input\n #searchInput\n [Placeholder]=\"Placeholder\"\n [Query]=\"Query\"\n [ShowShortcutHint]=\"ShowShortcutHint\"\n [DebounceMs]=\"DebounceMs\"\n (QueryChange)=\"OnQueryChange($any($event))\"\n (QuerySubmit)=\"OnQuerySubmit($any($event))\"\n (InputFocused)=\"OnInputFocused()\"\n (InputEscaped)=\"OnInputEscaped()\"\n (InputCleared)=\"OnInputCleared()\"\n ></mj-search-input>\n\n <mj-search-suggest\n #searchSuggest\n [IsOpen]=\"IsSuggestOpen\"\n [PreviewResults]=\"PreviewResults\"\n [RecentSearches]=\"RecentSearches\"\n [TotalCount]=\"PreviewTotalCount\"\n [IsLoading]=\"IsPreviewLoading\"\n [Query]=\"Query\"\n [MinQueryLength]=\"MinQueryLength\"\n [MaxPreviewResults]=\"MaxPreviewResults\"\n [ShowRecent]=\"EnableRecent\"\n (ResultSelected)=\"OnResultSelected($any($event))\"\n (RecentSelected)=\"OnRecentSelected($any($event))\"\n (SeeAllRequested)=\"OnSeeAllRequested($any($event))\"\n (ClearRecentRequested)=\"OnClearRecentRequested()\"\n ></mj-search-suggest>\n</div>\n", styles: ["/* Search Composite Component */\n\n.search-composite-wrap {\n position: relative;\n display: flex;\n align-items: stretch;\n gap: 8px;\n width: 100%;\n}\n\n.search-composite-scope {\n flex-shrink: 0;\n display: inline-flex;\n align-items: stretch;\n}\n\n.search-composite-wrap > mj-search-input {\n flex: 1;\n min-width: 0;\n}\n\n.search-composite-wrap > mj-search-suggest {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n}\n"] }]
355
+ args: [{ standalone: false, selector: 'mj-search-composite', template: "<div class=\"search-composite-wrap\">\n @if (EnableScopeSelector && HasScopes) {\n <mj-search-scope-selector\n class=\"search-composite-scope\"\n [SelectedScopeIDs]=\"SelectedScopeIDs\"\n (SelectionChange)=\"OnScopeSelectionChange($any($event))\">\n </mj-search-scope-selector>\n }\n\n <mj-search-input\n #searchInput\n [Placeholder]=\"Placeholder\"\n [Query]=\"Query\"\n [ShowShortcutHint]=\"ShowShortcutHint\"\n [DebounceMs]=\"DebounceMs\"\n (QueryChange)=\"OnQueryChange($any($event))\"\n (QuerySubmit)=\"OnQuerySubmit($any($event))\"\n (InputFocused)=\"OnInputFocused()\"\n (InputEscaped)=\"OnInputEscaped()\"\n (InputCleared)=\"OnInputCleared()\"\n ></mj-search-input>\n\n <mj-search-suggest\n #searchSuggest\n [IsOpen]=\"IsSuggestOpen\"\n [PreviewResults]=\"PreviewResults\"\n [RecentSearches]=\"RecentSearches\"\n [TotalCount]=\"PreviewTotalCount\"\n [IsLoading]=\"IsPreviewLoading\"\n [Query]=\"Query\"\n [MinQueryLength]=\"MinQueryLength\"\n [MaxPreviewResults]=\"MaxPreviewResults\"\n [ShowRecent]=\"EnableRecent\"\n [RecentRecords]=\"RecentRecords\"\n [ShowPromo]=\"ShowPromo\"\n [PromoText]=\"PromoText\"\n [PromoActionLabel]=\"PromoActionLabel\"\n (ResultSelected)=\"OnResultSelected($any($event))\"\n (RecentSelected)=\"OnRecentSelected($any($event))\"\n (SeeAllRequested)=\"OnSeeAllRequested($any($event))\"\n (ClearRecentRequested)=\"OnClearRecentRequested()\"\n (RecentRecordSelected)=\"OnRecentRecordSelected($event)\"\n (PromoAccepted)=\"PromoAccepted.emit($event)\"\n (PromoDismissed)=\"PromoDismissed.emit()\"\n ></mj-search-suggest>\n</div>\n", styles: ["/* Search Composite Component */\n\n.search-composite-wrap {\n position: relative;\n display: flex;\n align-items: stretch;\n gap: 8px;\n width: 100%;\n}\n\n.search-composite-scope {\n flex-shrink: 0;\n display: inline-flex;\n align-items: stretch;\n}\n\n.search-composite-wrap > mj-search-input {\n flex: 1;\n min-width: 0;\n}\n\n.search-composite-wrap > mj-search-suggest {\n position: absolute;\n top: 100%;\n left: 0;\n right: 0;\n}\n"] }]
293
356
  }], null, { searchInputRef: [{
294
357
  type: ViewChild,
295
358
  args: ['searchInput']
@@ -312,12 +375,24 @@ export class SearchCompositeComponent {
312
375
  type: Input
313
376
  }], EnableScopeSelector: [{
314
377
  type: Input
378
+ }], ShowPromo: [{
379
+ type: Input
380
+ }], PromoText: [{
381
+ type: Input
382
+ }], PromoActionLabel: [{
383
+ type: Input
315
384
  }], ResultSelected: [{
316
385
  type: Output
317
386
  }], SearchSubmitted: [{
318
387
  type: Output
319
388
  }], SeeAllRequested: [{
320
389
  type: Output
390
+ }], PromoAccepted: [{
391
+ type: Output
392
+ }], PromoDismissed: [{
393
+ type: Output
394
+ }], RecentRecordSelected: [{
395
+ type: Output
321
396
  }], OnDocumentMousedown: [{
322
397
  type: HostListener,
323
398
  args: ['document:mousedown', ['$event']]
@@ -1 +1 @@
1
- {"version":3,"file":"search-composite.component.js","sourceRoot":"","sources":["../../src/lib/search-composite.component.ts","../../src/lib/search-composite.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Search Composite Component\n *\n * Drop-in widget combining SearchInputComponent + SearchSuggestComponent.\n * Handles query debouncing, preview search calls, recent searches,\n * keyboard navigation delegation, and click-outside-to-close.\n */\n\nimport {\n Component,\n ElementRef,\n EventEmitter,\n HostListener,\n Input,\n OnDestroy,\n OnInit,\n Output,\n ViewChild,\n ChangeDetectorRef,\n inject\n} from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { SearchService, RecentSearch } from './search.service';\nimport { SearchInputComponent } from './search-input.component';\nimport { SearchSuggestComponent } from './search-suggest.component';\nimport { SearchResultItem, SearchScopeInfo } from './search-types';\n\n@Component({\n standalone: false,\n selector: 'mj-search-composite',\n templateUrl: './search-composite.component.html',\n styleUrls: ['./search-composite.component.css']\n})\nexport class SearchCompositeComponent implements OnInit, OnDestroy {\n private cdr = inject(ChangeDetectorRef);\n private elementRef = inject(ElementRef);\n protected searchService = inject(SearchService);\n private destroy$ = new Subject<void>();\n\n @ViewChild('searchInput') searchInputRef!: SearchInputComponent;\n @ViewChild('searchSuggest') searchSuggestRef!: SearchSuggestComponent;\n\n // --- Configuration Inputs ---\n\n /** Placeholder text for the search input */\n @Input() Placeholder = 'Search...';\n\n /** Whether to show keyboard shortcut hint on the input */\n @Input() ShowShortcutHint = true;\n\n /** Debounce time in milliseconds for query changes */\n @Input() DebounceMs = 400;\n\n /** Minimum query length before preview results are fetched */\n @Input() MinQueryLength = 2;\n\n /** Maximum number of preview results to show in the dropdown */\n @Input() MaxPreviewResults = 8;\n\n /** Whether to enable live preview search on typing */\n @Input() EnablePreview = true;\n\n /** Whether to enable recent searches display */\n @Input() EnableRecent = true;\n\n /**\n * Whether to show the scope selector inline with the search input. When true (default),\n * the composite lazy-loads the list of scopes the current user can see and renders the\n * selector only if at least one scope exists. When zero scopes are visible the selector\n * stays hidden and the UX is identical to the pre-scope unscoped behavior.\n */\n @Input() EnableScopeSelector = true;\n\n // --- Outputs ---\n\n /** Emitted when a result is selected from the preview dropdown */\n @Output() ResultSelected = new EventEmitter<SearchResultItem>();\n\n /** Emitted when the user presses Enter or selects a recent search (full search) */\n @Output() SearchSubmitted = new EventEmitter<string>();\n\n /** Emitted when the user clicks \"See all N results\" */\n @Output() SeeAllRequested = new EventEmitter<string>();\n\n // --- Internal state ---\n\n public Query = '';\n public IsSuggestOpen = false;\n\n /** The current min relevance percent from the suggest dropdown filter */\n public get MinRelevancePercent(): number {\n return this.searchSuggestRef?.MinRelevancePercent ?? 0;\n }\n public PreviewResults: SearchResultItem[] = [];\n public RecentSearches: RecentSearch[] = [];\n public PreviewTotalCount = 0;\n public IsPreviewLoading = false;\n private previewSearchVersion = 0;\n\n /**\n * Scopes the current user can see. Populated by `SearchService.LoadScopes()` on init.\n * When empty, the scope selector is not rendered (unscoped-as-before UX).\n */\n public AvailableScopes: SearchScopeInfo[] = [];\n\n /** Whether any scope is visible to the current user — drives selector visibility. */\n public HasScopes: boolean = false;\n\n /**\n * Currently selected scope IDs. Empty array means \"Global\" / unscoped. Read by the\n * shell (or any parent) on submit via the exposed getter, and mirrored to the server\n * through `SearchRequest.ScopeIDs` on the full submitted search.\n */\n public SelectedScopeIDs: string[] = [];\n\n ngOnInit(): void {\n this.subscribeToRecentSearches();\n this.searchService.LoadRecentSearches(); // fire-and-forget — loads from UserInfoEngine\n if (this.EnableScopeSelector) {\n this.subscribeToScopes();\n this.searchService.LoadScopes(); // fire-and-forget — populates Scopes$\n }\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // --- Click outside to close ---\n\n @HostListener('document:mousedown', ['$event'])\n OnDocumentMousedown(event: MouseEvent): void {\n const target = event.target as Node | null;\n if (target && !this.elementRef.nativeElement.contains(target)) {\n this.closeSuggest();\n }\n }\n\n // --- Keyboard navigation delegation ---\n\n @HostListener('keydown', ['$event'])\n OnHostKeydown(event: KeyboardEvent): void {\n if (!this.IsSuggestOpen) return;\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n this.searchSuggestRef?.NavigateDown();\n break;\n case 'ArrowUp':\n event.preventDefault();\n this.searchSuggestRef?.NavigateUp();\n break;\n case 'Enter':\n if (this.searchSuggestRef?.HighlightedIndex >= 0) {\n event.preventDefault();\n this.searchSuggestRef.SelectHighlighted();\n }\n break;\n }\n }\n\n // --- Event handlers from child components ---\n\n /** Handle debounced query changes from the input */\n public OnQueryChange(query: string): void {\n this.Query = query;\n\n if (query.length >= this.MinQueryLength && this.EnablePreview) {\n this.executePreviewSearch(query);\n } else {\n this.clearPreviewResults();\n }\n\n this.openSuggest();\n }\n\n /** Handle Enter press in the input */\n public OnQuerySubmit(query: string): void {\n // If a suggestion is highlighted, select it instead of searching\n if (this.IsSuggestOpen && this.searchSuggestRef && this.searchSuggestRef.HighlightedIndex >= 0) {\n this.searchSuggestRef.SelectHighlighted();\n return;\n }\n\n if (query.trim().length > 0) {\n this.SearchSubmitted.emit(query.trim());\n this.closeSuggest();\n }\n }\n\n /** Handle input focus */\n public OnInputFocused(): void {\n this.openSuggest();\n }\n\n /** Handle Escape press in the input */\n public OnInputEscaped(): void {\n if (this.IsSuggestOpen) {\n this.closeSuggest();\n }\n }\n\n /** Handle input cleared */\n public OnInputCleared(): void {\n this.Query = '';\n this.clearPreviewResults();\n this.openSuggest();\n }\n\n /** Handle result selection from suggest dropdown */\n public OnResultSelected(result: SearchResultItem): void {\n this.ResultSelected.emit(result);\n this.closeSuggest();\n }\n\n /** Handle recent search selection */\n public OnRecentSelected(query: string): void {\n this.Query = query;\n this.SearchSubmitted.emit(query);\n this.closeSuggest();\n }\n\n /** Handle \"See all\" click */\n public OnSeeAllRequested(query: string): void {\n this.SeeAllRequested.emit(query);\n this.closeSuggest();\n }\n\n /** Handle \"Clear\" recent searches */\n public OnClearRecentRequested(): void {\n this.searchService.ClearRecentSearches();\n }\n\n /**\n * Relay a selection change from the embedded scope selector to local state. Parents\n * read `SelectedScopeIDs` directly on submit; no output event is needed because\n * scope selection doesn't alter the inline preview (preview stays global for speed).\n */\n public OnScopeSelectionChange(scopeIDs: string[]): void {\n this.SelectedScopeIDs = scopeIDs;\n }\n\n // --- Private ---\n\n private openSuggest(): void {\n this.IsSuggestOpen = true;\n this.searchSuggestRef?.ResetHighlight();\n this.cdr.detectChanges();\n }\n\n private closeSuggest(): void {\n this.IsSuggestOpen = false;\n this.searchSuggestRef?.ResetHighlight();\n this.cdr.detectChanges();\n }\n\n private subscribeToRecentSearches(): void {\n this.searchService.RecentSearches$\n .pipe(takeUntil(this.destroy$))\n .subscribe(recents => {\n this.RecentSearches = recents;\n this.cdr.detectChanges();\n });\n }\n\n private subscribeToScopes(): void {\n this.searchService.Scopes$\n .pipe(takeUntil(this.destroy$))\n .subscribe(scopes => {\n this.AvailableScopes = scopes;\n this.HasScopes = scopes.length > 0;\n // Drop any previously-selected scope IDs the user can no longer see.\n if (this.SelectedScopeIDs.length > 0) {\n const visible = new Set(scopes.map(s => s.ID));\n const next = this.SelectedScopeIDs.filter(id => visible.has(id));\n if (next.length !== this.SelectedScopeIDs.length) {\n this.SelectedScopeIDs = next;\n }\n }\n this.cdr.detectChanges();\n });\n }\n\n private async executePreviewSearch(query: string): Promise<void> {\n const version = ++this.previewSearchVersion;\n this.IsPreviewLoading = true;\n this.cdr.detectChanges();\n\n try {\n const response = await this.searchService.PreviewSearch(query, this.MaxPreviewResults);\n // Only apply if this is still the latest request and query hasn't changed\n if (version === this.previewSearchVersion && this.Query === query) {\n this.PreviewResults = response.Results;\n this.PreviewTotalCount = response.TotalCount;\n }\n } catch {\n if (version === this.previewSearchVersion) {\n this.PreviewResults = [];\n this.PreviewTotalCount = 0;\n }\n } finally {\n if (version === this.previewSearchVersion) {\n this.IsPreviewLoading = false;\n this.cdr.detectChanges();\n }\n }\n }\n\n private clearPreviewResults(): void {\n this.PreviewResults = [];\n this.PreviewTotalCount = 0;\n this.cdr.detectChanges();\n }\n}\n","<div class=\"search-composite-wrap\">\n @if (EnableScopeSelector && HasScopes) {\n <mj-search-scope-selector\n class=\"search-composite-scope\"\n [SelectedScopeIDs]=\"SelectedScopeIDs\"\n (SelectionChange)=\"OnScopeSelectionChange($any($event))\">\n </mj-search-scope-selector>\n }\n\n <mj-search-input\n #searchInput\n [Placeholder]=\"Placeholder\"\n [Query]=\"Query\"\n [ShowShortcutHint]=\"ShowShortcutHint\"\n [DebounceMs]=\"DebounceMs\"\n (QueryChange)=\"OnQueryChange($any($event))\"\n (QuerySubmit)=\"OnQuerySubmit($any($event))\"\n (InputFocused)=\"OnInputFocused()\"\n (InputEscaped)=\"OnInputEscaped()\"\n (InputCleared)=\"OnInputCleared()\"\n ></mj-search-input>\n\n <mj-search-suggest\n #searchSuggest\n [IsOpen]=\"IsSuggestOpen\"\n [PreviewResults]=\"PreviewResults\"\n [RecentSearches]=\"RecentSearches\"\n [TotalCount]=\"PreviewTotalCount\"\n [IsLoading]=\"IsPreviewLoading\"\n [Query]=\"Query\"\n [MinQueryLength]=\"MinQueryLength\"\n [MaxPreviewResults]=\"MaxPreviewResults\"\n [ShowRecent]=\"EnableRecent\"\n (ResultSelected)=\"OnResultSelected($any($event))\"\n (RecentSelected)=\"OnRecentSelected($any($event))\"\n (SeeAllRequested)=\"OnSeeAllRequested($any($event))\"\n (ClearRecentRequested)=\"OnClearRecentRequested()\"\n ></mj-search-suggest>\n</div>\n"]}
1
+ {"version":3,"file":"search-composite.component.js","sourceRoot":"","sources":["../../src/lib/search-composite.component.ts","../../src/lib/search-composite.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Search Composite Component\n *\n * Drop-in widget combining SearchInputComponent + SearchSuggestComponent.\n * Handles query debouncing, preview search calls, recent searches,\n * keyboard navigation delegation, and click-outside-to-close.\n */\n\nimport {\n Component,\n ElementRef,\n EventEmitter,\n HostListener,\n Input,\n OnDestroy,\n OnInit,\n Output,\n ViewChild,\n ChangeDetectorRef,\n inject\n} from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\nimport { SearchService, RecentSearch } from './search.service';\nimport { SearchInputComponent } from './search-input.component';\nimport { SearchSuggestComponent } from './search-suggest.component';\nimport { SearchResultItem, SearchScopeInfo, RecentRecordItem } from './search-types';\n\n@Component({\n standalone: false,\n selector: 'mj-search-composite',\n templateUrl: './search-composite.component.html',\n styleUrls: ['./search-composite.component.css']\n})\nexport class SearchCompositeComponent implements OnInit, OnDestroy {\n private cdr = inject(ChangeDetectorRef);\n private elementRef = inject(ElementRef);\n protected searchService = inject(SearchService);\n private destroy$ = new Subject<void>();\n\n @ViewChild('searchInput') searchInputRef!: SearchInputComponent;\n @ViewChild('searchSuggest') searchSuggestRef!: SearchSuggestComponent;\n\n // --- Configuration Inputs ---\n\n /** Placeholder text for the search input */\n @Input() Placeholder = 'Search...';\n\n /** Whether to show keyboard shortcut hint on the input */\n @Input() ShowShortcutHint = true;\n\n /** Debounce time in milliseconds for query changes */\n @Input() DebounceMs = 400;\n\n /** Minimum query length before preview results are fetched */\n @Input() MinQueryLength = 2;\n\n /** Maximum number of preview results to show in the dropdown */\n @Input() MaxPreviewResults = 8;\n\n /** Whether to enable live preview search on typing */\n @Input() EnablePreview = true;\n\n /** Whether to enable recent searches display */\n @Input() EnableRecent = true;\n\n /**\n * Whether to show the scope selector inline with the search input. When true (default),\n * the composite lazy-loads the list of scopes the current user can see and renders the\n * selector only if at least one scope exists. When zero scopes are visible the selector\n * stays hidden and the UX is identical to the pre-scope unscoped behavior.\n */\n @Input() EnableScopeSelector = true;\n\n /** Promo row pass-throughs — see SearchSuggestComponent for semantics. */\n @Input() ShowPromo = false;\n @Input() PromoText = '';\n @Input() PromoActionLabel = 'Turn on';\n\n // --- Outputs ---\n\n /** Emitted when a result is selected from the preview dropdown */\n @Output() ResultSelected = new EventEmitter<SearchResultItem>();\n\n /** Emitted when the user presses Enter or selects a recent search (full search) */\n @Output() SearchSubmitted = new EventEmitter<string>();\n\n /** Emitted when the user clicks \"See all N results\" */\n @Output() SeeAllRequested = new EventEmitter<string>();\n\n /** Promo pass-throughs (accept carries the current query). */\n @Output() PromoAccepted = new EventEmitter<string>();\n @Output() PromoDismissed = new EventEmitter<void>();\n\n /** Emitted when the user selects a recently opened record from the dropdown */\n @Output() RecentRecordSelected = new EventEmitter<RecentRecordItem>();\n\n // --- Internal state ---\n\n public Query = '';\n public IsSuggestOpen = false;\n\n /** The current min relevance percent from the suggest dropdown filter */\n /** Programmatically focus the search input (e.g. a host-owned Ctrl/Cmd+K chord). */\n public Focus(): void {\n this.searchInputRef?.Focus();\n }\n\n public get MinRelevancePercent(): number {\n return this.searchSuggestRef?.MinRelevancePercent ?? 0;\n }\n public PreviewResults: SearchResultItem[] = [];\n public RecentSearches: RecentSearch[] = [];\n /** Recently opened records for the dropdown's idle state (max 3 shown). */\n public RecentRecords: RecentRecordItem[] = [];\n public PreviewTotalCount = 0;\n public IsPreviewLoading = false;\n private previewSearchVersion = 0;\n\n /**\n * Scopes the current user can see. Populated by `SearchService.LoadScopes()` on init.\n * When empty, the scope selector is not rendered (unscoped-as-before UX).\n */\n public AvailableScopes: SearchScopeInfo[] = [];\n\n /** Whether any scope is visible to the current user — drives selector visibility. */\n public HasScopes: boolean = false;\n\n /**\n * Currently selected scope IDs. Empty array means \"Global\" / unscoped. Read by the\n * shell (or any parent) on submit via the exposed getter, and mirrored to the server\n * through `SearchRequest.ScopeIDs` on the full submitted search.\n */\n public SelectedScopeIDs: string[] = [];\n\n ngOnInit(): void {\n this.subscribeToRecentSearches();\n this.searchService.LoadRecentSearches(); // fire-and-forget — loads from UserInfoEngine\n this.refreshRecentRecords(); // fire-and-forget — recently opened records\n if (this.EnableScopeSelector) {\n this.subscribeToScopes();\n this.searchService.LoadScopes(); // fire-and-forget — populates Scopes$\n }\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // --- Click outside to close ---\n\n @HostListener('document:mousedown', ['$event'])\n OnDocumentMousedown(event: MouseEvent): void {\n const target = event.target as Node | null;\n if (target && !this.elementRef.nativeElement.contains(target)) {\n this.closeSuggest();\n }\n }\n\n // --- Keyboard navigation delegation ---\n\n @HostListener('keydown', ['$event'])\n OnHostKeydown(event: KeyboardEvent): void {\n if (!this.IsSuggestOpen) return;\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n this.searchSuggestRef?.NavigateDown();\n break;\n case 'ArrowUp':\n event.preventDefault();\n this.searchSuggestRef?.NavigateUp();\n break;\n case 'Enter':\n if (this.searchSuggestRef?.HighlightedIndex >= 0) {\n event.preventDefault();\n this.searchSuggestRef.SelectHighlighted();\n }\n break;\n case 'Tab': {\n // Tab walks the dropdown suggestions (mirrors ArrowDown/Up) before\n // leaving the widget — same model as the palette and overlay. DOM\n // focus stays in the input (combobox pattern); only the highlight\n // moves. Once the highlight walks off either end, Tab proceeds\n // naturally (forward → the promo row / next control; backward →\n // out of the bar).\n const suggest = this.searchSuggestRef;\n const count = suggest?.NavigableItemCount ?? 0;\n if (!suggest || count === 0) {\n break;\n }\n if (!event.shiftKey && suggest.HighlightedIndex < count - 1) {\n event.preventDefault();\n suggest.NavigateDown();\n } else if (event.shiftKey && suggest.HighlightedIndex > 0) {\n event.preventDefault();\n suggest.NavigateUp();\n }\n break;\n }\n }\n }\n\n // --- Event handlers from child components ---\n\n /** Handle debounced query changes from the input */\n public OnQueryChange(query: string): void {\n this.Query = query;\n\n if (query.length >= this.MinQueryLength && this.EnablePreview) {\n this.executePreviewSearch(query);\n } else {\n this.clearPreviewResults();\n }\n\n this.openSuggest();\n }\n\n /** Handle Enter press in the input */\n public OnQuerySubmit(query: string): void {\n // If a suggestion is highlighted, select it instead of searching\n if (this.IsSuggestOpen && this.searchSuggestRef && this.searchSuggestRef.HighlightedIndex >= 0) {\n this.searchSuggestRef.SelectHighlighted();\n return;\n }\n\n if (query.trim().length > 0) {\n this.SearchSubmitted.emit(query.trim());\n this.closeSuggest();\n }\n }\n\n /** Handle input focus */\n public OnInputFocused(): void {\n this.openSuggest();\n }\n\n /** Handle Escape press in the input */\n public OnInputEscaped(): void {\n if (this.IsSuggestOpen) {\n this.closeSuggest();\n }\n }\n\n /** Handle input cleared */\n public OnInputCleared(): void {\n this.Query = '';\n this.clearPreviewResults();\n this.openSuggest();\n }\n\n /** Handle result selection from suggest dropdown */\n public OnResultSelected(result: SearchResultItem): void {\n // Direct navigation bypasses ExecuteSearch (which is what normally records\n // recents), so record the query here — the same compensation the omnibar\n // palette applies in its Execute(). Enter/see-all paths don't need this:\n // they land on the results page, whose full search records with the real\n // count (addToRecentSearches dedups by query, so no double entries).\n const typed = this.Query.trim();\n if (typed.length > 0) {\n this.searchService.RecordRecentSearch(typed, this.PreviewTotalCount);\n }\n this.ResultSelected.emit(result);\n this.closeSuggest();\n }\n\n /** Handle recent search selection */\n public OnRecentSelected(query: string): void {\n this.Query = query;\n this.SearchSubmitted.emit(query);\n this.closeSuggest();\n }\n\n /** Handle \"See all\" click */\n public OnSeeAllRequested(query: string): void {\n this.SeeAllRequested.emit(query);\n this.closeSuggest();\n }\n\n /** Handle \"Clear\" recent searches */\n public OnClearRecentRequested(): void {\n this.searchService.ClearRecentSearches();\n }\n\n /**\n * Relay a selection change from the embedded scope selector to local state. Parents\n * read `SelectedScopeIDs` directly on submit; no output event is needed because\n * scope selection doesn't alter the inline preview (preview stays global for speed).\n */\n public OnScopeSelectionChange(scopeIDs: string[]): void {\n this.SelectedScopeIDs = scopeIDs;\n }\n\n // --- Private ---\n\n private openSuggest(): void {\n this.IsSuggestOpen = true;\n this.searchSuggestRef?.ResetHighlight();\n // Refresh in the background so a record opened since the last dropdown\n // appears; name resolution is memoized in the service, so repeat opens\n // are cheap.\n this.refreshRecentRecords();\n this.cdr.detectChanges();\n }\n\n /** Load/refresh the recently-opened-records list (fail-soft, fire-and-forget). */\n private refreshRecentRecords(): void {\n void this.searchService.GetRecentlyOpenedRecords(3).then((records) => {\n this.RecentRecords = records;\n this.cdr.detectChanges();\n });\n }\n\n /** Recently-opened-record selection from the dropdown → bubble to the host. */\n public OnRecentRecordSelected(record: RecentRecordItem): void {\n this.RecentRecordSelected.emit(record);\n this.closeSuggest();\n }\n\n private closeSuggest(): void {\n this.IsSuggestOpen = false;\n this.searchSuggestRef?.ResetHighlight();\n this.cdr.detectChanges();\n }\n\n private subscribeToRecentSearches(): void {\n this.searchService.RecentSearches$\n .pipe(takeUntil(this.destroy$))\n .subscribe(recents => {\n this.RecentSearches = recents;\n this.cdr.detectChanges();\n });\n }\n\n private subscribeToScopes(): void {\n this.searchService.Scopes$\n .pipe(takeUntil(this.destroy$))\n .subscribe(scopes => {\n this.AvailableScopes = scopes;\n this.HasScopes = scopes.length > 0;\n // Drop any previously-selected scope IDs the user can no longer see.\n if (this.SelectedScopeIDs.length > 0) {\n const visible = new Set(scopes.map(s => s.ID));\n const next = this.SelectedScopeIDs.filter(id => visible.has(id));\n if (next.length !== this.SelectedScopeIDs.length) {\n this.SelectedScopeIDs = next;\n }\n }\n this.cdr.detectChanges();\n });\n }\n\n private async executePreviewSearch(query: string): Promise<void> {\n const version = ++this.previewSearchVersion;\n this.IsPreviewLoading = true;\n this.cdr.detectChanges();\n\n try {\n const response = await this.searchService.PreviewSearch(query, this.MaxPreviewResults);\n // Only apply if this is still the latest request and query hasn't changed\n if (version === this.previewSearchVersion && this.Query === query) {\n this.PreviewResults = response.Results;\n this.PreviewTotalCount = response.TotalCount;\n }\n } catch {\n if (version === this.previewSearchVersion) {\n this.PreviewResults = [];\n this.PreviewTotalCount = 0;\n }\n } finally {\n if (version === this.previewSearchVersion) {\n this.IsPreviewLoading = false;\n this.cdr.detectChanges();\n }\n }\n }\n\n private clearPreviewResults(): void {\n this.PreviewResults = [];\n this.PreviewTotalCount = 0;\n this.cdr.detectChanges();\n }\n}\n","<div class=\"search-composite-wrap\">\n @if (EnableScopeSelector && HasScopes) {\n <mj-search-scope-selector\n class=\"search-composite-scope\"\n [SelectedScopeIDs]=\"SelectedScopeIDs\"\n (SelectionChange)=\"OnScopeSelectionChange($any($event))\">\n </mj-search-scope-selector>\n }\n\n <mj-search-input\n #searchInput\n [Placeholder]=\"Placeholder\"\n [Query]=\"Query\"\n [ShowShortcutHint]=\"ShowShortcutHint\"\n [DebounceMs]=\"DebounceMs\"\n (QueryChange)=\"OnQueryChange($any($event))\"\n (QuerySubmit)=\"OnQuerySubmit($any($event))\"\n (InputFocused)=\"OnInputFocused()\"\n (InputEscaped)=\"OnInputEscaped()\"\n (InputCleared)=\"OnInputCleared()\"\n ></mj-search-input>\n\n <mj-search-suggest\n #searchSuggest\n [IsOpen]=\"IsSuggestOpen\"\n [PreviewResults]=\"PreviewResults\"\n [RecentSearches]=\"RecentSearches\"\n [TotalCount]=\"PreviewTotalCount\"\n [IsLoading]=\"IsPreviewLoading\"\n [Query]=\"Query\"\n [MinQueryLength]=\"MinQueryLength\"\n [MaxPreviewResults]=\"MaxPreviewResults\"\n [ShowRecent]=\"EnableRecent\"\n [RecentRecords]=\"RecentRecords\"\n [ShowPromo]=\"ShowPromo\"\n [PromoText]=\"PromoText\"\n [PromoActionLabel]=\"PromoActionLabel\"\n (ResultSelected)=\"OnResultSelected($any($event))\"\n (RecentSelected)=\"OnRecentSelected($any($event))\"\n (SeeAllRequested)=\"OnSeeAllRequested($any($event))\"\n (ClearRecentRequested)=\"OnClearRecentRequested()\"\n (RecentRecordSelected)=\"OnRecentRecordSelected($event)\"\n (PromoAccepted)=\"PromoAccepted.emit($event)\"\n (PromoDismissed)=\"PromoDismissed.emit()\"\n ></mj-search-suggest>\n</div>\n"]}
@@ -20,7 +20,12 @@ export declare class SearchInputComponent implements OnInit, OnDestroy {
20
20
  get Query(): string;
21
21
  /** Whether to show the keyboard shortcut hint badge */
22
22
  ShowShortcutHint: boolean;
23
- /** Text to display in the shortcut hint badge */
23
+ /**
24
+ * Text to display in the shortcut hint badge. Defaults platform-aware:
25
+ * "⌘K" on macOS, "Ctrl+K" elsewhere (matching the actual chord, which hosts
26
+ * bind with metaKey on Mac). Set explicitly only to advertise a different
27
+ * chord.
28
+ */
24
29
  ShortcutHint: string;
25
30
  /** Debounce time in milliseconds before QueryChange emits */
26
31
  DebounceMs: number;
@@ -54,6 +59,9 @@ export declare class SearchInputComponent implements OnInit, OnDestroy {
54
59
  OnClick(): void;
55
60
  /** Handle blur event */
56
61
  OnBlur(): void;
62
+ /** Platform-correct default for the shortcut badge (same detection idiom as
63
+ the Ctrl/Cmd+K keydown handlers that actually bind the chord). */
64
+ private static defaultShortcutHint;
57
65
  private setupDebounce;
58
66
  static ɵfac: i0.ɵɵFactoryDeclaration<SearchInputComponent, never>;
59
67
  static ɵcmp: i0.ɵɵComponentDeclaration<SearchInputComponent, "mj-search-input", never, { "Placeholder": { "alias": "Placeholder"; "required": false; }; "Query": { "alias": "Query"; "required": false; }; "ShowShortcutHint": { "alias": "ShowShortcutHint"; "required": false; }; "ShortcutHint": { "alias": "ShortcutHint"; "required": false; }; "DebounceMs": { "alias": "DebounceMs"; "required": false; }; }, { "QueryChange": "QueryChange"; "QuerySubmit": "QuerySubmit"; "InputFocused": "InputFocused"; "InputBlurred": "InputBlurred"; "InputEscaped": "InputEscaped"; "InputCleared": "InputCleared"; }, never, never, false, never>;
@@ -1 +1 @@
1
- {"version":3,"file":"search-input.component.d.ts","sourceRoot":"","sources":["../../src/lib/search-input.component.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAEH,UAAU,EACV,YAAY,EAEZ,SAAS,EACT,MAAM,EAKT,MAAM,eAAe,CAAC;;AAIvB,qBAMa,oBAAqB,YAAW,MAAM,EAAE,SAAS;IAC1D,OAAO,CAAC,GAAG,CAA6B;IACxC,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,WAAW,CAAyB;IAEtB,QAAQ,EAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAI9D,0CAA0C;IACjC,WAAW,SAAe;IAEnC,6DAA6D;IAC7D,OAAO,CAAC,MAAM,CAAM;IAEpB,IACI,KAAK,CAAC,KAAK,EAAE,MAAM,EAKtB;IACD,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,uDAAuD;IAC9C,gBAAgB,UAAQ;IAEjC,iDAAiD;IACxC,YAAY,SAAY;IAEjC,6DAA6D;IACpD,UAAU,SAAO;IAI1B,qDAAqD;IAC3C,WAAW,uBAA8B;IAEnD,sDAAsD;IAC5C,WAAW,uBAA8B;IAEnD,4CAA4C;IAClC,YAAY,qBAA4B;IAElD,yCAAyC;IAC/B,YAAY,qBAA4B;IAElD,wDAAwD;IAC9C,YAAY,qBAA4B;IAElD,kEAAkE;IACxD,YAAY,qBAA4B;IAIlD,4CAA4C;IACrC,SAAS,UAAS;IAEzB,QAAQ,IAAI,IAAI;IAIhB,WAAW,IAAI,IAAI;IAOnB,+CAA+C;IACxC,KAAK,IAAI,IAAI;IAIpB,4CAA4C;IACrC,KAAK,IAAI,IAAI;IAWpB,gCAAgC;IACzB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKnC,yCAAyC;IAClC,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAa5C,yBAAyB;IAClB,OAAO,IAAI,IAAI;IAMtB,mEAAmE;IAC5D,OAAO,IAAI,IAAI;IAMtB,wBAAwB;IACjB,MAAM,IAAI,IAAI;IAQrB,OAAO,CAAC,aAAa;yCAnIZ,oBAAoB;2CAApB,oBAAoB;CA8IhC"}
1
+ {"version":3,"file":"search-input.component.d.ts","sourceRoot":"","sources":["../../src/lib/search-input.component.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAEH,UAAU,EACV,YAAY,EAEZ,SAAS,EACT,MAAM,EAKT,MAAM,eAAe,CAAC;;AAIvB,qBAMa,oBAAqB,YAAW,MAAM,EAAE,SAAS;IAC1D,OAAO,CAAC,GAAG,CAA6B;IACxC,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,WAAW,CAAyB;IAEtB,QAAQ,EAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAI9D,0CAA0C;IACjC,WAAW,SAAe;IAEnC,6DAA6D;IAC7D,OAAO,CAAC,MAAM,CAAM;IAEpB,IACI,KAAK,CAAC,KAAK,EAAE,MAAM,EAKtB;IACD,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,uDAAuD;IAC9C,gBAAgB,UAAQ;IAEjC;;;;;OAKG;IACM,YAAY,SAA8C;IAEnE,6DAA6D;IACpD,UAAU,SAAO;IAI1B,qDAAqD;IAC3C,WAAW,uBAA8B;IAEnD,sDAAsD;IAC5C,WAAW,uBAA8B;IAEnD,4CAA4C;IAClC,YAAY,qBAA4B;IAElD,yCAAyC;IAC/B,YAAY,qBAA4B;IAElD,wDAAwD;IAC9C,YAAY,qBAA4B;IAElD,kEAAkE;IACxD,YAAY,qBAA4B;IAIlD,4CAA4C;IACrC,SAAS,UAAS;IAEzB,QAAQ,IAAI,IAAI;IAIhB,WAAW,IAAI,IAAI;IAOnB,+CAA+C;IACxC,KAAK,IAAI,IAAI;IAIpB,4CAA4C;IACrC,KAAK,IAAI,IAAI;IAWpB,gCAAgC;IACzB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKnC,yCAAyC;IAClC,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAa5C,yBAAyB;IAClB,OAAO,IAAI,IAAI;IAMtB,mEAAmE;IAC5D,OAAO,IAAI,IAAI;IAMtB,wBAAwB;IACjB,MAAM,IAAI,IAAI;IAQrB;yEACqE;IACrE,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAKlC,OAAO,CAAC,aAAa;yCA/IZ,oBAAoB;2CAApB,oBAAoB;CA0JhC"}
@@ -47,8 +47,13 @@ export class SearchInputComponent {
47
47
  }
48
48
  /** Whether to show the keyboard shortcut hint badge */
49
49
  ShowShortcutHint = true;
50
- /** Text to display in the shortcut hint badge */
51
- ShortcutHint = 'Ctrl+K';
50
+ /**
51
+ * Text to display in the shortcut hint badge. Defaults platform-aware:
52
+ * "⌘K" on macOS, "Ctrl+K" elsewhere (matching the actual chord, which hosts
53
+ * bind with metaKey on Mac). Set explicitly only to advertise a different
54
+ * chord.
55
+ */
56
+ ShortcutHint = SearchInputComponent.defaultShortcutHint();
52
57
  /** Debounce time in milliseconds before QueryChange emits */
53
58
  DebounceMs = 400;
54
59
  // --- Outputs ---
@@ -126,6 +131,12 @@ export class SearchInputComponent {
126
131
  this.cdr.detectChanges();
127
132
  }
128
133
  // --- Private ---
134
+ /** Platform-correct default for the shortcut badge (same detection idiom as
135
+ the Ctrl/Cmd+K keydown handlers that actually bind the chord). */
136
+ static defaultShortcutHint() {
137
+ const isMac = typeof navigator !== 'undefined' && navigator.platform.toUpperCase().indexOf('MAC') >= 0;
138
+ return isMac ? '⌘K' : 'Ctrl+K';
139
+ }
129
140
  setupDebounce() {
130
141
  this.queryInput$
131
142
  .pipe(debounceTime(this.DebounceMs), distinctUntilChanged(), takeUntil(this.destroy$))
@@ -1 +1 @@
1
- {"version":3,"file":"search-input.component.js","sourceRoot":"","sources":["../../src/lib/search-input.component.ts","../../src/lib/search-input.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Search Input Component\n *\n * A reusable search text input for navbar/hero placement.\n * Features debounced query emission, keyboard shortcut hint,\n * clear button, and focus management.\n */\n\nimport {\n Component,\n ElementRef,\n EventEmitter,\n Input,\n OnDestroy,\n OnInit,\n Output,\n ViewChild,\n ChangeDetectorRef,\n inject\n} from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';\n\n@Component({\n standalone: false,\n selector: 'mj-search-input',\n templateUrl: './search-input.component.html',\n styleUrls: ['./search-input.component.css']\n})\nexport class SearchInputComponent implements OnInit, OnDestroy {\n private cdr = inject(ChangeDetectorRef);\n private destroy$ = new Subject<void>();\n private queryInput$ = new Subject<string>();\n\n @ViewChild('inputEl') inputRef!: ElementRef<HTMLInputElement>;\n\n // --- Configuration Inputs ---\n\n /** Placeholder text shown in the input */\n @Input() Placeholder = 'Search...';\n\n /** Current query value (two-way bindable via QueryChange) */\n private _Query = '';\n\n @Input()\n set Query(value: string) {\n if (value !== this._Query) {\n this._Query = value;\n this.cdr.detectChanges();\n }\n }\n get Query(): string {\n return this._Query;\n }\n\n /** Whether to show the keyboard shortcut hint badge */\n @Input() ShowShortcutHint = true;\n\n /** Text to display in the shortcut hint badge */\n @Input() ShortcutHint = 'Ctrl+K';\n\n /** Debounce time in milliseconds before QueryChange emits */\n @Input() DebounceMs = 400;\n\n // --- Outputs ---\n\n /** Emitted after debounce when query text changes */\n @Output() QueryChange = new EventEmitter<string>();\n\n /** Emitted immediately when the user presses Enter */\n @Output() QuerySubmit = new EventEmitter<string>();\n\n /** Emitted when the input receives focus */\n @Output() InputFocused = new EventEmitter<void>();\n\n /** Emitted when the input loses focus */\n @Output() InputBlurred = new EventEmitter<void>();\n\n /** Emitted when the user presses Escape in the input */\n @Output() InputEscaped = new EventEmitter<void>();\n\n /** Emitted when the user clears the input via the clear button */\n @Output() InputCleared = new EventEmitter<void>();\n\n // --- Internal state ---\n\n /** Whether the input currently has focus */\n public IsFocused = false;\n\n ngOnInit(): void {\n this.setupDebounce();\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // --- Public Methods ---\n\n /** Programmatically focus the input element */\n public Focus(): void {\n this.inputRef?.nativeElement?.focus();\n }\n\n /** Clear the query and emit InputCleared */\n public Clear(): void {\n this._Query = '';\n this.queryInput$.next('');\n this.QueryChange.emit('');\n this.InputCleared.emit();\n this.Focus();\n this.cdr.detectChanges();\n }\n\n // --- Template event handlers ---\n\n /** Handle native input event */\n public OnInput(value: string): void {\n this._Query = value;\n this.queryInput$.next(value);\n }\n\n /** Handle keydown events on the input */\n public OnKeydown(event: KeyboardEvent): void {\n switch (event.key) {\n case 'Enter':\n event.preventDefault();\n this.QuerySubmit.emit(this._Query);\n break;\n case 'Escape':\n event.preventDefault();\n this.InputEscaped.emit();\n break;\n }\n }\n\n /** Handle focus event */\n public OnFocus(): void {\n this.IsFocused = true;\n this.InputFocused.emit();\n this.cdr.detectChanges();\n }\n\n /** Handle click — re-opens suggest when input already has focus */\n public OnClick(): void {\n if (this.IsFocused) {\n this.InputFocused.emit();\n }\n }\n\n /** Handle blur event */\n public OnBlur(): void {\n this.IsFocused = false;\n this.InputBlurred.emit();\n this.cdr.detectChanges();\n }\n\n // --- Private ---\n\n private setupDebounce(): void {\n this.queryInput$\n .pipe(\n debounceTime(this.DebounceMs),\n distinctUntilChanged(),\n takeUntil(this.destroy$)\n )\n .subscribe(value => {\n this.QueryChange.emit(value);\n });\n }\n}\n","<div class=\"search-input-container\" [class.search-input-focused]=\"IsFocused\">\n <i class=\"fa-solid fa-magnifying-glass search-input-icon\"></i>\n <input\n #inputEl\n type=\"text\"\n class=\"mj-input search-input-field\"\n [placeholder]=\"Placeholder\"\n [value]=\"Query\"\n (input)=\"OnInput($any($event.target).value)\"\n (keydown)=\"OnKeydown($event)\"\n (focus)=\"OnFocus()\"\n (blur)=\"OnBlur()\"\n (click)=\"OnClick()\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n @if (Query.length > 0) {\n <button\n class=\"search-input-clear\"\n (click)=\"Clear()\"\n title=\"Clear search\"\n aria-label=\"Clear search\"\n type=\"button\"\n >\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n @if (ShowShortcutHint && !IsFocused && Query.length === 0) {\n <kbd class=\"search-input-shortcut\">{{ ShortcutHint }}</kbd>\n }\n</div>\n"]}
1
+ {"version":3,"file":"search-input.component.js","sourceRoot":"","sources":["../../src/lib/search-input.component.ts","../../src/lib/search-input.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview Search Input Component\n *\n * A reusable search text input for navbar/hero placement.\n * Features debounced query emission, keyboard shortcut hint,\n * clear button, and focus management.\n */\n\nimport {\n Component,\n ElementRef,\n EventEmitter,\n Input,\n OnDestroy,\n OnInit,\n Output,\n ViewChild,\n ChangeDetectorRef,\n inject\n} from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';\n\n@Component({\n standalone: false,\n selector: 'mj-search-input',\n templateUrl: './search-input.component.html',\n styleUrls: ['./search-input.component.css']\n})\nexport class SearchInputComponent implements OnInit, OnDestroy {\n private cdr = inject(ChangeDetectorRef);\n private destroy$ = new Subject<void>();\n private queryInput$ = new Subject<string>();\n\n @ViewChild('inputEl') inputRef!: ElementRef<HTMLInputElement>;\n\n // --- Configuration Inputs ---\n\n /** Placeholder text shown in the input */\n @Input() Placeholder = 'Search...';\n\n /** Current query value (two-way bindable via QueryChange) */\n private _Query = '';\n\n @Input()\n set Query(value: string) {\n if (value !== this._Query) {\n this._Query = value;\n this.cdr.detectChanges();\n }\n }\n get Query(): string {\n return this._Query;\n }\n\n /** Whether to show the keyboard shortcut hint badge */\n @Input() ShowShortcutHint = true;\n\n /**\n * Text to display in the shortcut hint badge. Defaults platform-aware:\n * \"⌘K\" on macOS, \"Ctrl+K\" elsewhere (matching the actual chord, which hosts\n * bind with metaKey on Mac). Set explicitly only to advertise a different\n * chord.\n */\n @Input() ShortcutHint = SearchInputComponent.defaultShortcutHint();\n\n /** Debounce time in milliseconds before QueryChange emits */\n @Input() DebounceMs = 400;\n\n // --- Outputs ---\n\n /** Emitted after debounce when query text changes */\n @Output() QueryChange = new EventEmitter<string>();\n\n /** Emitted immediately when the user presses Enter */\n @Output() QuerySubmit = new EventEmitter<string>();\n\n /** Emitted when the input receives focus */\n @Output() InputFocused = new EventEmitter<void>();\n\n /** Emitted when the input loses focus */\n @Output() InputBlurred = new EventEmitter<void>();\n\n /** Emitted when the user presses Escape in the input */\n @Output() InputEscaped = new EventEmitter<void>();\n\n /** Emitted when the user clears the input via the clear button */\n @Output() InputCleared = new EventEmitter<void>();\n\n // --- Internal state ---\n\n /** Whether the input currently has focus */\n public IsFocused = false;\n\n ngOnInit(): void {\n this.setupDebounce();\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // --- Public Methods ---\n\n /** Programmatically focus the input element */\n public Focus(): void {\n this.inputRef?.nativeElement?.focus();\n }\n\n /** Clear the query and emit InputCleared */\n public Clear(): void {\n this._Query = '';\n this.queryInput$.next('');\n this.QueryChange.emit('');\n this.InputCleared.emit();\n this.Focus();\n this.cdr.detectChanges();\n }\n\n // --- Template event handlers ---\n\n /** Handle native input event */\n public OnInput(value: string): void {\n this._Query = value;\n this.queryInput$.next(value);\n }\n\n /** Handle keydown events on the input */\n public OnKeydown(event: KeyboardEvent): void {\n switch (event.key) {\n case 'Enter':\n event.preventDefault();\n this.QuerySubmit.emit(this._Query);\n break;\n case 'Escape':\n event.preventDefault();\n this.InputEscaped.emit();\n break;\n }\n }\n\n /** Handle focus event */\n public OnFocus(): void {\n this.IsFocused = true;\n this.InputFocused.emit();\n this.cdr.detectChanges();\n }\n\n /** Handle click — re-opens suggest when input already has focus */\n public OnClick(): void {\n if (this.IsFocused) {\n this.InputFocused.emit();\n }\n }\n\n /** Handle blur event */\n public OnBlur(): void {\n this.IsFocused = false;\n this.InputBlurred.emit();\n this.cdr.detectChanges();\n }\n\n // --- Private ---\n\n /** Platform-correct default for the shortcut badge (same detection idiom as\n the Ctrl/Cmd+K keydown handlers that actually bind the chord). */\n private static defaultShortcutHint(): string {\n const isMac = typeof navigator !== 'undefined' && navigator.platform.toUpperCase().indexOf('MAC') >= 0;\n return isMac ? '⌘K' : 'Ctrl+K';\n }\n\n private setupDebounce(): void {\n this.queryInput$\n .pipe(\n debounceTime(this.DebounceMs),\n distinctUntilChanged(),\n takeUntil(this.destroy$)\n )\n .subscribe(value => {\n this.QueryChange.emit(value);\n });\n }\n}\n","<div class=\"search-input-container\" [class.search-input-focused]=\"IsFocused\">\n <i class=\"fa-solid fa-magnifying-glass search-input-icon\"></i>\n <input\n #inputEl\n type=\"text\"\n class=\"mj-input search-input-field\"\n [placeholder]=\"Placeholder\"\n [value]=\"Query\"\n (input)=\"OnInput($any($event.target).value)\"\n (keydown)=\"OnKeydown($event)\"\n (focus)=\"OnFocus()\"\n (blur)=\"OnBlur()\"\n (click)=\"OnClick()\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n @if (Query.length > 0) {\n <button\n class=\"search-input-clear\"\n (click)=\"Clear()\"\n title=\"Clear search\"\n aria-label=\"Clear search\"\n type=\"button\"\n >\n <i class=\"fa-solid fa-times\"></i>\n </button>\n }\n @if (ShowShortcutHint && !IsFocused && Query.length === 0) {\n <kbd class=\"search-input-shortcut\">{{ ShortcutHint }}</kbd>\n }\n</div>\n"]}
@@ -37,7 +37,13 @@ export declare class SearchOverlayComponent implements OnInit, OnDestroy {
37
37
  searchInputRef: ElementRef<HTMLInputElement>;
38
38
  /** Placeholder text for the search input */
39
39
  Placeholder: string;
40
- /** Maximum number of results to fetch */
40
+ /**
41
+ * Maximum number of results to fetch and display. Deliberately small — the
42
+ * overlay is a quick-jump surface; "See all results" hands off to the full
43
+ * Search Results workspace for anything deeper. 8 matches the omnibar
44
+ * palette's RESULT count (it fetches 9 rows = 8 results + its see-all row;
45
+ * this overlay's see-all is a footer button, not a row).
46
+ */
41
47
  MaxResults: number;
42
48
  /** Whether the overlay is currently visible */
43
49
  private _IsOpen;
@@ -60,11 +66,40 @@ export declare class SearchOverlayComponent implements OnInit, OnDestroy {
60
66
  * Defaults to false to preserve the request-response UX that shipped in Phase 1.
61
67
  */
62
68
  EnableStreaming: boolean;
69
+ /**
70
+ * When false, the overlay does NOT claim the global Ctrl/Cmd+K chord. For hosts
71
+ * (e.g. the Explorer shell) that own that shortcut themselves and open the
72
+ * overlay programmatically — two listeners on the same chord would double-toggle.
73
+ * Escape/arrow handling while open is unaffected.
74
+ */
75
+ EnableGlobalShortcut: boolean;
76
+ /**
77
+ * Optional promo strip pinned to the overlay's bottom edge — a host-supplied
78
+ * nudge (e.g. Explorer advertising its command palette). The component is
79
+ * deliberately ignorant of WHAT is being promoted; the host provides the
80
+ * copy and handles both outcomes.
81
+ */
82
+ ShowPromo: boolean;
83
+ /** Promo copy (one sentence). Required when ShowPromo is true. */
84
+ PromoText: string;
85
+ /** Label for the promo's accept action. */
86
+ PromoActionLabel: string;
63
87
  IsOpenChange: EventEmitter<boolean>;
64
88
  ResultSelected: EventEmitter<SearchResultSelectedEvent>;
65
89
  FilterChanged: EventEmitter<SearchFilterChangeEvent>;
66
90
  SearchExecuted: EventEmitter<SearchExecutedEvent>;
67
91
  AgentCtaClicked: EventEmitter<string>;
92
+ /**
93
+ * Emitted when the user clicks "See all results" — carries the current query.
94
+ * Hosts (e.g. the Explorer shell) open the full Search Results workspace,
95
+ * which has scopes, relevance controls, and richer result actions than this
96
+ * capped quick-jump overlay. The overlay closes itself after emitting.
97
+ */
98
+ SeeAllRequested: EventEmitter<string>;
99
+ /** Promo accept — carries the current query so the host can hand it off. */
100
+ PromoAccepted: EventEmitter<string>;
101
+ /** Promo dismissed — the host should persist this and stop showing it. */
102
+ PromoDismissed: EventEmitter<void>;
68
103
  Query: string;
69
104
  IsSearching: boolean;
70
105
  ResultGroups: SearchResultGroup[];
@@ -84,8 +119,12 @@ export declare class SearchOverlayComponent implements OnInit, OnDestroy {
84
119
  StreamingProviders: StreamingProviderStatus[];
85
120
  /** Active stream subscription so we can cancel on a new search or destroy. */
86
121
  private currentStream;
122
+ /** Element focused before the overlay opened — restored on close (a11y). */
123
+ private previousFocus;
87
124
  /** All results flattened for keyboard navigation */
88
125
  get FlatResults(): SearchResultItem[];
126
+ /** id of the highlighted option, announced via aria-activedescendant. */
127
+ get ActiveDescendantId(): string | null;
89
128
  ngOnInit(): void;
90
129
  ngOnDestroy(): void;
91
130
  HandleGlobalKeydown(event: KeyboardEvent): void;
@@ -107,6 +146,12 @@ export declare class SearchOverlayComponent implements OnInit, OnDestroy {
107
146
  ClearAllFilters(): void;
108
147
  /** Handle clicking the agent CTA */
109
148
  OnAgentCtaClick(): void;
149
+ /** Promo accept: emit the current query and close — the host takes over. */
150
+ OnPromoAccept(): void;
151
+ /** Promo dismiss: the host persists the dismissal; hide it immediately. */
152
+ OnPromoDismiss(): void;
153
+ /** Handle clicking "See all results" — hand off to the full Search workspace */
154
+ OnSeeAllClick(): void;
110
155
  /** Handle clicking the backdrop to close */
111
156
  OnBackdropClick(): void;
112
157
  /** Check if a filter option is active */
@@ -118,6 +163,24 @@ export declare class SearchOverlayComponent implements OnInit, OnDestroy {
118
163
  private isToggleShortcut;
119
164
  private handleOverlayKeydown;
120
165
  private moveHighlight;
166
+ /**
167
+ * Tab behavior inside the dialog:
168
+ * - On a result row, Tab / Shift+Tab step through the RESULTS themselves
169
+ * (mirrors ArrowDown/Up) until walking off either end of the list — then
170
+ * focus continues to the footer actions / back to the earlier controls.
171
+ * - Everywhere else, Tab wraps within the dialog (focus trap): input → close
172
+ * → filter chips → results → footer actions → back to the input.
173
+ * Escape is handled by the document-level keydown.
174
+ */
175
+ OnSpotlightKeydown(event: KeyboardEvent): void;
176
+ /**
177
+ * Recent-search row activated (click or Enter/Space). Re-runs the search AND
178
+ * refocuses the input — the activated row leaves the DOM when recents are
179
+ * replaced by results, which would otherwise drop focus to <body>.
180
+ */
181
+ OnRecentSelect(query: string): void;
182
+ /** Recent-search rows are keyboard-activatable (Enter/Space = click). */
183
+ OnRecentKeydown(event: KeyboardEvent, query: string): void;
121
184
  private setupSearchDebounce;
122
185
  private subscribeToSearchState;
123
186
  private executeSearch;
@@ -140,6 +203,6 @@ export declare class SearchOverlayComponent implements OnInit, OnDestroy {
140
203
  /** Get the flat index of a result for keyboard navigation */
141
204
  getFlatIndex(result: SearchResultItem): number;
142
205
  static ɵfac: i0.ɵɵFactoryDeclaration<SearchOverlayComponent, never>;
143
- static ɵcmp: i0.ɵɵComponentDeclaration<SearchOverlayComponent, "mj-search-overlay", never, { "Placeholder": { "alias": "Placeholder"; "required": false; }; "MaxResults": { "alias": "MaxResults"; "required": false; }; "IsOpen": { "alias": "IsOpen"; "required": false; }; "DebounceMs": { "alias": "DebounceMs"; "required": false; }; "IncludeSources": { "alias": "IncludeSources"; "required": false; }; "ShowFilters": { "alias": "ShowFilters"; "required": false; }; "AgentCtaText": { "alias": "AgentCtaText"; "required": false; }; "ShowAgentCta": { "alias": "ShowAgentCta"; "required": false; }; "EnableStreaming": { "alias": "EnableStreaming"; "required": false; }; }, { "IsOpenChange": "IsOpenChange"; "ResultSelected": "ResultSelected"; "FilterChanged": "FilterChanged"; "SearchExecuted": "SearchExecuted"; "AgentCtaClicked": "AgentCtaClicked"; }, never, never, false, never>;
206
+ static ɵcmp: i0.ɵɵComponentDeclaration<SearchOverlayComponent, "mj-search-overlay", never, { "Placeholder": { "alias": "Placeholder"; "required": false; }; "MaxResults": { "alias": "MaxResults"; "required": false; }; "IsOpen": { "alias": "IsOpen"; "required": false; }; "DebounceMs": { "alias": "DebounceMs"; "required": false; }; "IncludeSources": { "alias": "IncludeSources"; "required": false; }; "ShowFilters": { "alias": "ShowFilters"; "required": false; }; "AgentCtaText": { "alias": "AgentCtaText"; "required": false; }; "ShowAgentCta": { "alias": "ShowAgentCta"; "required": false; }; "EnableStreaming": { "alias": "EnableStreaming"; "required": false; }; "EnableGlobalShortcut": { "alias": "EnableGlobalShortcut"; "required": false; }; "ShowPromo": { "alias": "ShowPromo"; "required": false; }; "PromoText": { "alias": "PromoText"; "required": false; }; "PromoActionLabel": { "alias": "PromoActionLabel"; "required": false; }; }, { "IsOpenChange": "IsOpenChange"; "ResultSelected": "ResultSelected"; "FilterChanged": "FilterChanged"; "SearchExecuted": "SearchExecuted"; "AgentCtaClicked": "AgentCtaClicked"; "SeeAllRequested": "SeeAllRequested"; "PromoAccepted": "PromoAccepted"; "PromoDismissed": "PromoDismissed"; }, never, never, false, never>;
144
207
  }
145
208
  //# sourceMappingURL=search-overlay.component.d.ts.map