@searchstax-inc/searchstudio-ux-angular 0.0.2 → 1.0.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.
Files changed (22) hide show
  1. package/README.md +734 -13
  2. package/esm2020/lib/components/searchstax-search-external/searchstax-search-external.component.mjs +40 -0
  3. package/esm2020/lib/components/searchstax-search-facets/searchstax-search-facets.component.mjs +112 -0
  4. package/esm2020/lib/components/searchstax-search-overview/searchstax-search-overview.component.mjs +3 -3
  5. package/esm2020/lib/components/searchstax-search-pagination/searchstax-search-pagination.component.mjs +3 -3
  6. package/esm2020/lib/components/searchstax-search-related/searchstax-search-related.component.mjs +44 -0
  7. package/esm2020/lib/components/searchstax-search-sorting/searchstax-search-sorting.component.mjs +45 -0
  8. package/esm2020/lib/searchstudio-ux-angular.module.mjs +25 -5
  9. package/esm2020/public-api.mjs +5 -1
  10. package/fesm2015/searchstax-inc-searchstudio-ux-angular.mjs +264 -9
  11. package/fesm2015/searchstax-inc-searchstudio-ux-angular.mjs.map +1 -1
  12. package/fesm2020/searchstax-inc-searchstudio-ux-angular.mjs +250 -9
  13. package/fesm2020/searchstax-inc-searchstudio-ux-angular.mjs.map +1 -1
  14. package/lib/components/searchstax-search-external/searchstax-search-external.component.d.ts +17 -0
  15. package/lib/components/searchstax-search-facets/searchstax-search-facets.component.d.ts +37 -0
  16. package/lib/components/searchstax-search-overview/searchstax-search-overview.component.d.ts +1 -1
  17. package/lib/components/searchstax-search-pagination/searchstax-search-pagination.component.d.ts +1 -1
  18. package/lib/components/searchstax-search-related/searchstax-search-related.component.d.ts +19 -0
  19. package/lib/components/searchstax-search-sorting/searchstax-search-sorting.component.d.ts +18 -0
  20. package/lib/searchstudio-ux-angular.module.d.ts +6 -2
  21. package/package.json +1 -1
  22. package/public-api.d.ts +4 -0
package/README.md CHANGED
@@ -1,24 +1,745 @@
1
- # SearchstudioUxAngular
1
+ # searchstudio-ux-angular
2
2
 
3
- This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 13.0.0.
3
+ Library to build searchstudio search page
4
4
 
5
- ## Code scaffolding
5
+ ## Installation
6
+ npm install following package
7
+ `npm install --save @searchstax-inc/searchstudio-ux-angular`
6
8
 
7
- Run `ng generate component component-name --project searchstudio-ux-angular` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project searchstudio-ux-angular`.
8
- > Note: Don't forget to add `--project searchstudio-ux-angular` or else it will be added to the default project in your `angular.json` file.
9
+ Add following code to `<head>`
9
10
 
10
- ## Build
11
+ ```
12
+ <script type="text/javascript">
13
+ var _msq = _msq || []; //declare object
14
+ var analyticsBaseUrl = 'https://analytics-us-east.searchstax.co';
15
+ (function () {
16
+ var ms = document.createElement('script');
17
+ ms.type = 'text/javascript';
18
+ ms.src = 'https://static.searchstax.co/studio-js/v3/js/studio-analytics.js';
19
+ var s = document.getElementsByTagName('script')[0];
20
+ s.parentNode.insertBefore(ms, s);
21
+ })();
22
+ </script>
23
+ ```
24
+ ## Usage
11
25
 
12
- Run `ng build searchstudio-ux-angular` to build the project. The build artifacts will be stored in the `dist/` directory.
26
+ After importing SearchstaxWrapper component needs to wrap all other components.
13
27
 
14
- ## Publishing
28
+ Make sure your module imports SearchstudioUxAngularModule:
15
29
 
16
- After building your library with `ng build searchstudio-ux-angular`, go to the dist folder `cd dist/searchstudio-ux-angular` and run `npm publish`.
30
+ imports: [
31
+ SearchstudioUxAngularModule
32
+ ],
17
33
 
18
- ## Running unit tests
34
+ ```
19
35
 
