@fluid-topics/ft-search-bar 0.0.88

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.
@@ -0,0 +1,1126 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { css, html, nothing } from "lit";
8
+ import { property, query, state } from "lit/decorators.js";
9
+ import { repeat } from "lit/directives/repeat.js";
10
+ import { classMap } from "lit/directives/class-map.js";
11
+ import { customElement, Debouncer, FtLitElement, jsonProperty, ParametrizedLabelResolver } from "@fluid-topics/ft-wc-utils";
12
+ import { FtSizeCategory, FtSizeWatcher } from "@fluid-topics/ft-size-watcher";
13
+ import { FtTypography, FtTypographyBody2 } from "@fluid-topics/ft-typography";
14
+ import { facetToFilter, getBreadcrumbFromValue, getLabelFromValue, selectedValues, serializeRequest } from "./converters";
15
+ import { FtFilter, FtFilterOption } from "@fluid-topics/ft-filter";
16
+ import { FtIcon, FtIcons, FtIconVariants, resolveFileFormatIcon, } from "@fluid-topics/ft-icon";
17
+ import { FtAccordion, FtAccordionItem } from "@fluid-topics/ft-accordion";
18
+ import { FtButton } from "@fluid-topics/ft-button";
19
+ import { FtChip } from "@fluid-topics/ft-chip";
20
+ import { FtSelect, FtSelectOption } from "@fluid-topics/ft-select";
21
+ import { FtSnapScroll } from "@fluid-topics/ft-snap-scroll";
22
+ import { FtTooltip } from "@fluid-topics/ft-tooltip";
23
+ import { Icon } from "@material/mwc-icon";
24
+ import { FtRipple } from "@fluid-topics/ft-ripple";
25
+ import { flatDeep } from "@fluid-topics/ft-filter/build/utils";
26
+ if (window.fluidtopics == null) {
27
+ console.warn("Fluid Topics public API was not found. You can find it here: https://www.npmjs.com/package/@fluid-topics/public-api");
28
+ }
29
+ export const DEFAULT_LABELS = {
30
+ filtersButton: "Filters",
31
+ oneFilterEnabled: "1 filter enabled",
32
+ nFiltersEnabled: "{0} filter(s) enabled",
33
+ inputPlaceHolder: "Search",
34
+ filterInputPlaceHolder: "Filter {0}",
35
+ clearInputButton: "Clear",
36
+ clearFilterButton: "Clear",
37
+ displayMoreFilterValuesButton: "More",
38
+ searchButton: "Search",
39
+ noSuggestions: "No results found…",
40
+ clearFilters: "Clear filters",
41
+ contentLocaleSelector: "Lang",
42
+ removeRecentSearch: "Remove",
43
+ back: "Back",
44
+ };
45
+ export class LaunchSearchEvent extends CustomEvent {
46
+ constructor(request) {
47
+ super("launch-search", { detail: request });
48
+ }
49
+ }
50
+ export class SearchStateChangeEvent extends CustomEvent {
51
+ constructor(request) {
52
+ super("change", { detail: request });
53
+ }
54
+ }
55
+ let FtSearchBar = class FtSearchBar extends FtLitElement {
56
+ constructor() {
57
+ super(...arguments);
58
+ this.baseUrl = "";
59
+ this.apiIntegrationIdentifier = "ft-search-bar";
60
+ this.availableContentLocales = [];
61
+ this.labels = {};
62
+ this.labelResolver = new ParametrizedLabelResolver(DEFAULT_LABELS, {});
63
+ this.displayedFilters = [];
64
+ this.searchRequestSerializer = (request) => serializeRequest(this.baseUrl, request);
65
+ this.searchFilters = [];
66
+ this.sizeCategory = FtSizeCategory.S;
67
+ this.displayFacets = false;
68
+ this.mobileMenuOpen = false;
69
+ this.facets = [];
70
+ this.query = "";
71
+ this.suggestions = [];
72
+ this.suggestionsLoaded = true;
73
+ this.recentSearches = [];
74
+ this.updateFacetsDebouncer = new Debouncer(500);
75
+ this.suggestDebouncer = new Debouncer(300);
76
+ this.facetsLoaded = false;
77
+ this.closeFloatingContainer = (e) => {
78
+ if (this.sizeCategory !== FtSizeCategory.S) {
79
+ this.displayFacets = this.displayFacets && e.composedPath().some(element => element === this.floatingContainer);
80
+ }
81
+ };
82
+ }
83
+ // language=CSS
84
+ getStyles() {
85
+ return [
86
+ FtTypographyBody2,
87
+ css `
88
+ * {
89
+ box-sizing: border-box;
90
+ }
91
+
92
+ .ft-search-bar--container {
93
+ display: flex;
94
+ flex-direction: column;
95
+ gap: 8px;
96
+ background: var(--ft-color-surface, #FFFFFF);
97
+ outline: none;
98
+
99
+ --ft-search-bar-border-radius--internal: var(--ft-search-bar-border-radius, var(--ft-border-radius-S, 4px))
100
+ }
101
+
102
+ .ft-search-bar--mobile-menu-open {
103
+ position: var(--ft-search-bar-mobile-open-position, fixed);
104
+ top: var(--ft-search-bar-mobile-open-top, 0);
105
+ bottom: var(--ft-search-bar-mobile-open-bottom, 0);
106
+ left: var(--ft-search-bar-mobile-open-left, 0);
107
+ right: var(--ft-search-bar-mobile-open-right, 0);
108
+ z-index: var(--ft-search-bar-floating-components-z-index, 1);
109
+ padding: 16px;
110
+ }
111
+
112
+ .ft-search-bar {
113
+ flex-shrink: 0;
114
+ position: relative;
115
+ display: flex;
116
+ flex-direction: row;
117
+ align-items: center;
118
+ height: var(--ft-search-bar-height, 38px);
119
+
120
+ background: var(--ft-color-surface, #FFFFFF);
121
+ border: 1px solid var(--ft-color-outline, rgba(0, 0, 0, 0.14));
122
+ border-radius: var(--ft-search-bar-border-radius--internal);
123
+ }
124
+
125
+ .ft-search-bar--floating-panel-open .ft-search-bar {
126
+ border-radius: var(--ft-search-bar-border-radius--internal) var(--ft-search-bar-border-radius--internal) 0 0;
127
+ }
128
+
129
+ .ft-search-bar--input-container {
130
+ flex-grow: 1;
131
+ flex-shrink: 1;
132
+ align-self: stretch;
133
+ position: relative;
134
+ }
135
+
136
+ .ft-search-bar--input {
137
+ border: none;
138
+ background-color: transparent;
139
+ padding: 0 8px;
140
+ height: 100%;
141
+ width: 100%;
142
+ }
143
+
144
+ .ft-search-bar--input:focus-within {
145
+ outline-color: var(--ft-color-primary, #2196F3);
146
+ }
147
+
148
+ .ft-search-bar--mobile .ft-search-bar--suggestions {
149
+ flex-grow: 1;
150
+ flex-shrink: 1;
151
+ overflow-y: auto;
152
+ height: 0;
153
+ }
154
+
155
+ .ft-search-bar--mobile-open .ft-search-bar--suggestions {
156
+ height: initial;
157
+ }
158
+
159
+ .ft-search-bar--floating-panel,
160
+ .ft-search-bar--desktop .ft-search-bar--suggestions {
161
+ position: absolute;
162
+ z-index: var(--ft-search-bar-floating-components-z-index, 1);
163
+ top: 100%;
164
+ left: -1px;
165
+ right: -1px;
166
+ display: none;
167
+ background: var(--ft-color-surface, #FFFFFF);
168
+ border: 1px solid var(--ft-color-outline, rgba(0, 0, 0, 0.14));
169
+ border-radius: 0 0 var(--ft-search-bar-border-radius--internal) var(--ft-search-bar-border-radius--internal);
170
+ box-shadow: var(--ft-elevation-02, 0px 4px 10px 0px rgba(0, 0, 0, 0.06), 0px 2px 5px 0px rgba(0, 0, 0, 0.14), 0px 0px 1px 0px rgba(0, 0, 0, 0.06));
171
+ outline: none;
172
+ }
173
+
174
+ .ft-search-bar--desktop .ft-search-bar--suggestions {
175
+ top: calc(100% + 1px);
176
+ }
177
+
178
+ .ft-search-bar--input-container:focus-within .ft-search-bar--suggestions-not-empty {
179
+ display: block;
180
+ }
181
+
182
+ .ft-search-bar--no-suggestions {
183
+ text-align: center;
184
+ padding: 8px;
185
+ color: var(--ft-color-on-surface, rgba(0, 0, 0, 0.87));
186
+ }
187
+
188
+ .ft-search-bar--suggestion {
189
+ text-decoration: none;
190
+ position: relative;
191
+ display: flex;
192
+ align-items: center;
193
+ padding: 8px;
194
+ gap: 8px;
195
+ cursor: pointer;
196
+ color: var(--ft-color-on-surface, rgba(0, 0, 0, 0.87));
197
+ min-height: 52px;
198
+ }
199
+
200
+ .ft-search-bar--desktop .ft-search-bar--suggestion {
201
+ min-height: 44px;
202
+ }
203
+
204
+ .ft-search-bar--suggestion:focus {
205
+ outline: none;
206
+ }
207
+
208
+ .ft-search-bar--mobile .ft-search-bar--suggestion:first-child,
209
+ .ft-search-bar--recent-search + .ft-search-bar--suggestion:not(.ft-search-bar--recent-search) {
210
+ border-top: 1px solid var(--ft-color-outline, rgba(0, 0, 0, 0.14));
211
+ }
212
+
213
+ .ft-search-bar--suggestion ft-typography {
214
+ display: block;
215
+ flex-grow: 1;
216
+ flex-shrink: 1;
217
+ }
218
+
219
+ .ft-search-bar > ft-button {
220
+ flex-shrink: 0;
221
+ }
222
+
223
+ .ft-search-bar--left-action {
224
+ --ft-border-radius-L: calc(var(--ft-search-bar-border-radius--internal) - 1px) 0 0 calc(var(--ft-search-bar-border-radius--internal) - 1px);
225
+ border-right: 1px solid var(--ft-color-outline, rgba(0, 0, 0, 0.14));
226
+ }
227
+
228
+ .ft-search-bar--floating-panel-open .ft-search-bar--left-action {
229
+ --ft-border-radius-L: calc(var(--ft-search-bar-border-radius--internal) - 1px) 0 0 0;
230
+ }
231
+
232
+ .ft-search-bar--launch-search,
233
+ .ft-search-bar--clear-query {
234
+ margin: 0 4px;
235
+ }
236
+
237
+ .ft-search-bar--separator {
238
+ height: 20px;
239
+ border-right: 1px solid var(--ft-color-outline, rgba(0, 0, 0, 0.14));
240
+ }
241
+
242
+ .ft-search-bar--floating-panel {
243
+ padding: 16px;
244
+ }
245
+
246
+ .ft-search-bar--floating-panel-open .ft-search-bar--floating-panel {
247
+ display: block;
248
+ }
249
+
250
+ .ft-search-bar--desktop .ft-search-bar--facets-actions {
251
+ display: flex;
252
+ align-items: center;
253
+ justify-content: flex-end;
254
+ gap: 8px;
255
+ padding: 0 10px;
256
+ margin-bottom: 16px;
257
+ }
258
+
259
+ .ft-search-bar--mobile .ft-search-bar--facets-actions {
260
+ flex-shrink: 0;
261
+ flex-grow: 0;
262
+ display: flex;
263
+ gap: 16px;
264
+ justify-content: space-evenly;
265
+ }
266
+
267
+ .ft-search-bar--mobile .ft-search-bar--facets-actions > * {
268
+ flex-grow: 1;
269
+ flex-basis: 0;
270
+ }
271
+
272
+ .ft-search-bar > .ft-search-bar--content-locale,
273
+ .ft-search-bar > .ft-search-bar--content-locale::part(container),
274
+ .ft-search-bar > .ft-search-bar--content-locale::part(main-panel) {
275
+ height: 100%;
276
+ }
277
+
278
+ .ft-search-bar > .ft-search-bar--content-locale::part(options) {
279
+ top: calc(100% + 1px);
280
+ right: unset;
281
+ width: max-content;
282
+ min-width: 100%;
283
+ }
284
+
285
+ .ft-search-bar > .ft-search-bar--content-locale::part(selected-value) {
286
+ --ft-color-on-surface: var(--ft-button-color, var(--ft-color-primary, #2196F3));
287
+ --ft-ripple-color: var(--ft-button-color, var(--ft-color-primary, #2196F3));
288
+ border-radius: calc(var(--ft-search-bar-border-radius--internal) - 1px) 0 0 calc(var(--ft-search-bar-border-radius--internal) - 1px);
289
+ }
290
+
291
+ .ft-search-bar > .ft-search-bar--content-locale::part(label) {
292
+ --ft-input-label-border-color: transparent;
293
+ --ft-ripple-color: var(--ft-button-color, var(--ft-color-primary, #2196F3));
294
+ }
295
+
296
+ .ft-search-bar--floating-panel .ft-search-bar--content-locale {
297
+ margin-right: auto;
298
+ min-width: 250px;
299
+ --ft-select-options-z-index: 2;
300
+ }
301
+
302
+ .ft-search-bar--mobile .ft-search-bar--content-locale::part(clear-button) {
303
+ display: none;
304
+ }
305
+
306
+ .ft-search-bar--floating-panel .ft-search-bar--filters-container {
307
+ display: block;
308
+ height: 400px;
309
+ --ft-snap-scroll-gap: 16px;
310
+ }
311
+
312
+ .ft-search-bar--floating-panel ft-filter {
313
+ display: flex;
314
+ flex-grow: 0;
315
+ max-height: 100%;
316
+ max-width: 250px;
317
+ }
318
+
319
+ .ft-search-bar--hierarchical-filter {
320
+ width: 250px;
321
+ }
322
+
323
+ .ft-search-bar--mobile .ft-search-bar--filters-container {
324
+ flex-grow: 1;
325
+ flex-shrink: 1;
326
+ overflow-y: auto;
327
+ margin: 0 -16px;
328
+ padding: 0 16px;
329
+ }
330
+
331
+ .ft-search-bar--mobile .ft-search-bar--filters-container ft-filter {
332
+ display: flex;
333
+ max-height: 60vh;
334
+ }
335
+
336
+ .ft-search-bar--mobile ft-filter::part(container) {
337
+ flex-grow: 1;
338
+ }
339
+
340
+ .ft-search-bar--filter-label {
341
+ display: flex;
342
+ justify-content: space-between;
343
+ align-items: baseline;
344
+ gap: 8px;
345
+ }
346
+
347
+ .ft-search-bar--filter-label > * {
348
+ white-space: nowrap;
349
+ overflow: hidden;
350
+ text-overflow: ellipsis;
351
+ }
352
+
353
+ .ft-search-bar--filter-label > :first-child {
354
+ flex-shrink: 0;
355
+ }
356
+
357
+ .ft-search-bar--filter-label > :last-child {
358
+ flex-shrink: 1;
359
+ color: var(--ft-color-on-surface-medium, rgba(0, 0, 0, 0.60))
360
+ }
361
+
362
+ ft-accordion-item::part(toggle) {
363
+ margin-left: -16px;
364
+ margin-right: -16px;
365
+ }
366
+
367
+ ft-accordion-item::part(label) {
368
+ overflow: hidden;
369
+ }
370
+
371
+ ft-accordion-item::part(content) {
372
+ padding-left: 0;
373
+ padding-right: 0;
374
+ }
375
+
376
+ .ft-search-bar--selected-filters {
377
+ flex-shrink: 0;
378
+ display: flex;
379
+ flex-direction: row;
380
+ flex-wrap: wrap;
381
+ gap: 8px;
382
+ }
383
+
384
+ .ft-search-bar--selected-filters * {
385
+ max-width: 100%;
386
+ }
387
+ `
388
+ ];
389
+ }
390
+ get recentSearchesStorageKey() {
391
+ return this.baseUrl + ":ft:recent-search-queries";
392
+ }
393
+ get request() {
394
+ return {
395
+ uiLocale: this.uiLocale,
396
+ contentLocale: this.contentLocale,
397
+ query: this.query,
398
+ facets: this.displayedFilters.map(id => ({ id })),
399
+ filters: this.searchFilters,
400
+ paging: { perPage: 0, page: 1 },
401
+ sort: [],
402
+ };
403
+ }
404
+ get suggestRequest() {
405
+ return {
406
+ contentLocale: this.contentLocale,
407
+ input: this.query,
408
+ filters: this.searchFilters,
409
+ sort: [],
410
+ };
411
+ }
412
+ get hasFacets() {
413
+ return this.facets.length > 0;
414
+ }
415
+ get hasLocaleSelector() {
416
+ return this.availableContentLocales.length > 1;
417
+ }
418
+ focus() {
419
+ var _a;
420
+ (_a = this.container) === null || _a === void 0 ? void 0 : _a.focus();
421
+ }
422
+ clear() {
423
+ this.query = "";
424
+ this.searchFilters = [];
425
+ if (this.input) {
426
+ this.input.value = "";
427
+ }
428
+ this.mobileMenuOpen = false;
429
+ this.displayFacets = false;
430
+ }
431
+ getTemplate() {
432
+ const rootClasses = {
433
+ "ft-search-bar--container": true,
434
+ "ft-search-bar--mobile": this.sizeCategory === FtSizeCategory.S,
435
+ "ft-search-bar--desktop": this.sizeCategory !== FtSizeCategory.S,
436
+ "ft-search-bar--floating-panel-open": this.sizeCategory !== FtSizeCategory.S && this.displayFacets,
437
+ "ft-search-bar--mobile-menu-open": this.mobileMenuOpen,
438
+ };
439
+ return html `
440
+ <ft-size-watcher @change=${this.updateSize}></ft-size-watcher>
441
+ <div class="${classMap(rootClasses)}" part="container" tabindex="-1">
442
+ ${this.sizeCategory === FtSizeCategory.S ? this.renderMobileSearchBar() : this.renderDesktopSearchBar()}
443
+ </div>
444
+ `;
445
+ }
446
+ renderDesktopSearchBar() {
447
+ return html `
448
+ <div class="ft-search-bar" part="search-bar">
449
+ ${(this.renderSearchBarLeftAction())}
450
+ <div class="ft-search-bar--input-container" part="input-container">
451
+ <input class="ft-search-bar--input ft-typography--body2"
452
+ part="input"
453
+ type="text"
454
+ placeholder="${this.labelResolver.resolve("inputPlaceHolder")}"
455
+ value="${this.query}"
456
+ @keydown=${this.onSearchBarKeyDown}
457
+ @keyup=${this.onSearchBarKeyUp}>
458
+ ${this.renderSuggestions()}
459
+ </div>
460
+ ${this.renderDesktopSearchBarButtons()}
461
+ <div class="ft-search-bar--floating-panel" @keyup=${this.onFloatingContainerKeyUp} tabindex="-1">
462
+ ${this.renderDesktopFacetsActions()}
463
+ ${this.renderDesktopFacets()}
464
+ </div>
465
+ </div>
466
+ ${this.renderSelectedFacets()}
467
+ `;
468
+ }
469
+ renderSearchBarLeftAction() {
470
+ if (this.hasFacets) {
471
+ return html `
472
+ <ft-button class="ft-search-bar--filters-opener ft-search-bar--left-action"
473
+ part="filters-opener"
474
+ trailingIcon
475
+ icon="${this.displayFacets ? "expand_less" : "expand_more"}"
476
+ @click=${(e) => {
477
+ e.stopPropagation();
478
+ this.displayFacets = !this.displayFacets;
479
+ }}
480
+ @focusin=${(e) => e.stopPropagation()}>
481
+ ${this.labelResolver.resolve("filtersButton")}
482
+ </ft-button>
483
+ `;
484
+ }
485
+ if (this.hasLocaleSelector) {
486
+ return html `
487
+ <ft-select
488
+ class="ft-search-bar--content-locale ft-search-bar--left-action"
489
+ part="content-locale"
490
+ @change=${(e) => this.contentLocale = e.detail}>
491
+ ${repeat(this.availableContentLocales, l => l.lang, l => html `
492
+ <ft-select-option value="${l.lang}"
493
+ label="${l.label}"
494
+ ?selected=${l.lang === this.contentLocale}>
495
+ </ft-select-option>
496
+ `)}
497
+ </ft-select>
498
+ `;
499
+ }
500
+ return nothing;
501
+ }
502
+ renderDesktopSearchBarButtons() {
503
+ return html `
504
+ ${this.query ? html `
505
+ <ft-button class="ft-search-bar--clear-query"
506
+ part="search-bar-actions"
507
+ icon="close"
508
+ round dense
509
+ label="${this.labelResolver.resolve("clearInputButton")}"
510
+ @click=${() => this.setQuery("")}
511
+ ></ft-button>
512
+ <div class="ft-search-bar--separator"></div>
513
+ ` : null}
514
+ <ft-button class="ft-search-bar--launch-search"
515
+ part="search-bar-actions"
516
+ icon="search"
517
+ round dense
518
+ label="${this.labelResolver.resolve("searchButton")}"
519
+ @click=${this.launchSearch}
520
+ ></ft-button>
521
+ `;
522
+ }
523
+ renderMobileSearchBar() {
524
+ return html `
525
+ <div class="ft-search-bar">
526
+ <div class="ft-search-bar--input-container" part="input-container">
527
+ <input class="ft-search-bar--input ft-typography--body2"
528
+ part="input"
529
+ type="text"
530
+ placeholder="${this.labelResolver.resolve("inputPlaceHolder")}"
531
+ value="${this.query}"
532
+ @keyup=${this.onSearchBarKeyUp}
533
+ @focus=${() => {
534
+ this.mobileMenuOpen = true;
535
+ this.displayFacets = false;
536
+ }}>
537
+ </div>
538
+ ${this.renderMobileSearchBarButtons()}
539
+ </div>
540
+ ${this.mobileMenuOpen ? this.renderMobileFacetsActions() : this.renderSelectedFacets()}
541
+ ${this.displayFacets ? this.renderMobileFacets() : this.renderSuggestions()}
542
+ `;
543
+ }
544
+ renderMobileSearchBarButtons() {
545
+ if (this.query || this.mobileMenuOpen) {
546
+ return html `
547
+ <ft-button class="ft-search-bar--clear-query"
548
+ part="search-bar-actions"
549
+ icon="close"
550
+ round
551
+ label="${this.labelResolver.resolve("clearInputButton")}"
552
+ @click=${() => {
553
+ this.setQuery("");
554
+ this.mobileMenuOpen = false;
555
+ this.displayFacets = false;
556
+ }}
557
+ ></ft-button>
558
+ `;
559
+ }
560
+ return html `
561
+ <ft-button class="ft-search-bar--launch-search"
562
+ part="search-bar-actions"
563
+ icon="search"
564
+ round
565
+ label="${this.labelResolver.resolve("searchButton")}"
566
+ @click=${() => { var _a; return (_a = this.input) === null || _a === void 0 ? void 0 : _a.focus(); }}
567
+ ></ft-button>
568
+ `;
569
+ }
570
+ renderMobileFacetsActions() {
571
+ if (!this.hasLocaleSelector && this.displayedFilters.length === 0) {
572
+ return null;
573
+ }
574
+ if (this.displayFacets) {
575
+ return html `
576
+ <div class="ft-search-bar--facets-actions">
577
+ <ft-button part="facets-actions"
578
+ icon="arrow_back"
579
+ label="${this.labelResolver.resolve("back")}"
580
+ @click=${() => this.displayFacets = false}>
581
+ ${this.labelResolver.resolve("back")}
582
+ </ft-button>
583
+ ${this.searchFilters.length > 0 ? html `
584
+ <ft-button part="facets-actions" @click=${this.clearFilters}>
585
+ ${this.labelResolver.resolve("clearFilters")}
586
+ </ft-button>
587
+ ` : null}
588
+ </div>
589
+ `;
590
+ }
591
+ let label = this.searchFilters.length > 0
592
+ ? (this.searchFilters.length > 1
593
+ ? this.labelResolver.resolve("nFiltersEnabled", this.searchFilters.length)
594
+ : this.labelResolver.resolve("oneFilterEnabled"))
595
+ : this.labelResolver.resolve("filtersButton");
596
+ return html `
597
+ <div class="ft-search-bar--facets-actions">
598
+ <ft-button part="facets-actions"
599
+ @click=${() => this.displayFacets = true}>
600
+ ${label}
601
+ </ft-button>
602
+ </div>
603
+ `;
604
+ }
605
+ renderMobileFacets() {
606
+ var _a;
607
+ const currentLocale = this.availableContentLocales.filter(l => l.lang === this.contentLocale).pop();
608
+ const contentLocales = this.availableContentLocales.map(l => ({
609
+ value: l.lang,
610
+ label: l.label,
611
+ selected: l.lang == this.contentLocale,
612
+ options: []
613
+ }));
614
+ return html `
615
+ <ft-accordion class="ft-search-bar--filters-container">
616
+ ${this.hasLocaleSelector ? html `
617
+ <ft-accordion-item>
618
+ <div class="ft-search-bar--filter-label" slot="toggle">
619
+ <ft-typography variant="button">${this.labelResolver.resolve("contentLocaleSelector")}
620
+ </ft-typography>
621
+ <ft-typography variant="body2">
622
+ ${(_a = currentLocale === null || currentLocale === void 0 ? void 0 : currentLocale.label) !== null && _a !== void 0 ? _a : ""}
623
+ </ft-typography>
624
+ </div>
625
+ <ft-filter
626
+ part="filters"
627
+ class="ft-search-bar--content-locale"
628
+ id="content-locale"
629
+ filterPlaceHolder="${this.labelResolver.resolve("filterInputPlaceHolder", this.labelResolver.resolve("contentLocaleSelector"))}"
630
+ clearButtonLabel="${this.labelResolver.resolve("clearFilterButton")}"
631
+ raiseSelectedOptions
632
+ .options=${contentLocales}
633
+ @change=${(e) => this.contentLocale = e.detail[0]}
634
+ ></ft-filter>
635
+ </ft-accordion-item>
636
+ ` : null}
637
+ ${repeat(this.facets, facet => facet.key, facet => {
638
+ const filter = facetToFilter(facet);
639
+ return html `
640
+ <ft-accordion-item>
641
+ <div class="ft-search-bar--filter-label" slot="toggle">
642
+ <ft-typography variant="button">${facet.label}</ft-typography>
643
+ <ft-typography variant="body2">
644
+ ${selectedValues(filter).join(", ")}
645
+ </ft-typography>
646
+ </div>
647
+ <ft-filter
648
+ part="filters"
649
+ id="${filter.id}"
650
+ filterPlaceHolder="${this.labelResolver.resolve("filterInputPlaceHolder", filter.label)}"
651
+ clearButtonLabel="${this.labelResolver.resolve("clearFilterButton")}"
652
+ moreValuesButtonLabel="${this.labelResolver.resolve("displayMoreFilterValuesButton")}"
653
+ ?multivalued=${filter.multivalued}
654
+ raiseSelectedOptions
655
+ .options=${filter.options}
656
+ .displayedValuesLimit=${10}
657
+ @change=${(e) => this.setFilter(filter.id, filter.label, e.detail)}
658
+ ></ft-filter>
659
+ </ft-accordion-item>
660
+ `;
661
+ })}
662
+ </ft-accordion>
663
+ `;
664
+ }
665
+ renderSuggestions() {
666
+ const filteredRecentSearches = this.recentSearches.filter(q => q.toLowerCase().includes(this.query.toLowerCase()));
667
+ const shouldDisplaySuggestions = this.query.length > 2 || filteredRecentSearches.length > 0;
668
+ return html `
669
+ <div class="ft-search-bar--suggestions ${shouldDisplaySuggestions ? "ft-search-bar--suggestions-not-empty" : ""}"
670
+ @keydown=${this.onSuggestKeyDown}>
671
+ ${repeat(filteredRecentSearches.slice(0, 5), query => query, query => html `
672
+ <a href="${this.searchRequestSerializer({ ...this.request, query: query })}"
673
+ part="suggestions"
674
+ class="ft-search-bar--suggestion ft-search-bar--recent-search"
675
+ @keyup=${(e) => this.onSuggestKeyUp(e, query)}
676
+ @click=${(e) => this.onSuggestClick(e, query)}>
677
+ <ft-ripple></ft-ripple>
678
+ <mwc-icon part="suggestion-icon">history</mwc-icon>
679
+ <ft-typography variant="body1">${query}</ft-typography>
680
+ <ft-button icon="close"
681
+ round
682
+ part="remove-suggestion"
683
+ ?dense=${this.sizeCategory !== FtSizeCategory.S}
684
+ label="${this.labelResolver.resolve("removeRecentSearch")}"
685
+ @click=${(e) => this.removeRecentSearch(e, query)}></ft-button>
686
+ </a>
687
+ `)}
688
+ ${repeat(this.suggestions, suggest => suggest.value, suggest => html `
689
+ <a href="${this.searchRequestSerializer({ ...this.request, query: suggest.value })}"
690
+ part="suggestions"
691
+ class="ft-search-bar--suggestion"
692
+ @keyup=${(e) => this.onSuggestKeyUp(e, suggest.value)}
693
+ @click=${(e) => this.onSuggestClick(e, suggest.value)}>
694
+ <ft-ripple></ft-ripple>
695
+ ${this.getIcon(suggest)}
696
+ <ft-typography variant="body1">${suggest.value}</ft-typography>
697
+ </a>
698
+ `)}
699
+ ${filteredRecentSearches.length === 0 && this.suggestions.length === 0 && this.query.length > 2 && this.suggestionsLoaded
700
+ ? html `
701
+ <ft-typography class="ft-search-bar--no-suggestions" element="p"
702
+ variant="body2">
703
+ ${this.labelResolver.resolve("noSuggestions")}
704
+ </ft-typography>
705
+ ` : null}
706
+ </div>
707
+ `;
708
+ }
709
+ getIcon(suggest) {
710
+ const iconVariant = suggest.type === "DOCUMENT" ? FtIconVariants.file_format : FtIconVariants.fluid_topics;
711
+ let icon;
712
+ switch (suggest.type) {
713
+ case "MAP":
714
+ icon = suggest.editorialType === "BOOK" ? FtIcons.BOOK : FtIcons.ARTICLE;
715
+ break;
716
+ case "DOCUMENT":
717
+ icon = resolveFileFormatIcon(suggest.mimeType, suggest.filenameExtension);
718
+ break;
719
+ case "TOPIC":
720
+ icon = FtIcons.TOPICS;
721
+ break;
722
+ }
723
+ return html `
724
+ <ft-icon variant="${iconVariant}" part="suggestion-icon">
725
+ ${icon}
726
+ </ft-icon>
727
+ `;
728
+ }
729
+ renderDesktopFacetsActions() {
730
+ return html `
731
+ <div class="ft-search-bar--facets-actions">
732
+ ${this.hasLocaleSelector ? html `
733
+ <ft-select
734
+ class="ft-search-bar--content-locale"
735
+ part="content-locale"
736
+ label="${this.labelResolver.resolve("contentLocaleSelector")}"
737
+ outlined
738
+ @change=${(e) => this.contentLocale = e.detail}>
739
+ ${repeat(this.availableContentLocales, l => l.lang, l => html `
740
+ <ft-select-option value="${l.lang}"
741
+ label="${l.label}"
742
+ ?selected=${l.lang === this.contentLocale}>
743
+ </ft-select-option>
744
+ `)}
745
+ </ft-select>
746
+ ` : null}
747
+ ${this.searchFilters.length > 0 ? html `
748
+ <ft-button part="facets-actions"
749
+ @click=${this.clearFilters}>
750
+ ${this.labelResolver.resolve("clearFilters")}
751
+ </ft-button>
752
+ ` : null}
753
+ <slot name="facets-actions"></slot>
754
+ </div>
755
+ `;
756
+ }
757
+ renderDesktopFacets() {
758
+ if (!this.hasFacets) {
759
+ return null;
760
+ }
761
+ return html `
762
+ <ft-snap-scroll horizontal limitSize controls
763
+ class="ft-search-bar--filters-container"
764
+ part="filters-container">
765
+ ${repeat(this.facets, facet => facet.key, facet => {
766
+ const filter = facetToFilter(facet);
767
+ const hierachical = filter.options.some(o => { var _a, _b; return ((_b = (_a = o.subOptions) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0; });
768
+ return html `
769
+ <ft-filter
770
+ class="${hierachical ? "ft-search-bar--hierarchical-filter" : ""}"
771
+ part="filters"
772
+ id="${filter.id}"
773
+ label="${filter.label}"
774
+ filterPlaceHolder="${this.labelResolver.resolve("filterInputPlaceHolder", filter.label)}"
775
+ clearButtonLabel="${this.labelResolver.resolve("clearFilterButton")}"
776
+ moreValuesButtonLabel="${this.labelResolver.resolve("displayMoreFilterValuesButton")}"
777
+ ?multivalued=${filter.multivalued}
778
+ raiseSelectedOptions
779
+ .options=${filter.options}
780
+ .displayedValuesLimit=${10}
781
+ @change=${(e) => this.setFilter(filter.id, filter.label, e.detail)}
782
+ ></ft-filter>
783
+ `;
784
+ })}
785
+ </ft-snap-scroll>
786
+ `;
787
+ }
788
+ renderSelectedFacets() {
789
+ if (!this.hasLocaleSelector && this.searchFilters.length === 0) {
790
+ return null;
791
+ }
792
+ return html `
793
+ <div class="ft-search-bar--selected-filters" part="selected-filters-container">
794
+ ${this.hasLocaleSelector && (this.hasFacets || this.sizeCategory === FtSizeCategory.S) ? html `
795
+ <ft-chip part="selected-filters">${(this.getLocaleLabel(this.contentLocale))}</ft-chip>
796
+ ` : null}
797
+ ${repeat(this.searchFilters, filter => filter.key, filter => repeat(filter.values, value => {
798
+ let label = filter.label + ": " + getBreadcrumbFromValue(value);
799
+ return html `
800
+ <ft-tooltip inline text="${label}">
801
+ <ft-chip part="selected-filters"
802
+ removable
803
+ label="${label}"
804
+ @icon-click=${() => this.setFilter(filter.key, filter.label, filter.values.filter(v => v !== value))}>
805
+ ${getLabelFromValue(value)}
806
+ </ft-chip>
807
+ </ft-tooltip>
808
+ `;
809
+ }))}
810
+ </div>
811
+ `;
812
+ }
813
+ async firstUpdated(props) {
814
+ var _a, _b;
815
+ super.firstUpdated(props);
816
+ this.initApi();
817
+ this.availableContentLocales = (_b = await ((_a = this.api) === null || _a === void 0 ? void 0 : _a.getAvailableSearchLocales().then(result => result.contentLocales).catch(() => []))) !== null && _b !== void 0 ? _b : [];
818
+ }
819
+ update(props) {
820
+ var _a, _b;
821
+ if (props.has("labels")) {
822
+ this.labelResolver = new ParametrizedLabelResolver(DEFAULT_LABELS, this.labels);
823
+ }
824
+ if (props.has("sizeCategory")) {
825
+ this.mobileMenuOpen = false;
826
+ this.displayFacets = this.displayFacets && this.sizeCategory !== FtSizeCategory.S;
827
+ }
828
+ super.update(props);
829
+ if ((props.has("availableContentLocales") || props.has("contentLocale")) && this.availableContentLocales.length > 0) {
830
+ if (!this.availableContentLocales.some(l => l.lang === this.contentLocale)) {
831
+ this.contentLocale = (_a = this.availableContentLocales[0]) === null || _a === void 0 ? void 0 : _a.lang;
832
+ }
833
+ }
834
+ if (props.has("baseUrl") && this.baseUrl) {
835
+ if (this.baseUrl.endsWith("/")) {
836
+ this.baseUrl = this.baseUrl.replace(/\/$/, "");
837
+ }
838
+ this.recentSearches = JSON.parse((_b = window.localStorage.getItem(this.recentSearchesStorageKey)) !== null && _b !== void 0 ? _b : "[]");
839
+ }
840
+ if (["baseUrl", "apiIntegrationIdentifier"].some(p => props.has(p))) {
841
+ this.setApi();
842
+ }
843
+ if (["uiLocale", "contentLocale", "searchFilters", "displayedFilters", "api"].some(p => props.has(p))) {
844
+ this.updateFacets();
845
+ }
846
+ if (["query", "uiLocale", "contentLocale", "searchFilters", "displayedFilters", "api"].some(p => props.has(p))) {
847
+ this.updateSuggestions();
848
+ }
849
+ if (["query", "uiLocale", "contentLocale", "searchFilters"].some(p => props.has(p))) {
850
+ this.dispatchEvent(new SearchStateChangeEvent(this.request));
851
+ }
852
+ }
853
+ contentAvailableCallback(props) {
854
+ var _a, _b;
855
+ super.contentAvailableCallback(props);
856
+ if (props.has("displayFacets") && this.displayFacets) {
857
+ (_a = this.floatingContainer) === null || _a === void 0 ? void 0 : _a.focus();
858
+ }
859
+ if (this.scrollToFacet != null && this.facetsLoaded) {
860
+ (_b = this.scrollingFiltersContainer) === null || _b === void 0 ? void 0 : _b.scrollIndexIntoView(this.facets.findIndex(f => f.key === this.scrollToFacet));
861
+ this.scrollToFacet = undefined;
862
+ }
863
+ }
864
+ initApi() {
865
+ if (this.api == null) {
866
+ this.setApi();
867
+ setTimeout(() => this.initApi(), 100);
868
+ }
869
+ }
870
+ setApi() {
871
+ this.api = window.fluidtopics ? new window.fluidtopics.FluidTopicsApi(this.baseUrl, this.apiIntegrationIdentifier) : undefined;
872
+ }
873
+ updateFacets() {
874
+ if (this.displayedFilters.length > 0) {
875
+ this.facetsLoaded = false;
876
+ this.updateFacetsDebouncer.run(async () => {
877
+ var _a, _b;
878
+ this.facets = (_b = await ((_a = this.api) === null || _a === void 0 ? void 0 : _a.search({ ...this.request, query: "" }).then(r => r.facets).catch(() => []))) !== null && _b !== void 0 ? _b : [];
879
+ this.facetsLoaded = true;
880
+ });
881
+ }
882
+ else {
883
+ this.facets = [];
884
+ }
885
+ }
886
+ updateSuggestions() {
887
+ this.suggestionsLoaded = false;
888
+ this.suggestDebouncer.run(async () => {
889
+ this.suggestions = this.api && this.query.length > 2 ? await this.api.getSuggestions(this.suggestRequest).then(r => r.suggestions).catch(() => []) : [];
890
+ this.suggestionsLoaded = true;
891
+ });
892
+ }
893
+ onSearchBarKeyUp(e) {
894
+ const input = e.composedPath()[0];
895
+ this.query = input.value;
896
+ if (e.key === "Enter") {
897
+ this.launchSearch();
898
+ }
899
+ }
900
+ onSearchBarKeyDown(e) {
901
+ var _a, _b;
902
+ switch (e.key) {
903
+ case "Escape":
904
+ this.mobileMenuOpen = false;
905
+ (_a = this.input) === null || _a === void 0 ? void 0 : _a.blur();
906
+ break;
907
+ case "ArrowDown":
908
+ e.stopPropagation();
909
+ e.preventDefault();
910
+ (_b = this.firstSuggestion) === null || _b === void 0 ? void 0 : _b.focus();
911
+ break;
912
+ }
913
+ }
914
+ onFloatingContainerKeyUp(e) {
915
+ var _a;
916
+ if (e.key === "Escape") {
917
+ this.displayFacets = false;
918
+ (_a = this.filtersOpener) === null || _a === void 0 ? void 0 : _a.focus();
919
+ }
920
+ }
921
+ setQuery(query) {
922
+ if (this.input) {
923
+ this.input.value = query;
924
+ }
925
+ this.query = query;
926
+ }
927
+ onSuggestClick(e, suggest) {
928
+ if (!e.ctrlKey && !e.metaKey) {
929
+ this.onSuggestSelected(e, suggest);
930
+ }
931
+ }
932
+ onSuggestKeyUp(e, suggest) {
933
+ if (e.key === "Enter" || e.key === " ") {
934
+ this.onSuggestSelected(e, suggest);
935
+ }
936
+ }
937
+ onSuggestSelected(e, suggest) {
938
+ e.preventDefault();
939
+ this.setQuery(suggest);
940
+ this.launchSearch();
941
+ }
942
+ launchSearch() {
943
+ if (this.query) {
944
+ let filteredRecentSearches = this.recentSearches
945
+ .filter(q => q.toLowerCase() !== this.query.toLowerCase())
946
+ .filter((q, index) => index < 20);
947
+ this.recentSearches = [this.query, ...filteredRecentSearches];
948
+ this.saveRecentSearches();
949
+ }
950
+ this.focus();
951
+ this.dispatchEvent(new LaunchSearchEvent(this.request));
952
+ }
953
+ saveRecentSearches() {
954
+ window.localStorage.setItem(this.recentSearchesStorageKey, JSON.stringify(this.recentSearches));
955
+ }
956
+ connectedCallback() {
957
+ super.connectedCallback();
958
+ document.addEventListener("focusin", this.closeFloatingContainer);
959
+ document.addEventListener("click", this.closeFloatingContainer);
960
+ }
961
+ disconnectedCallback() {
962
+ super.disconnectedCallback();
963
+ document.removeEventListener("focusin", this.closeFloatingContainer);
964
+ document.addEventListener("click", this.closeFloatingContainer);
965
+ }
966
+ updateSize(e) {
967
+ this.sizeCategory = e.detail.category;
968
+ }
969
+ getLocaleLabel(locale) {
970
+ var _a;
971
+ return (_a = this.availableContentLocales.filter(l => { var _a; return ((_a = l.lang) !== null && _a !== void 0 ? _a : "").toLowerCase() === (locale !== null && locale !== void 0 ? locale : "").toLowerCase(); })
972
+ .map(l => l.label)
973
+ .pop()) !== null && _a !== void 0 ? _a : locale;
974
+ }
975
+ setFilter(key, label, selectedValues) {
976
+ let newFilters = this.searchFilters.filter(f => f.key !== key);
977
+ this.facets.forEach(facet => {
978
+ if (facet.key === key) {
979
+ flatDeep(facet.rootNodes, n => n.childNodes).forEach(n => n.selected = selectedValues.includes(n.value));
980
+ }
981
+ });
982
+ if (selectedValues.length) {
983
+ newFilters.push({
984
+ key: key,
985
+ label: label,
986
+ negative: false,
987
+ values: selectedValues
988
+ });
989
+ }
990
+ this.searchFilters = newFilters;
991
+ this.scrollToFacet = key;
992
+ }
993
+ clearFilters() {
994
+ this.facets.forEach(facet => flatDeep(facet.rootNodes, n => n.childNodes).forEach(n => n.selected = false));
995
+ this.searchFilters = [];
996
+ const firstFacet = this.facets[0];
997
+ this.scrollToFacet = firstFacet === null || firstFacet === void 0 ? void 0 : firstFacet.key;
998
+ }
999
+ removeRecentSearch(e, query) {
1000
+ var _a, _b, _c, _d;
1001
+ e.preventDefault();
1002
+ e.stopPropagation();
1003
+ const thingToFocus = (_d = (_b = (_a = this.focusedSuggestion) === null || _a === void 0 ? void 0 : _a.previousElementSibling) !== null && _b !== void 0 ? _b : (_c = this.focusedSuggestion) === null || _c === void 0 ? void 0 : _c.nextElementSibling) !== null && _d !== void 0 ? _d : this.input;
1004
+ thingToFocus === null || thingToFocus === void 0 ? void 0 : thingToFocus.focus();
1005
+ this.recentSearches = this.recentSearches.filter(q => q.toLowerCase() !== query.toLowerCase());
1006
+ this.saveRecentSearches();
1007
+ }
1008
+ onSuggestKeyDown(e) {
1009
+ var _a, _b, _c, _d, _e, _f;
1010
+ switch (e.key) {
1011
+ case "ArrowUp":
1012
+ (_c = ((_b = (_a = this.focusedSuggestion) === null || _a === void 0 ? void 0 : _a.previousElementSibling) !== null && _b !== void 0 ? _b : this.lastSuggestion)) === null || _c === void 0 ? void 0 : _c.focus();
1013
+ e.preventDefault();
1014
+ e.stopPropagation();
1015
+ break;
1016
+ case "ArrowDown":
1017
+ (_f = ((_e = (_d = this.focusedSuggestion) === null || _d === void 0 ? void 0 : _d.nextElementSibling) !== null && _e !== void 0 ? _e : this.firstSuggestion)) === null || _f === void 0 ? void 0 : _f.focus();
1018
+ e.preventDefault();
1019
+ e.stopPropagation();
1020
+ break;
1021
+ }
1022
+ }
1023
+ };
1024
+ FtSearchBar.elementDefinitions = {
1025
+ "ft-accordion": FtAccordion,
1026
+ "ft-accordion-item": FtAccordionItem,
1027
+ "ft-button": FtButton,
1028
+ "ft-chip": FtChip,
1029
+ "ft-filter": FtFilter,
1030
+ "ft-filter-option": FtFilterOption,
1031
+ "ft-icon": FtIcon,
1032
+ "ft-ripple": FtRipple,
1033
+ "ft-select": FtSelect,
1034
+ "ft-select-option": FtSelectOption,
1035
+ "ft-size-watcher": FtSizeWatcher,
1036
+ "ft-snap-scroll": FtSnapScroll,
1037
+ "ft-tooltip": FtTooltip,
1038
+ "ft-typography": FtTypography,
1039
+ "mwc-icon": Icon,
1040
+ };
1041
+ __decorate([
1042
+ property({ type: String })
1043
+ ], FtSearchBar.prototype, "baseUrl", void 0);
1044
+ __decorate([
1045
+ property({ type: String })
1046
+ ], FtSearchBar.prototype, "apiIntegrationIdentifier", void 0);
1047
+ __decorate([
1048
+ property({ type: String })
1049
+ ], FtSearchBar.prototype, "contentLocale", void 0);
1050
+ __decorate([
1051
+ state()
1052
+ ], FtSearchBar.prototype, "availableContentLocales", void 0);
1053
+ __decorate([
1054
+ property({ type: String })
1055
+ ], FtSearchBar.prototype, "uiLocale", void 0);
1056
+ __decorate([
1057
+ jsonProperty({})
1058
+ ], FtSearchBar.prototype, "labels", void 0);
1059
+ __decorate([
1060
+ jsonProperty([])
1061
+ ], FtSearchBar.prototype, "displayedFilters", void 0);
1062
+ __decorate([
1063
+ property()
1064
+ ], FtSearchBar.prototype, "searchRequestSerializer", void 0);
1065
+ __decorate([
1066
+ state()
1067
+ ], FtSearchBar.prototype, "searchFilters", void 0);
1068
+ __decorate([
1069
+ state()
1070
+ ], FtSearchBar.prototype, "sizeCategory", void 0);
1071
+ __decorate([
1072
+ state()
1073
+ ], FtSearchBar.prototype, "displayFacets", void 0);
1074
+ __decorate([
1075
+ state()
1076
+ ], FtSearchBar.prototype, "mobileMenuOpen", void 0);
1077
+ __decorate([
1078
+ state()
1079
+ ], FtSearchBar.prototype, "facets", void 0);
1080
+ __decorate([
1081
+ query(".ft-search-bar--container")
1082
+ ], FtSearchBar.prototype, "container", void 0);
1083
+ __decorate([
1084
+ query(".ft-search-bar--filters-opener")
1085
+ ], FtSearchBar.prototype, "filtersOpener", void 0);
1086
+ __decorate([
1087
+ query(".ft-search-bar--floating-panel")
1088
+ ], FtSearchBar.prototype, "floatingContainer", void 0);
1089
+ __decorate([
1090
+ query("ft-snap-scroll.ft-search-bar--filters-container")
1091
+ ], FtSearchBar.prototype, "scrollingFiltersContainer", void 0);
1092
+ __decorate([
1093
+ query(".ft-search-bar--input")
1094
+ ], FtSearchBar.prototype, "input", void 0);
1095
+ __decorate([
1096
+ state()
1097
+ ], FtSearchBar.prototype, "query", void 0);
1098
+ __decorate([
1099
+ state()
1100
+ ], FtSearchBar.prototype, "suggestions", void 0);
1101
+ __decorate([
1102
+ state()
1103
+ ], FtSearchBar.prototype, "suggestionsLoaded", void 0);
1104
+ __decorate([
1105
+ state()
1106
+ ], FtSearchBar.prototype, "recentSearches", void 0);
1107
+ __decorate([
1108
+ state()
1109
+ ], FtSearchBar.prototype, "scrollToFacet", void 0);
1110
+ __decorate([
1111
+ query(".ft-search-bar--suggestion:first-child")
1112
+ ], FtSearchBar.prototype, "firstSuggestion", void 0);
1113
+ __decorate([
1114
+ query(".ft-search-bar--suggestion:focus-within")
1115
+ ], FtSearchBar.prototype, "focusedSuggestion", void 0);
1116
+ __decorate([
1117
+ query(".ft-search-bar--suggestion:last-child")
1118
+ ], FtSearchBar.prototype, "lastSuggestion", void 0);
1119
+ __decorate([
1120
+ state()
1121
+ ], FtSearchBar.prototype, "api", void 0);
1122
+ FtSearchBar = __decorate([
1123
+ customElement("ft-search-bar")
1124
+ ], FtSearchBar);
1125
+ export { FtSearchBar };
1126
+ //# sourceMappingURL=ft-search-bar.js.map