20
- Run `ng test searchstudio-ux-angular` to execute the unit tests via [Karma](https://karma-runner.github.io).
36
+ ```
21
37
 
22
- ## Further help
38
+ ## Initialization
39
+ Initialization object needs to be of type: [ISearchstaxConfig](https://github.com/searchstax/searchstudio-ux-js/blob/main/src/interfaces/connector.interface.ts#L5)
23
40
 
24
- To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
41
+ Initialization example
42
+ ```
43
+ Add following code to your ts file and fill config
44
+
45
+ config = {
46
+ searchURL: '',
47
+ suggesterURL: '',
48
+ trackApiKey: '',
49
+ searchAuth: '',
50
+ authType: 'basic',
51
+ relatedSearchesAPIKey: '',
52
+ relatedSearchesURL: ''
53
+ }
54
+
55
+ beforeSearch(props: ISearchObject) {
56
+ // gets searchProps, if passed along further search will execute, if null then event gets canceled
57
+ // props can be modified and passed along
58
+ const propsCopy = { ...props }
59
+ // propsCopy.term = propsCopy.term;
60
+ return propsCopy
61
+ }
62
+ afterSearch(results: ISearchstaxParsedResult[]) {
63
+ const copy = [...results]
64
+ // copy.splice(0, 1);
65
+ console.log('copy', copy);
66
+ return copy
67
+ }
68
+
69
+ afterAutosuggest(result: ISearchstaxSuggestResponse) {
70
+ const copy = { ...result }
71
+ return copy
72
+ }
73
+
74
+ beforeAutosuggest(props: ISearchstaxSuggestProps) {
75
+ // gets suggestProps, if passed along further autosuggest will execute, if null then event gets canceled
76
+ // props can be modified and passed along
77
+ const propsCopy = { ...props }
78
+ // propsCopy.term = propsCopy.term + '222';
79
+ return propsCopy
80
+ }
81
+
82
+ afterLinkClick(results: ISearchstaxParsedResult): ISearchstaxParsedResult {
83
+ // gets result that was clicked, if passed along further functions will execute, if null then event gets canceled
84
+ const copy = { ...results }
85
+
86
+ return copy
87
+ }
88
+
89
+ initialized(searchstax: Searchstax) {
90
+ console.log('searchstax', searchstax);
91
+ }
92
+ ```
93
+
94
+ ## Initial layout
95
+ Our base theme is designed with this layout in mind but it is optional as all widgets have id parameters and can be attached to any element.
96
+ ```
97
+ <div>
98
+ <app-searchstax-wrapper
99
+ [searchURL]="config.searchURL"
100
+ [suggesterURL]="config.suggesterURL"
101
+ [trackApiKey]="config.trackApiKey"
102
+ [searchAuth]="config.searchAuth"
103
+ [beforeSearch]="beforeSearch"
104
+ [afterSearch]="afterSearch"
105
+ (initialized)="initialized($event)"
106
+ >
107
+ <div class="searchstax-page-layout-container">
108
+ <app-searchstax-input
109
+ [afterAutosuggest]="afterAutosuggest"
110
+ [beforeAutosuggest]="beforeAutosuggest"
111
+ [suggestAfterMinChars]="3"
112
+ ></app-searchstax-input>
113
+ <div class="search-details-container">
114
+ <app-searchstax-search-feedback></app-searchstax-search-feedback>
115
+ <app-searchstax-search-sorting></app-searchstax-search-sorting>
116
+ </div>
117
+ <div class="searchstax-page-layout-facet-result-container">
118
+ <div class="searchstax-page-layout-facet-container">
119
+ <app-searchstax-search-facets
120
+ [facetingType]="'showUnavailable'"
121
+ [itemsPerPageDesktop]="2"
122
+ [itemsPerPageMobile]="99"
123
+ ></app-searchstax-search-facets>
124
+ </div>
125
+ <div class="searchstax-page-layout-result-container">
126
+ <app-searchstax-external-promotions></app-searchstax-external-promotions>
127
+ <app-searchstax-results
128
+ [afterLinkClick]="afterLinkClick"
129
+ ></app-searchstax-results>
130
+ <app-searchstax-related-searches
131
+ [relatedSearchesURL]="config.relatedSearchesURL"
132
+ [relatedSearchesAPIKey]="config.relatedSearchesAPIKey"
133
+ ></app-searchstax-related-searches>
134
+
135
+ <app-searchstax-search-pagination></app-searchstax-search-pagination>
136
+ </div>
137
+ </div>
138
+ </div>
139
+ </app-searchstax-wrapper>
140
+ </div>
141
+
142
+ ```
143
+
144
+ ### widgets
145
+ Following widgets are available:
146
+
147
+ [Input Widget](#input-widget)
148
+
149
+ [Result Widget](#result-widget)
150
+
151
+ [Facets Widget](#facets-widget)
152
+
153
+ [Pagination Widget](#pagination-widget)
154
+
155
+ [SearchFeedback Widget](#searchfeedback-widget)
156
+
157
+ [RelatedSearches Widget](#relatedsearches-widget)
158
+
159
+ [ExternalPromotions Widget](#externalpromotions-widget)
160
+
161
+ [sorting Widget](#sorting-widget)
162
+
163
+ ### Input Widget ###
164
+
165
+ example of input widget initialization with minimum options
166
+ ```
167
+ <app-searchstax-input
168
+ [afterAutosuggest]="afterAutosuggest"
169
+ [beforeAutosuggest]="beforeAutosuggest"
170
+ [suggestAfterMinChars]="3"
171
+ ></app-searchstax-input>
172
+ ```
173
+
174
+
175
+ example of input widget initialization with template override
176
+ ```
177
+ <app-searchstax-input
178
+ [afterAutosuggest]="afterAutosuggest"
179
+ [beforeAutosuggest]="beforeAutosuggest"
180
+ [suggestAfterMinChars]="3"
181
+ [templateOverride]="inputTemplate"
182
+ >
183
+ <ng-template
184
+ #inputTemplate
185
+ let-suggestions="suggestions"
186
+ let-onMouseLeave="onMouseLeave"
187
+ let-onMouseOver="onMouseOver"
188
+ let-onMouseClick="onMouseClick"
189
+ let-context="context"
190
+ >
191
+ <div class="searchstax-search-input-wrapper">
192
+ <input
193
+ type="text"
194
+ id="searchstax-search-input"
195
+ class="searchstax-search-input"
196
+ placeholder="SEARCH FOR..."
197
+ />
198
+ <div
199
+ class="searchstax-autosuggest-container"
200
+ [ngClass]="{ hidden: suggestions.length === 0 }"
201
+ (mouseleave)="onMouseLeave(context)"
202
+ >
203
+ <div class="searchstax-autosuggest-item" *ngFor="let suggestion of suggestions">
204
+ <div
205
+ class="searchstax-autosuggest-item-term-container"
206
+ [innerHtml]="suggestion.term"
207
+ (mouseover)="onMouseOver(suggestion, context)"
208
+ (click)="onMouseClick($event, context)"
209
+ ></div>
210
+ </div>
211
+ </div>
212
+ <button class="searchstax-spinner-icon" id="searchstax-search-input-action-button"></button>
213
+ </div>
214
+ </ng-template>
215
+ </app-searchstax-input>
216
+ ```
217
+ ### Result Widget ###
218
+
219
+ example of results widget initialization with minimum options
220
+ ```
221
+ <app-searchstax-results
222
+ [afterLinkClick]="afterLinkClick"
223
+ ></app-searchstax-results>
224
+ ```
225
+
226
+ example of result widget initialization with template override
227
+ ```
228
+ <app-searchstax-results
229
+ [afterLinkClick]="afterLinkClick"
230
+ [resultsTemplate]="resultsTemplate"
231
+ [noResultsTemplate]="noResultsTemplate"
232
+ >
233
+ <ng-template
234
+ #resultsTemplate
235
+ let-searchResults="searchResults"
236
+ let-resultClicked="resultClicked"
237
+ let-isImage="isImage"
238
+ let-context="context"
239
+ >
240
+ <div class="searchstax-search-results">
241
+ <div
242
+ class="searchstax-search-result"
243
+ [ngClass]="{ 'has-thumbnail': searchResult.thumbnail }"
244
+ *ngFor="let searchResult of searchResults"
245
+ >
246
+ <div *ngIf="searchResult.promoted" class="searchstax-search-result-promoted"></div>
247
+ <a
248
+ *ngIf="searchResult.url"
249
+ [href]="searchResult.url"
250
+ [attr.data-searchstax-unique-result-id]="searchResult.uniqueId"
251
+ (click)="resultClicked(searchResult, $event, context)"
252
+ class="searchstax-result-item-link"
253
+ ></a>
254
+ <div *ngIf="searchResult.ribbon" class="searchstax-search-result-ribbon">
255
+ {{ searchResult.ribbon }}
256
+ </div>
257
+ <img *ngIf="searchResult.thumbnail" [src]="searchResult.thumbnail" class="searchstax-thumbnail" />
258
+ <div class="searchstax-search-result-title-container">
259
+ <span class="searchstax-search-result-title">{{ searchResult.title }}</span>
260
+ </div>
261
+ <p *ngIf="searchResult.paths" class="searchstax-search-result-common">
262
+ {{ searchResult.paths }}
263
+ </p>
264
+ <p
265
+ *ngIf="searchResult.description"
266
+ class="searchstax-search-result-description searchstax-search-result-common"
267
+ >
268
+ {{ searchResult.description }}
269
+ </p>
270
+ <div *ngFor="let unmappedField of searchResult.unmappedFields">
271
+ <div *ngIf="isImage(unmappedField)" class="searchstax-search-result-image-container">
272
+ <img [src]="unmappedField.value" class="searchstax-result-image" />
273
+ </div>
274
+ <div *ngIf="!isImage(unmappedField)">
275
+ <p class="searchstax-search-result-common">
276
+ {{ unmappedField.value }}
277
+ </p>
278
+ </div>
279
+ </div>
280
+ </div>
281
+ </div>
282
+ </ng-template>
283
+ <ng-template #noResultsTemplate let-metadata="metadata" let-searchTerm="searchTerm">
284
+ <div class="searchstax-no-results">
285
+ Showing <strong>no results</strong> for
286
+ <strong>"{{ searchTerm }}"</strong>
287
+ <br />
288
+ <span *ngIf="metadata?.spellingSuggestion"
289
+ >&nbsp;Did you mean
290
+ <a href="#" class="searchstax-suggestion-term">{{ metadata?.spellingSuggestion }}</a
291
+ >?</span
292
+ >
293
+ </div>
294
+ <div>
295
+ <p>
296
+ Try searching for search related terms or topics. We offer a wide variety of content to help you get
297
+ the information you need.
298
+ </p>
299
+ <p>Lost? Click on the ‘X” in the Search Box to reset your search.</p>
300
+ </div>
301
+ </ng-template>
302
+ </app-searchstax-results>
303
+ ```
304
+
305
+ ### Pagination Widget ###
306
+
307
+
308
+ example of pagination widget initialization with minimum options
309
+ ```
310
+ <app-searchstax-search-pagination></app-searchstax-search-pagination>
311
+ ```
312
+
313
+ example of pagination widget initialization with various options
314
+ ```
315
+ <app-searchstax-search-pagination [templateOverride]="paginationTemplate">
316
+ <ng-template
317
+ #paginationTemplate
318
+ let-paginationData="paginationData"
319
+ let-previousPage="previousPage"
320
+ let-nextPage="nextPage"
321
+ let-context="context"
322
+ >
323
+ <div class="searchstax-pagination-container">
324
+ <div class="searchstax-pagination-content">
325
+ <a
326
+ class="searchstax-pagination-previous"
327
+ (click)="previousPage($event, context)"
328
+ id="searchstax-pagination-previous"
329
+ >
330
+ &lt; Previous
331
+ </a>
332
+ <div class="searchstax-pagination-details">
333
+ {{ paginationData?.startResultIndex }} - {{ paginationData?.endResultIndex }} of
334
+ {{ paginationData?.totalResults }}
335
+ </div>
336
+ <a
337
+ class="searchstax-pagination-next"
338
+ (click)="nextPage($event, context)"
339
+ id="searchstax-pagination-next"
340
+ >Next ></a
341
+ >
342
+ </div>
343
+ </div>
344
+ </ng-template>
345
+ </app-searchstax-search-pagination>
346
+ ```
347
+
348
+ ### Facets Widget ###
349
+
350
+ example of facets widget initialization with minimum options
351
+ ```
352
+ <app-searchstax-search-facets
353
+ [facetingType]="'showUnavailable'"
354
+ [itemsPerPageDesktop]="2"
355
+ [itemsPerPageMobile]="99"
356
+ ></app-searchstax-search-facets>
357
+ ```
358
+
359
+
360
+ example of facets widget initialization with template overrides
361
+ ```
362
+ <app-searchstax-search-facets
363
+ [facetingType]="'showUnavailable'"
364
+ [itemsPerPageDesktop]="2"
365
+ [itemsPerPageMobile]="99"
366
+ [templateOverrideDesktop]="templateOverrideDesktop"
367
+ [templateOverrideMobile]="templateOverrideMobile"
368
+ >
369
+ <ng-template
370
+ #templateOverrideDesktop
371
+ let-facetsTemplateDataDesktop="facetsTemplateDataDesktop"
372
+ let-isNotDeactivated="isNotDeactivated"
373
+ let-context="context"
374
+ let-toggleFacetGroup="toggleFacetGroup"
375
+ let-facetValues="facetValues"
376
+ let-isChecked="isChecked"
377
+ let-selectFacet="selectFacet"
378
+ let-showMoreLessDesktop="showMoreLessDesktop"
379
+ >
380
+ <div class="searchstax-facets-container-desktop">
381
+ <div
382
+ class="searchstax-facet-container"
383
+ *ngFor="let facet of facetsTemplateDataDesktop?.facets"
384
+ [class]="{ active: isNotDeactivated(facet.name, context) }"
385
+ >
386
+ <div>
387
+ <div class="searchstax-facet-title-container" (click)="toggleFacetGroup(facet.name, context)">
388
+ <div class="searchstax-facet-title">{{ facet.label }}</div>
389
+ <div class="searchstax-facet-title-arrow active"></div>
390
+ </div>
391
+ <div class="searchstax-facet-values-container">
392
+ <div
393
+ *ngFor="let facetValue of facetValues(facet); index as key"
394
+ class="searchstax-facet-value-container"
395
+ [class]="{ 'searchstax-facet-value-disabled': facetValue.disabled }"
396
+ #ref
397
+ >
398
+ <div class="searchstax-facet-input">
399
+ <input
400
+ type="checkbox"
401
+ class="searchstax-facet-input-checkbox"
402
+ [checked]="isChecked(facetValue, context)"
403
+ [disabled]="facetValue.disabled"
404
+ (click)="selectFacet(ref, $event, facetValue, true, context)"
405
+ />
406
+ </div>
407
+ <div
408
+ class="searchstax-facet-value-label"
409
+ (click)="selectFacet(ref, $event, facetValue, false, context)"
410
+ >
411
+ {{ facetValue.value }}
412
+ </div>
413
+ <div
414
+ class="searchstax-facet-value-count"
415
+ (click)="selectFacet(ref, $event, facetValue, false, context)"
416
+ >
417
+ ({{ facetValue.count }})
418
+ </div>
419
+ </div>
420
+ <div class="searchstax-facet-show-more-container" *ngIf="facet.hasMoreFacets">
421
+ <div
422
+ class="searchstax-facet-show-more-container"
423
+ (click)="showMoreLessDesktop($event, facet, context)"
424
+ >
425
+ <div
426
+ *ngIf="facet.showingAllFacets"
427
+ class="searchstax-facet-show-less-button searchstax-facet-show-button"
428
+ >
429
+ less
430
+ </div>
431
+ <div
432
+ *ngIf="!facet.showingAllFacets"
433
+ class="searchstax-facet-show-more-button searchstax-facet-show-button"
434
+ >
435
+ more
436
+ </div>
437
+ </div>
438
+ </div>
439
+ </div>
440
+ </div>
441
+ </div>
442
+ </div>
443
+ </ng-template>
444
+ <ng-template
445
+ #templateOverrideMobile
446
+ let-isNotDeactivated="isNotDeactivated"
447
+ let-context="context"
448
+ let-toggleFacetGroup="toggleFacetGroup"
449
+ let-facetValues="facetValues"
450
+ let-isChecked="isChecked"
451
+ let-selectFacet="selectFacet"
452
+ let-openOverlay="openOverlay"
453
+ let-selectedFacetsCheckboxes="selectedFacetsCheckboxes"
454
+ let-unselectFacet="unselectFacet"
455
+ let-unselectAll="unselectAll"
456
+ let-facetMobileData="facetMobileData"
457
+ let-facetsTemplateDataMobile="facetsTemplateDataMobile"
458
+ let-closeOverlay="closeOverlay"
459
+ let-showMoreLessDesktop="showMoreLessDesktop"
460
+ >
461
+ <div class="searchstax-facets-container-mobile">
462
+ <div class="searchstax-facets-pills-container">
463
+ <div class="searchstax-facets-pill searchstax-facets-pill-filter-by" (click)="openOverlay(context)">
464
+ <div class="searchstax-facets-pill-label">Filter By</div>
465
+ </div>
466
+ <div class="searchstax-facets-pills-selected">
467
+ <div
468
+ class="searchstax-facets-pill searchstax-facets-pill-facets"
469
+ *ngFor="let facet of selectedFacetsCheckboxes"
470
+ (click)="unselectFacet(facet, context)"
471
+ >
472
+ <div class="searchstax-facets-pill-label">{{ facet.value }} ({{ facet.count }})</div>
473
+ <div class="searchstax-facets-pill-icon-close"></div>
474
+ </div>
475
+ </div>
476
+ <div
477
+ class="searchstax-facets-pill searchstax-clear-filters searchstax-facets-pill-clear-all"
478
+ *ngIf="selectedFacetsCheckboxes.length"
479
+ (click)="unselectAll(context)"
480
+ >
481
+ <div class="searchstax-facets-pill-label">Clear Filters</div>
482
+ </div>
483
+ </div>
484
+ <div
485
+ class="searchstax-facets-mobile-overlay"
486
+ [class]="{ 'searchstax-show': facetMobileData(facetsTemplateDataMobile)?.overlayOpened }"
487
+ >
488
+ <div class="searchstax-facets-mobile-overlay-header">
489
+ <div class="searchstax-facets-mobile-overlay-header-title">Filter By</div>
490
+ <div class="searchstax-search-close" (click)="closeOverlay(context)"></div>
491
+ </div>
492
+ <div class="searchstax-facets-container-mobile">
493
+ <div
494
+ *ngFor="let facet of facetsTemplateDataMobile?.facets"
495
+ class="searchstax-facet-container"
496
+ [class]="{ active: isNotDeactivated(facet.name, context) }"
497
+ >
498
+ <div>
499
+ <div class="searchstax-facet-title-container" (click)="toggleFacetGroup(facet.name, context)">
500
+ <div class="searchstax-facet-title">{{ facet.label }}</div>
501
+ <div class="searchstax-facet-title-arrow active"></div>
502
+ </div>
503
+ <div class="searchstax-facet-values-container">
504
+ <div
505
+ *ngFor="let facetValue of facetValues(facet); index as key"
506
+ class="searchstax-facet-value-container"
507
+ [class]="{ 'searchstax-facet-value-disabled': facetValue.disabled }"
508
+ #ref
509
+ >
510
+ <div class="searchstax-facet-input">
511
+ <input
512
+ type="checkbox"
513
+ class="searchstax-facet-input-checkbox"
514
+ [checked]="isChecked(facetValue, context)"
515
+ [disabled]="facetValue.disabled"
516
+ (click)="selectFacet(ref, $event, facetValue, true, context)"
517
+ />
518
+ </div>
519
+ <div
520
+ class="searchstax-facet-value-label"
521
+ (click)="selectFacet(ref, $event, facetValue, false, context)"
522
+ >
523
+ {{ facetValue.value }}
524
+ </div>
525
+ <div
526
+ class="searchstax-facet-value-count"
527
+ (click)="selectFacet(ref, $event, facetValue, false, context)"
528
+ >
529
+ ({{ facetValue.count }})
530
+ </div>
531
+ </div>
532
+ <div class="searchstax-facet-show-more-container" *ngIf="facet.hasMoreFacets">
533
+ <div
534
+ class="searchstax-facet-show-more-container"
535
+ (click)="showMoreLessDesktop($event, facet, context)"
536
+ >
537
+ <div
538
+ *ngIf="facet.showingAllFacets"
539
+ class="searchstax-facet-show-less-button searchstax-facet-show-button"
540
+ >
541
+ less
542
+ </div>
543
+ <div
544
+ *ngIf="!facet.showingAllFacets"
545
+ class="searchstax-facet-show-more-button searchstax-facet-show-button"
546
+ >
547
+ more
548
+ </div>
549
+ </div>
550
+ </div>
551
+ </div>
552
+ </div>
553
+ </div>
554
+ </div>
555
+ <button class="searchstax-facets-mobile-overlay-done" (click)="closeOverlay(context)">Done</button>
556
+ </div>
557
+ </div>
558
+ </ng-template>
559
+ </app-searchstax-search-facets>
560
+ ```
561
+
562
+ ### SearchFeedback Widget ###
563
+
564
+ example of search feedback widget initialization with minimum options
565
+ ```
566
+ <app-searchstax-search-feedback></app-searchstax-search-feedback>
567
+ ```
568
+
569
+
570
+ example of search feedback widget initialization with template overrides
571
+ ```
572
+ <app-searchstax-search-feedback [templateOverride]="feedbackTemplate">
573
+ <ng-template
574
+ #feedbackTemplate
575
+ let-searchFeedbackData="searchFeedbackData"
576
+ let-onOriginalQueryClick="onOriginalQueryClick"
577
+ let-context="context"
578
+ >
579
+ <div class="searchstax-feedback-container">
580
+ Showing
581
+ <b>{{ searchFeedbackData!.startResultIndex }} - {{ searchFeedbackData!.endResultIndex }}</b>
582
+ of <b>{{ searchFeedbackData!.totalResults }}</b> results
583
+ <span *ngIf="searchFeedbackData.searchTerm"
584
+ >for "<b>{{ searchFeedbackData!.searchTerm }}</b
585
+ >"
586
+ </span>
587
+ <div class="searchstax-feedback-container-suggested">
588
+ <div *ngIf="searchFeedbackData.autoCorrectedQuery">
589
+ Search instead for
590
+ <a
591
+ href="#"
592
+ (click)="onOriginalQueryClick($event, context)"
593
+ class="searchstax-feedback-original-query"
594
+ >{{ searchFeedbackData!.originalQuery }}</a
595
+ >
596
+ </div>
597
+ </div>
598
+ </div>
599
+ </ng-template>
600
+ </app-searchstax-search-feedback>
601
+ ```
602
+
603
+ ## RelatedSearches widget
604
+
605
+
606
+
607
+ example of search RelatedSearches widget initialization with minimum options
608
+ ```
609
+ <app-searchstax-related-searches
610
+ [relatedSearchesURL]="config.relatedSearchesURL"
611
+ [relatedSearchesAPIKey]="config.relatedSearchesAPIKey"
612
+ ></app-searchstax-related-searches>
613
+ ```
614
+
615
+
616
+ example of search RelatedSearches widget initialization with template overrides
617
+ ```
618
+ <app-searchstax-related-searches
619
+ [relatedSearchesURL]="config.relatedSearchesURL"
620
+ [relatedSearchesAPIKey]="config.relatedSearchesAPIKey"
621
+ [templateOverride]="relatedTemplate"
622
+ >
623
+ <ng-template
624
+ #relatedTemplate
625
+ let-rand="rand"
626
+ let-relatedData="relatedData"
627
+ let-executeSearch="executeSearch"
628
+ let-context="context"
629
+ >
630
+ <div class="searchstax-related-searches-container" [id]="'searchstax-related-searches-container' + rand">
631
+ Related searches: <span id="searchstax-related-searches"></span>
632
+ <span class="searchstax-related-search" *ngIf="relatedData.relatedSearches">
633
+ <span
634
+ *ngFor="let related of relatedData.relatedSearches"
635
+ (click)="executeSearch(related, context)"
636
+ class="searchstax-related-search searchstax-related-search-item"
637
+ >
638
+ {{ related.related_search }}<span *ngIf="!related.last">,</span>
639
+ </span>
640
+ </span>
641
+ </div>
642
+ </ng-template>
643
+ </app-searchstax-related-searches>
644
+ ```
645
+
646
+ ### ExternalPromotions widget ###
647
+
648
+ example of search ExternalPromotions widget initialization with minimum options
649
+ ```
650
+ <app-searchstax-external-promotions></app-searchstax-external-promotions>
651
+ ```
652
+
653
+
654
+ example of search ExternalPromotions widget initialization with template overrides
655
+ ```
656
+ <app-searchstax-external-promotions [templateOverride]="externalPromotionsTemplate">
657
+ <ng-template
658
+ #externalPromotionsTemplate
659
+ let-context="context"
660
+ let-externalPromotionsData="externalPromotionsData"
661
+ let-trackClick="trackClick"
662
+ >
663
+ <div class="searchstax-external-promotions-container" id="searchstax-external-promotions-container">
664
+ <div
665
+ class="searchstax-external-promotion searchstax-search-result"
666
+ *ngFor="let externalPromotion of externalPromotionsData.externalPromotions"
667
+ >
668
+ <div class="icon-elevated"></div>
669
+ <a
670
+ *ngIf="externalPromotion.url"
671
+ [href]="externalPromotion.url"
672
+ (click)="trackClick(externalPromotion, $event, context)"
673
+ class="searchstax-result-item-link"
674
+ ></a>
675
+ <div class="searchstax-search-result-title-container">
676
+ <span class="searchstax-search-result-title">{{ externalPromotion.name }}</span>
677
+ </div>
678
+ <p
679
+ *ngIf="externalPromotion.description"
680
+ class="searchstax-search-result-description searchstax-search-result-common"
681
+ >
682
+ {{ externalPromotion.description }}
683
+ </p>
684
+ <p
685
+ *ngIf="externalPromotion.url"
686
+ class="searchstax-search-result-description searchstax-search-result-common"
687
+ >
688
+ {{ externalPromotion.url }}
689
+ </p>
690
+ </div>
691
+ </div>
692
+ </ng-template>
693
+ </app-searchstax-external-promotions>
694
+ ```
695
+
696
+
697
+ ### Sorting Widget ###
698
+
699
+ example of sorting widget initialization with minimum options
700
+ ```
701
+ <app-searchstax-search-sorting></app-searchstax-search-sorting>
702
+ ```
703
+
704
+
705
+ example of sorting widget initialization with template override
706
+ ```
707
+ <app-searchstax-search-sorting [templateOverride]="sortingTemplateOverride">
708
+ <ng-template
709
+ #sortingTemplateOverride
710
+ let-selectedSorting="selectedSorting"
711
+ let-orderChange="orderChange"
712
+ let-context="context"
713
+ >
714
+ <div class="searchstax-sorting-container">
715
+ <label class="searchstax-sorting-label" for="sort-by">Sort By</label>
716
+ <select
717
+ id="searchstax-search-order-select"
718
+ class="searchstax-search-order-select"
719
+ [value]="selectedSorting"
720
+ (change)="orderChange($event, context)"
721
+ >
722
+ <option value="">Relevance</option>
723
+ <option value="date desc">Newest Content</option>
724
+ <option value="date asc">Oldest Content</option>
725
+ </select>
726
+ </div>
727
+ </ng-template>
728
+ </app-searchstax-search-sorting>
729
+ ```
730
+
731
+
732
+ ## Template overrides
733
+ Templates are passed to components via props.
734
+
735
+ ## STYLING
736
+
737
+ scss styles can be imported from searchstudio-ux-js
738
+ ```
739
+ @import './../node_modules/@searchstax-inc/searchstudio-ux-js/dist/styles/scss/mainTheme.scss';
740
+ ```
741
+ css can be taken from
742
+
743
+ ```
744
+ ./../node_modules/@searchstax-inc/searchstudio-ux-js/dist/styles/mainTheme.css
745
+ ```