@fluid-topics/ft-search-bar 0.1.3 → 0.1.7

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.
@@ -4,33 +4,31 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
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
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { css, html, nothing } from "lit";
7
+ import { html, nothing } from "lit";
8
8
  import { property, query, state } from "lit/decorators.js";
9
9
  import { repeat } from "lit/directives/repeat.js";
10
10
  import { classMap } from "lit/directives/class-map.js";
11
- import { customElement, Debouncer, designSystemVariables, FtCssVariable, FtLitElement, jsonProperty, ParametrizedLabelResolver, setVariable } from "@fluid-topics/ft-wc-utils";
11
+ import { customElement, Debouncer, FtLitElement, jsonProperty, ParametrizedLabelResolver } from "@fluid-topics/ft-wc-utils";
12
12
  import { FtSizeCategory, FtSizeWatcher } from "@fluid-topics/ft-size-watcher";
13
13
  import { FtTypography, FtTypographyBody2 } from "@fluid-topics/ft-typography";
14
14
  import { facetToFilter, getBreadcrumbFromValue, getLabelFromValue, selectedValues, serializeRequest } from "./converters";
15
15
  import { FtFilter, FtFilterOption } from "@fluid-topics/ft-filter";
16
16
  import { FtIcon, FtIcons, FtIconVariants, resolveFileFormatIcon, } from "@fluid-topics/ft-icon";
17
17
  import { FtAccordion, FtAccordionItem } from "@fluid-topics/ft-accordion";
18
- import { FtButton, FtButtonCssVariables } from "@fluid-topics/ft-button";
19
- import { FtChip, FtChipCssVariables } from "@fluid-topics/ft-chip";
20
- import { FtSelect, FtSelectCssVariables, FtSelectOption } from "@fluid-topics/ft-select";
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
21
  import { FtSnapScroll } from "@fluid-topics/ft-snap-scroll";
22
22
  import { FtTooltip } from "@fluid-topics/ft-tooltip";
23
23
  import { Icon } from "@material/mwc-icon";
24
- import { FtRipple, FtRippleCssVariables } from "@fluid-topics/ft-ripple";
24
+ import { FtRipple } from "@fluid-topics/ft-ripple";
25
25
  import { flatDeep } from "@fluid-topics/ft-filter/build/utils";
26
- import { FtInputLabelCssVariables } from "@fluid-topics/ft-input-label";
26
+ import { facetsCss, searchBarCss, selectedFiltersCss, suggestionsCss } from "./ft-search-bar.css";
27
27
  if (window.fluidtopics == null) {
28
28
  console.warn("Fluid Topics public API was not found. You can find it here: https://www.npmjs.com/package/@fluid-topics/public-api");
29
29
  }
30
30
  export const DEFAULT_LABELS = {
31
31
  filtersButton: "Filters",
32
- oneFilterEnabled: "1 filter enabled",
33
- nFiltersEnabled: "{0} filter(s) enabled",
34
32
  inputPlaceHolder: "Search",
35
33
  filterInputPlaceHolder: "Filter {0}",
36
34
  clearInputButton: "Clear",
@@ -40,27 +38,11 @@ export const DEFAULT_LABELS = {
40
38
  noSuggestions: "No results found…",
41
39
  clearFilters: "Clear filters",
42
40
  contentLocaleSelector: "Lang",
41
+ presetsSelector: "Preset",
43
42
  removeRecentSearch: "Remove",
44
43
  back: "Back",
45
44
  };
46
- export const FtSearchBarCssVariables = {
47
- height: FtCssVariable.create("--ft-search-bar-height", "SIZE", "38px"),
48
- borderRadius: FtCssVariable.extend("--ft-search-bar-border-radius", designSystemVariables.borderRadiusS),
49
- mobileOpenPosition: FtCssVariable.create("--ft-search-bar-mobile-open-position", "POSITION", "fixed"),
50
- mobileOpenTop: FtCssVariable.create("--ft-search-bar-mobile-open-top", "SIZE", "0"),
51
- mobileOpenBottom: FtCssVariable.create("--ft-search-bar-mobile-open-bottom", "SIZE", "0"),
52
- mobileOpenLeft: FtCssVariable.create("--ft-search-bar-mobile-open-left", "SIZE", "0"),
53
- mobileOpenRight: FtCssVariable.create("--ft-search-bar-mobile-open-right", "SIZE", "0"),
54
- floatingZIndex: FtCssVariable.create("--ft-search-bar-floating-components-z-index", "NUMBER", "2"),
55
- colorSurface: FtCssVariable.external(designSystemVariables.colorSurface, "Design system"),
56
- colorOnSurface: FtCssVariable.external(designSystemVariables.colorOnSurface, "Design system"),
57
- colorOnSurfaceMedium: FtCssVariable.external(designSystemVariables.colorOnSurfaceMedium, "Design system"),
58
- colorOutline: FtCssVariable.external(designSystemVariables.colorOutline, "Design system"),
59
- colorPrimary: FtCssVariable.external(designSystemVariables.colorPrimary, "Design system"),
60
- elevation02: FtCssVariable.external(designSystemVariables.elevation02, "Design system"),
61
- buttonColor: FtCssVariable.external(FtButtonCssVariables.color, "Button"),
62
- buttonRippleColor: FtCssVariable.external(FtButtonCssVariables.rippleColor, "Button"),
63
- };
45
+ export { FtSearchBarCssVariables } from "./ft-search-bar.css";
64
46
  export class LaunchSearchEvent extends CustomEvent {
65
47
  constructor(request) {
66
48
  super("launch-search", { detail: request });
@@ -74,18 +56,21 @@ export class SearchStateChangeEvent extends CustomEvent {
74
56
  let FtSearchBar = class FtSearchBar extends FtLitElement {
75
57
  constructor() {
76
58
  super(...arguments);
59
+ this.dense = false;
77
60
  this.baseUrl = "";
78
61
  this.apiIntegrationIdentifier = "ft-search-bar";
79
62
  this.availableContentLocales = [];
80
63
  this.labels = {};
81
64
  this.labelResolver = new ParametrizedLabelResolver(DEFAULT_LABELS, {});
82
65
  this.displayedFilters = [];
66
+ this.presets = [];
83
67
  this.searchRequestSerializer = (request) => serializeRequest(this.baseUrl, request);
84
68
  this.searchFilters = [];
85
69
  this.sizeCategory = FtSizeCategory.S;
86
70
  this.displayFacets = false;
87
71
  this.mobileMenuOpen = false;
88
72
  this.facets = [];
73
+ this.knownFacetLabels = {};
89
74
  this.query = "";
90
75
  this.suggestions = [];
91
76
  this.suggestionsLoaded = true;
@@ -94,316 +79,25 @@ let FtSearchBar = class FtSearchBar extends FtLitElement {
94
79
  this.suggestDebouncer = new Debouncer(300);
95
80
  this.facetsLoaded = false;
96
81
  this.closeFloatingContainer = (e) => {
97
- if (this.sizeCategory !== FtSizeCategory.S) {
82
+ if (!this.isMobile) {
98
83
  this.displayFacets = this.displayFacets && e.composedPath().some(element => element === this.floatingContainer);
99
84
  }
100
85
  };
86
+ this.compareFilters = (a, b) => a.key === b.key
87
+ && a.negative == b.negative
88
+ && a.values.length === b.values.length
89
+ && a.values.every(value => b.values.includes(value));
90
+ this.compareRequests = (a, b) => (a.contentLocale == null || b.contentLocale == null || a.contentLocale === b.contentLocale)
91
+ && a.filters.length === b.filters.length
92
+ && a.filters.every(fa => b.filters.some(fb => this.compareFilters(fa, fb)));
101
93
  }
102
- // language=CSS
103
94
  getStyles() {
104
95
  return [
105
96
  FtTypographyBody2,
106
- css `
107
- * {
108
- box-sizing: border-box;
109
- }
110
-
111
- .ft-search-bar--container {
112
- display: flex;
113
- flex-direction: column;
114
- gap: 8px;
115
- background: ${FtSearchBarCssVariables.colorSurface};
116
- outline: none;
117
-
118
- --ft-search-bar-border-radius--internal: ${FtSearchBarCssVariables.borderRadius};
119
- }
120
-
121
- .ft-search-bar--mobile-menu-open {
122
- position: ${FtSearchBarCssVariables.mobileOpenPosition};
123
- top: ${FtSearchBarCssVariables.mobileOpenTop};
124
- bottom: ${FtSearchBarCssVariables.mobileOpenBottom};
125
- left: ${FtSearchBarCssVariables.mobileOpenLeft};
126
- right: ${FtSearchBarCssVariables.mobileOpenRight};
127
- z-index: ${FtSearchBarCssVariables.floatingZIndex};
128
- padding: 16px;
129
- }
130
-
131
- .ft-search-bar {
132
- flex-shrink: 0;
133
- position: relative;
134
- display: flex;
135
- flex-direction: row;
136
- align-items: center;
137
- height: ${FtSearchBarCssVariables.height};
138
-
139
- background: ${FtSearchBarCssVariables.colorSurface};
140
- border: 1px solid ${FtSearchBarCssVariables.colorOutline};
141
- border-radius: var(--ft-search-bar-border-radius--internal);
142
- }
143
-
144
- .ft-search-bar--floating-panel-open .ft-search-bar {
145
- border-radius: var(--ft-search-bar-border-radius--internal) var(--ft-search-bar-border-radius--internal) 0 0;
146
- }
147
-
148
- .ft-search-bar--input-container {
149
- flex-grow: 1;
150
- flex-shrink: 1;
151
- align-self: stretch;
152
- position: relative;
153
- }
154
-
155
- .ft-search-bar--input {
156
- border: none;
157
- background-color: transparent;
158
- padding: 0 8px;
159
- height: 100%;
160
- width: 100%;
161
- }
162
-
163
- .ft-search-bar--input:focus-within {
164
- outline-color: ${FtSearchBarCssVariables.colorPrimary};
165
- }
166
-
167
- .ft-search-bar--mobile .ft-search-bar--suggestions {
168
- flex-grow: 1;
169
- flex-shrink: 1;
170
- overflow-y: auto;
171
- height: 0;
172
- }
173
-
174
- .ft-search-bar--mobile-open .ft-search-bar--suggestions {
175
- height: initial;
176
- }
177
-
178
- .ft-search-bar--floating-panel,
179
- .ft-search-bar--desktop .ft-search-bar--suggestions {
180
- position: absolute;
181
- z-index: var(--ft-search-bar-floating-components-z-index, 1);
182
- top: 100%;
183
- left: -1px;
184
- right: -1px;
185
- display: none;
186
- background: ${FtSearchBarCssVariables.colorSurface};
187
- border: 1px solid ${FtSearchBarCssVariables.colorOutline};
188
- border-radius: 0 0 var(--ft-search-bar-border-radius--internal) var(--ft-search-bar-border-radius--internal);
189
- box-shadow: ${FtSearchBarCssVariables.elevation02};
190
- outline: none;
191
- }
192
-
193
- .ft-search-bar--desktop .ft-search-bar--suggestions {
194
- top: calc(100% + 1px);
195
- }
196
-
197
- .ft-search-bar--input-container:focus-within .ft-search-bar--suggestions-not-empty {
198
- display: block;
199
- }
200
-
201
- .ft-search-bar--no-suggestions {
202
- text-align: center;
203
- padding: 8px;
204
- color: ${FtSearchBarCssVariables.colorOnSurface};
205
- }
206
-
207
- .ft-search-bar--suggestion {
208
- text-decoration: none;
209
- position: relative;
210
- display: flex;
211
- align-items: center;
212
- padding: 8px;
213
- gap: 8px;
214
- cursor: pointer;
215
- color: ${FtSearchBarCssVariables.colorOnSurface};
216
- min-height: 52px;
217
- }
218
-
219
- .ft-search-bar--desktop .ft-search-bar--suggestion {
220
- min-height: 44px;
221
- }
222
-
223
- .ft-search-bar--suggestion:focus {
224
- outline: none;
225
- }
226
-
227
- .ft-search-bar--mobile .ft-search-bar--suggestion:first-child,
228
- .ft-search-bar--recent-search + .ft-search-bar--suggestion:not(.ft-search-bar--recent-search) {
229
- border-top: 1px solid ${FtSearchBarCssVariables.colorOutline};
230
- }
231
-
232
- .ft-search-bar--suggestion ft-typography {
233
- display: block;
234
- flex-grow: 1;
235
- flex-shrink: 1;
236
- }
237
-
238
- .ft-search-bar > ft-button {
239
- flex-shrink: 0;
240
- }
241
-
242
- .ft-search-bar--left-action {
243
- ${setVariable(FtButtonCssVariables.borderRadius, "calc(var(--ft-search-bar-border-radius--internal) - 1px) 0 0 calc(var(--ft-search-bar-border-radius--internal) - 1px)")};
244
- border-right: 1px solid ${FtSearchBarCssVariables.colorOutline};
245
- }
246
-
247
- .ft-search-bar--floating-panel-open .ft-search-bar--left-action {
248
- ${setVariable(FtButtonCssVariables.borderRadius, "calc(var(--ft-search-bar-border-radius--internal) - 1px) 0 0 0")};
249
- }
250
-
251
- .ft-search-bar--launch-search,
252
- .ft-search-bar--clear-query {
253
- margin: 0 4px;
254
- }
255
-
256
- .ft-search-bar--separator {
257
- height: 20px;
258
- border-right: 1px solid ${FtSearchBarCssVariables.colorOutline};
259
- }
260
-
261
- .ft-search-bar--floating-panel {
262
- padding: 16px;
263
- }
264
-
265
- .ft-search-bar--floating-panel-open .ft-search-bar--floating-panel {
266
- display: block;
267
- }
268
-
269
- .ft-search-bar--desktop .ft-search-bar--facets-actions {
270
- display: flex;
271
- align-items: center;
272
- justify-content: flex-end;
273
- gap: 8px;
274
- padding: 0 10px;
275
- margin-bottom: 16px;
276
- }
277
-
278
- .ft-search-bar--mobile .ft-search-bar--facets-actions {
279
- flex-shrink: 0;
280
- flex-grow: 0;
281
- display: flex;
282
- gap: 16px;
283
- justify-content: space-evenly;
284
- }
285
-
286
- .ft-search-bar--mobile .ft-search-bar--facets-actions > * {
287
- flex-grow: 1;
288
- flex-basis: 0;
289
- }
290
-
291
- .ft-search-bar > .ft-search-bar--content-locale,
292
- .ft-search-bar > .ft-search-bar--content-locale::part(container),
293
- .ft-search-bar > .ft-search-bar--content-locale::part(main-panel) {
294
- height: 100%;
295
- }
296
-
297
- .ft-search-bar > .ft-search-bar--content-locale::part(options) {
298
- top: calc(100% + 1px);
299
- right: unset;
300
- width: max-content;
301
- min-width: 100%;
302
- }
303
-
304
- .ft-search-bar > .ft-search-bar--content-locale::part(selected-value) {
305
- ${setVariable(FtChipCssVariables.color, FtSearchBarCssVariables.buttonColor)};
306
- ${setVariable(FtChipCssVariables.rippleColor, FtSearchBarCssVariables.buttonRippleColor)};
307
- border-radius: calc(var(--ft-search-bar-border-radius--internal) - 1px) 0 0 calc(var(--ft-search-bar-border-radius--internal) - 1px);
308
- }
309
-
310
- .ft-search-bar > .ft-search-bar--content-locale::part(label) {
311
- ${setVariable(FtInputLabelCssVariables.borderColor, "transparent")};
312
- ${setVariable(FtRippleCssVariables.color, FtSearchBarCssVariables.buttonRippleColor)}
313
- }
314
-
315
- .ft-search-bar--floating-panel .ft-search-bar--content-locale {
316
- margin-right: auto;
317
- min-width: 250px;
318
- ${setVariable(FtSelectCssVariables.optionsZIndex, "2")};
319
- }
320
-
321
- .ft-search-bar--mobile .ft-search-bar--content-locale::part(clear-button) {
322
- display: none;
323
- }
324
-
325
- .ft-search-bar--floating-panel .ft-search-bar--filters-container {
326
- display: block;
327
- height: 400px;
328
- --ft-snap-scroll-gap: 16px;
329
- }
330
-
331
- .ft-search-bar--floating-panel ft-filter {
332
- display: flex;
333
- flex-grow: 0;
334
- max-height: 100%;
335
- max-width: 250px;
336
- }
337
-
338
- .ft-search-bar--hierarchical-filter {
339
- width: 250px;
340
- }
341
-
342
- .ft-search-bar--mobile .ft-search-bar--filters-container {
343
- flex-grow: 1;
344
- flex-shrink: 1;
345
- overflow-y: auto;
346
- margin: 0 -16px;
347
- padding: 0 16px;
348
- }
349
-
350
- .ft-search-bar--mobile .ft-search-bar--filters-container ft-filter {
351
- display: flex;
352
- max-height: 60vh;
353
- }
354
-
355
- .ft-search-bar--mobile ft-filter::part(container) {
356
- flex-grow: 1;
357
- }
358
-
359
- .ft-search-bar--filter-label {
360
- display: flex;
361
- justify-content: space-between;
362
- align-items: baseline;
363
- gap: 8px;
364
- }
365
-
366
- .ft-search-bar--filter-label > * {
367
- white-space: nowrap;
368
- overflow: hidden;
369
- text-overflow: ellipsis;
370
- }
371
-
372
- .ft-search-bar--filter-label > :first-child {
373
- flex-shrink: 0;
374
- }
375
-
376
- .ft-search-bar--filter-label > :last-child {
377
- flex-shrink: 1;
378
- color: ${FtSearchBarCssVariables.colorOnSurfaceMedium};
379
- }
380
-
381
- ft-accordion-item::part(toggle) {
382
- margin-left: -16px;
383
- margin-right: -16px;
384
- }
385
-
386
- ft-accordion-item::part(label) {
387
- overflow: hidden;
388
- }
389
-
390
- ft-accordion-item::part(content) {
391
- padding-left: 0;
392
- padding-right: 0;
393
- }
394
-
395
- .ft-search-bar--selected-filters {
396
- flex-shrink: 0;
397
- display: flex;
398
- flex-direction: row;
399
- flex-wrap: wrap;
400
- gap: 8px;
401
- }
402
-
403
- .ft-search-bar--selected-filters * {
404
- max-width: 100%;
405
- }
406
- `
97
+ searchBarCss,
98
+ facetsCss,
99
+ selectedFiltersCss,
100
+ suggestionsCss
407
101
  ];
408
102
  }
409
103
  get recentSearchesStorageKey() {
@@ -414,12 +108,16 @@ let FtSearchBar = class FtSearchBar extends FtLitElement {
414
108
  uiLocale: this.uiLocale,
415
109
  contentLocale: this.contentLocale,
416
110
  query: this.query,
417
- facets: this.displayedFilters.map(id => ({ id })),
111
+ facets: this.facetsRequest,
418
112
  filters: this.searchFilters,
419
113
  paging: { perPage: 0, page: 1 },
420
114
  sort: [],
421
115
  };
422
116
  }
117
+ get facetsRequest() {
118
+ const fromFilters = this.searchFilters.filter(f => !this.displayedFilters.includes(f.key)).map(f => ({ id: f.key }));
119
+ return [...this.displayedFilters.map(id => ({ id })), ...fromFilters];
120
+ }
423
121
  get suggestRequest() {
424
122
  return {
425
123
  contentLocale: this.contentLocale,
@@ -428,8 +126,14 @@ let FtSearchBar = class FtSearchBar extends FtLitElement {
428
126
  sort: [],
429
127
  };
430
128
  }
129
+ get isMobile() {
130
+ return this.sizeCategory === FtSizeCategory.S;
131
+ }
431
132
  get hasFacets() {
432
- return this.facets.length > 0;
133
+ return this.facetsRequest.length > 0;
134
+ }
135
+ get hasPresets() {
136
+ return this.presets.length > 0;
433
137
  }
434
138
  get hasLocaleSelector() {
435
139
  return this.availableContentLocales.length > 1;
@@ -450,113 +154,39 @@ let FtSearchBar = class FtSearchBar extends FtLitElement {
450
154
  getTemplate() {
451
155
  const rootClasses = {
452
156
  "ft-search-bar--container": true,
453
- "ft-search-bar--mobile": this.sizeCategory === FtSizeCategory.S,
454
- "ft-search-bar--desktop": this.sizeCategory !== FtSizeCategory.S,
455
- "ft-search-bar--floating-panel-open": this.sizeCategory !== FtSizeCategory.S && this.displayFacets,
157
+ "ft-search-bar--dense": !this.isMobile && this.dense,
158
+ "ft-search-bar--mobile": this.isMobile,
159
+ "ft-search-bar--desktop": !this.isMobile,
160
+ "ft-search-bar--floating-panel-open": !this.isMobile && this.displayFacets,
456
161
  "ft-search-bar--mobile-menu-open": this.mobileMenuOpen,
457
162
  };
458
163
  return html `
459
164
  <ft-size-watcher @change=${this.updateSize}></ft-size-watcher>
460
165
  <div class="${classMap(rootClasses)}" part="container" tabindex="-1">
461
- ${this.sizeCategory === FtSizeCategory.S ? this.renderMobileSearchBar() : this.renderDesktopSearchBar()}
166
+ ${this.isMobile ? this.renderMobileSearchBar() : this.renderDesktopSearchBar()}
462
167
  </div>
463
168
  `;
464
169
  }
465
- renderDesktopSearchBar() {
466
- return html `
467
- <div class="ft-search-bar" part="search-bar">
468
- ${(this.renderSearchBarLeftAction())}
469
- <div class="ft-search-bar--input-container" part="input-container">
470
- <input class="ft-search-bar--input ft-typography--body2"
471
- part="input"
472
- type="text"
473
- placeholder="${this.labelResolver.resolve("inputPlaceHolder")}"
474
- value="${this.query}"
475
- @keydown=${this.onSearchBarKeyDown}
476
- @keyup=${this.onSearchBarKeyUp}>
477
- ${this.renderSuggestions()}
478
- </div>
479
- ${this.renderDesktopSearchBarButtons()}
480
- <div class="ft-search-bar--floating-panel" @keyup=${this.onFloatingContainerKeyUp} tabindex="-1">
481
- ${this.renderDesktopFacetsActions()}
482
- ${this.renderDesktopFacets()}
483
- </div>
484
- </div>
485
- ${this.renderSelectedFacets()}
486
- `;
487
- }
488
- renderSearchBarLeftAction() {
489
- if (this.hasFacets) {
490
- return html `
491
- <ft-button class="ft-search-bar--filters-opener ft-search-bar--left-action"
492
- part="filters-opener"
493
- trailingIcon
494
- icon="${this.displayFacets ? "expand_less" : "expand_more"}"
495
- @click=${(e) => {
496
- e.stopPropagation();
497
- this.displayFacets = !this.displayFacets;
498
- }}
499
- @focusin=${(e) => e.stopPropagation()}>
500
- ${this.labelResolver.resolve("filtersButton")}
501
- </ft-button>
502
- `;
503
- }
504
- if (this.hasLocaleSelector) {
505
- return html `
506
- <ft-select
507
- class="ft-search-bar--content-locale ft-search-bar--left-action"
508
- part="content-locale"
509
- @change=${(e) => this.contentLocale = e.detail}>
510
- ${repeat(this.availableContentLocales, l => l.lang, l => html `
511
- <ft-select-option value="${l.lang}"
512
- label="${l.label}"
513
- ?selected=${l.lang === this.contentLocale}>
514
- </ft-select-option>
515
- `)}
516
- </ft-select>
517
- `;
518
- }
519
- return nothing;
520
- }
521
- renderDesktopSearchBarButtons() {
522
- return html `
523
- ${this.query ? html `
524
- <ft-button class="ft-search-bar--clear-query"
525
- part="search-bar-actions"
526
- icon="close"
527
- round dense
528
- label="${this.labelResolver.resolve("clearInputButton")}"
529
- @click=${() => this.setQuery("")}
530
- ></ft-button>
531
- <div class="ft-search-bar--separator"></div>
532
- ` : null}
533
- <ft-button class="ft-search-bar--launch-search"
534
- part="search-bar-actions"
535
- icon="search"
536
- round dense
537
- label="${this.labelResolver.resolve("searchButton")}"
538
- @click=${this.launchSearch}
539
- ></ft-button>
540
- `;
541
- }
542
170
  renderMobileSearchBar() {
543
171
  return html `
544
172
  <div class="ft-search-bar">
545
173
  <div class="ft-search-bar--input-container" part="input-container">
546
- <input class="ft-search-bar--input ft-typography--body2"
547
- part="input"
548
- type="text"
549
- placeholder="${this.labelResolver.resolve("inputPlaceHolder")}"
550
- value="${this.query}"
551
- @keyup=${this.onSearchBarKeyUp}
552
- @focus=${() => {
174
+ <div class="ft-search-bar--input-outline" part="input-outline">
175
+ <input class="ft-search-bar--input ft-typography--body2"
176
+ part="input"
177
+ type="text"
178
+ placeholder="${this.labelResolver.resolve("inputPlaceHolder")}"
179
+ value="${this.query}"
180
+ @keyup=${this.onSearchBarKeyUp}
181
+ @focus=${() => {
553
182
  this.mobileMenuOpen = true;
554
183
  this.displayFacets = false;
555
184
  }}>
185
+ </div>
556
186
  </div>
557
187
  ${this.renderMobileSearchBarButtons()}
558
188
  </div>
559
- ${this.mobileMenuOpen ? this.renderMobileFacetsActions() : this.renderSelectedFacets()}
189
+ ${this.displayFacets ? this.renderFacetsActions() : this.renderSelectedFacets()}
560
190
  ${this.displayFacets ? this.renderMobileFacets() : this.renderSuggestions()}
561
191
  `;
562
192
  }
@@ -586,54 +216,13 @@ let FtSearchBar = class FtSearchBar extends FtLitElement {
586
216
  ></ft-button>
587
217
  `;
588
218
  }
589
- renderMobileFacetsActions() {
590
- if (!this.hasLocaleSelector && this.displayedFilters.length === 0) {
591
- return null;
592
- }
593
- if (this.displayFacets) {
594
- return html `
595
- <div class="ft-search-bar--facets-actions">
596
- <ft-button part="facets-actions"
597
- icon="arrow_back"
598
- label="${this.labelResolver.resolve("back")}"
599
- @click=${() => this.displayFacets = false}>
600
- ${this.labelResolver.resolve("back")}
601
- </ft-button>
602
- ${this.searchFilters.length > 0 ? html `
603
- <ft-button part="facets-actions" @click=${this.clearFilters}>
604
- ${this.labelResolver.resolve("clearFilters")}
605
- </ft-button>
606
- ` : null}
607
- </div>
608
- `;
609
- }
610
- let label = this.searchFilters.length > 0
611
- ? (this.searchFilters.length > 1
612
- ? this.labelResolver.resolve("nFiltersEnabled", this.searchFilters.length)
613
- : this.labelResolver.resolve("oneFilterEnabled"))
614
- : this.labelResolver.resolve("filtersButton");
615
- return html `
616
- <div class="ft-search-bar--facets-actions">
617
- <ft-button part="facets-actions"
618
- @click=${() => this.displayFacets = true}>
619
- ${label}
620
- </ft-button>
621
- </div>
622
- `;
623
- }
624
219
  renderMobileFacets() {
625
220
  var _a;
626
221
  const currentLocale = this.availableContentLocales.filter(l => l.lang === this.contentLocale).pop();
627
- const contentLocales = this.availableContentLocales.map(l => ({
628
- value: l.lang,
629
- label: l.label,
630
- selected: l.lang == this.contentLocale,
631
- options: []
632
- }));
633
222
  return html `
634
223
  <ft-accordion class="ft-search-bar--filters-container">
635
224
  ${this.hasLocaleSelector ? html `
636
- <ft-accordion-item>
225
+ <ft-accordion-item data-facet-key="ft:contentLocale">
637
226
  <div class="ft-search-bar--filter-label" slot="toggle">
638
227
  <ft-typography variant="button">${this.labelResolver.resolve("contentLocaleSelector")}
639
228
  </ft-typography>
@@ -644,11 +233,8 @@ let FtSearchBar = class FtSearchBar extends FtLitElement {
644
233
  <ft-filter
645
234
  part="filters"
646
235
  class="ft-search-bar--content-locale"
647
- id="content-locale"
648
236
  filterPlaceHolder="${this.labelResolver.resolve("filterInputPlaceHolder", this.labelResolver.resolve("contentLocaleSelector"))}"
649
- clearButtonLabel="${this.labelResolver.resolve("clearFilterButton")}"
650
- raiseSelectedOptions
651
- .options=${contentLocales}
237
+ .options=${(this.contentLocalesAsFilterOptions())}
652
238
  @change=${(e) => this.contentLocale = e.detail[0]}
653
239
  ></ft-filter>
654
240
  </ft-accordion-item>
@@ -656,7 +242,7 @@ let FtSearchBar = class FtSearchBar extends FtLitElement {
656
242
  ${repeat(this.facets, facet => facet.key, facet => {
657
243
  const filter = facetToFilter(facet);
658
244
  return html `
659
- <ft-accordion-item>
245
+ <ft-accordion-item data-facet-key="${facet.key}">
660
246
  <div class="ft-search-bar--filter-label" slot="toggle">
661
247
  <ft-typography variant="button">${facet.label}</ft-typography>
662
248
  <ft-typography variant="body2">
@@ -681,6 +267,226 @@ let FtSearchBar = class FtSearchBar extends FtLitElement {
681
267
  </ft-accordion>
682
268
  `;
683
269
  }
270
+ contentLocalesAsFilterOptions() {
271
+ return this.availableContentLocales.map(l => ({
272
+ value: l.lang,
273
+ label: l.label,
274
+ selected: l.lang == this.contentLocale
275
+ }));
276
+ }
277
+ renderDesktopSearchBar() {
278
+ return html `
279
+ <div class="ft-search-bar" part="search-bar">
280
+ ${(this.renderSearchBarLeftAction())}
281
+ <div class="ft-search-bar--input-container" part="input-container">
282
+ <div class="ft-search-bar--input-outline" part="input-outline">
283
+ ${this.dense ? this.renderSelectedFacets() : nothing}
284
+ <input class="ft-search-bar--input ft-typography--body2"
285
+ part="input"
286
+ type="text"
287
+ placeholder="${this.labelResolver.resolve("inputPlaceHolder")}"
288
+ value="${this.query}"
289
+ @keydown=${this.onSearchBarKeyDown}
290
+ @keyup=${this.onSearchBarKeyUp}>
291
+ </div>
292
+ ${this.renderSuggestions()}
293
+ </div>
294
+ ${this.renderDesktopSearchBarButtons()}
295
+ <div class="ft-search-bar--floating-panel" @keyup=${this.onFloatingContainerKeyUp} tabindex="-1">
296
+ ${this.renderFacetsActions()}
297
+ ${this.renderDesktopFacets()}
298
+
299
+ </div>
300
+ </div>
301
+ ${this.dense ? nothing : this.renderSelectedFacets()}
302
+ `;
303
+ }
304
+ renderSearchBarLeftAction() {
305
+ if (this.hasFacets) {
306
+ return html `
307
+ <ft-button class="ft-search-bar--filters-opener ft-search-bar--left-action"
308
+ part="filters-opener"
309
+ trailingIcon
310
+ icon="${this.displayFacets ? "expand_less" : "expand_more"}"
311
+ @click=${(e) => {
312
+ e.stopPropagation();
313
+ this.displayFacets = !this.displayFacets;
314
+ }}
315
+ @focusin=${(e) => e.stopPropagation()}>
316
+ ${this.labelResolver.resolve("filtersButton")}
317
+ </ft-button>
318
+ `;
319
+ }
320
+ if (this.hasLocaleSelector) {
321
+ return html `
322
+ <ft-select outlined
323
+ class="ft-search-bar--content-locale ft-search-bar--left-action"
324
+ part="content-locale"
325
+ @change=${(e) => this.contentLocale = e.detail}>
326
+ ${repeat(this.availableContentLocales, l => l.lang, l => html `
327
+ <ft-select-option value="${l.lang}"
328
+ label="${l.label}"
329
+ ?selected=${l.lang === this.contentLocale}>
330
+ </ft-select-option>
331
+ `)}
332
+ </ft-select>
333
+ `;
334
+ }
335
+ return nothing;
336
+ }
337
+ renderDesktopSearchBarButtons() {
338
+ return html `
339
+ ${this.query ? html `
340
+ <ft-button class="ft-search-bar--clear-query"
341
+ part="search-bar-actions"
342
+ icon="close"
343
+ round dense
344
+ label="${this.labelResolver.resolve("clearInputButton")}"
345
+ @click=${() => this.setQuery("")}
346
+ ></ft-button>
347
+ <div class="ft-search-bar--separator"></div>
348
+ ` : null}
349
+ <ft-button class="ft-search-bar--launch-search"
350
+ part="search-bar-actions"
351
+ icon="search"
352
+ round dense
353
+ label="${this.labelResolver.resolve("searchButton")}"
354
+ @click=${this.launchSearch}
355
+ ></ft-button>
356
+ `;
357
+ }
358
+ renderFacetsActions() {
359
+ return html `
360
+ <div class="ft-search-bar--facets-actions">
361
+ ${this.hasPresets ? html `
362
+ <ft-select
363
+ class="ft-search-bar--presets"
364
+ part="presets"
365
+ label="${this.labelResolver.resolve("presetsSelector")}"
366
+ outlined
367
+ @change=${(e) => this.selectedPreset = e.detail}>
368
+ ${repeat(this.presets, p => p.name, p => html `
369
+ <ft-select-option value="${p.name}"
370
+ label="${p.name}"
371
+ ?selected=${p.name === this.selectedPreset}>
372
+ </ft-select-option>
373
+ `)}
374
+ </ft-select>
375
+ ` : nothing}
376
+ ${this.searchFilters.length > 0 ? html `
377
+ <ft-button part="facets-actions"
378
+ @click=${this.clearFilters}>
379
+ ${this.labelResolver.resolve("clearFilters")}
380
+ </ft-button>
381
+ ` : nothing}
382
+ <slot name="facets-actions"></slot>
383
+ </div>
384
+ `;
385
+ }
386
+ renderDesktopFacets() {
387
+ if (!this.hasFacets) {
388
+ return nothing;
389
+ }
390
+ return html `
391
+ <ft-snap-scroll horizontal limitSize controls
392
+ class="ft-search-bar--filters-container"
393
+ part="filters-container">
394
+ ${this.hasLocaleSelector ? html `
395
+ <ft-filter part="filters"
396
+ class="ft-search-bar--content-locale"
397
+ label="${this.labelResolver.resolve("contentLocaleSelector")}"
398
+ filterPlaceHolder="${this.labelResolver.resolve("filterInputPlaceHolder", this.labelResolver.resolve("contentLocaleSelector"))}"
399
+ .options=${(this.contentLocalesAsFilterOptions())}
400
+ @change=${(e) => this.contentLocale = e.detail[0]}
401
+ ></ft-filter>
402
+ ` : nothing}
403
+ ${repeat(this.facets, facet => facet.key, facet => {
404
+ const filter = facetToFilter(facet);
405
+ 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; });
406
+ return html `
407
+ <ft-filter
408
+ class="${hierachical ? "ft-search-bar--hierarchical-filter" : ""}"
409
+ part="filters"
410
+ id="${filter.id}"
411
+ label="${filter.label}"
412
+ filterPlaceHolder="${this.labelResolver.resolve("filterInputPlaceHolder", filter.label)}"
413
+ clearButtonLabel="${this.labelResolver.resolve("clearFilterButton")}"
414
+ moreValuesButtonLabel="${this.labelResolver.resolve("displayMoreFilterValuesButton")}"
415
+ ?multivalued=${filter.multivalued}
416
+ raiseSelectedOptions
417
+ .options=${filter.options}
418
+ .displayedValuesLimit=${10}
419
+ @change=${(e) => this.setFilter(filter.id, filter.label, e.detail)}
420
+ ></ft-filter>
421
+ `;
422
+ })}
423
+ </ft-snap-scroll>
424
+ `;
425
+ }
426
+ renderSelectedFacets() {
427
+ if (!this.hasLocaleSelector && this.searchFilters.length === 0) {
428
+ return null;
429
+ }
430
+ const useSnapScroll = (!this.isMobile && this.dense) || (this.isMobile && this.mobileMenuOpen);
431
+ const filters = html `
432
+ ${this.hasLocaleSelector && (this.hasFacets || this.isMobile) ? html `
433
+ <ft-chip part="selected-filters"
434
+ ?dense=${this.dense && !this.isMobile}
435
+ ?clickable=${this.isMobile}
436
+ @click=${() => this.openMobileFilters("ft:contentLocale")}>
437
+ ${(this.getLocaleLabel(this.contentLocale))}
438
+ </ft-chip>
439
+ ` : null}
440
+ ${repeat(this.searchFilters, filter => filter.key, filter => {
441
+ return repeat(filter.values, value => {
442
+ let label = filter.label + ": " + getBreadcrumbFromValue(value);
443
+ const chip = html `
444
+ <ft-chip
445
+ part="selected-filters"
446
+ ?dense=${this.dense && !this.isMobile}
447
+ ?clickable=${this.isMobile}
448
+ ?removable=${!this.isMobile}
449
+ icon=${this.isMobile ? nothing : "close"}
450
+ label="${label}"
451
+ title=${useSnapScroll ? label : nothing}
452
+ @click=${() => this.openMobileFilters(filter.key)}
453
+ @icon-click=${() => this.setFilter(filter.key, filter.label, filter.values.filter(v => v !== value))}>
454
+ ${getLabelFromValue(value)}
455
+ </ft-chip>
456
+ `;
457
+ return useSnapScroll ? chip : html `
458
+ <ft-tooltip inline text="${label}">
459
+ ${chip}
460
+ </ft-tooltip>
461
+ `;
462
+ });
463
+ })}
464
+ ${this.isMobile ? html `
465
+ <ft-chip part="selected-filters"
466
+ icon="add"
467
+ clickable
468
+ @click=${() => {
469
+ this.mobileMenuOpen = true;
470
+ this.displayFacets = true;
471
+ }}>
472
+ ${this.labelResolver.resolve("filtersButton")}
473
+ </ft-chip>
474
+ ` : nothing}
475
+ `;
476
+ return useSnapScroll
477
+ ? html `
478
+ <ft-snap-scroll horizontal controls hideScrollbar limitSize
479
+ class="ft-search-bar--selected-filters"
480
+ part="selected-filters-container">
481
+ ${filters}
482
+ </ft-snap-scroll>
483
+ `
484
+ : html `
485
+ <div class="ft-search-bar--selected-filters" part="selected-filters-container">
486
+ ${filters}
487
+ </div>
488
+ `;
489
+ }
684
490
  renderSuggestions() {
685
491
  const filteredRecentSearches = this.recentSearches.filter(q => q.toLowerCase().includes(this.query.toLowerCase()));
686
492
  const shouldDisplaySuggestions = this.query.length > 2 || filteredRecentSearches.length > 0;
@@ -699,7 +505,7 @@ let FtSearchBar = class FtSearchBar extends FtLitElement {
699
505
  <ft-button icon="close"
700
506
  round
701
507
  part="remove-suggestion"
702
- ?dense=${this.sizeCategory !== FtSizeCategory.S}
508
+ ?dense=${!this.isMobile}
703
509
  label="${this.labelResolver.resolve("removeRecentSearch")}"
704
510
  @click=${(e) => this.removeRecentSearch(e, query)}></ft-button>
705
511
  </a>
@@ -745,89 +551,12 @@ let FtSearchBar = class FtSearchBar extends FtLitElement {
745
551
  </ft-icon>
746
552
  `;
747
553
  }
748
- renderDesktopFacetsActions() {
749
- return html `
750
- <div class="ft-search-bar--facets-actions">
751
- ${this.hasLocaleSelector ? html `
752
- <ft-select
753
- class="ft-search-bar--content-locale"
754
- part="content-locale"
755
- label="${this.labelResolver.resolve("contentLocaleSelector")}"
756
- outlined
757
- @change=${(e) => this.contentLocale = e.detail}>
758
- ${repeat(this.availableContentLocales, l => l.lang, l => html `
759
- <ft-select-option value="${l.lang}"
760
- label="${l.label}"
761
- ?selected=${l.lang === this.contentLocale}>
762
- </ft-select-option>
763
- `)}
764
- </ft-select>
765
- ` : null}
766
- ${this.searchFilters.length > 0 ? html `
767
- <ft-button part="facets-actions"
768
- @click=${this.clearFilters}>
769
- ${this.labelResolver.resolve("clearFilters")}
770
- </ft-button>
771
- ` : null}
772
- <slot name="facets-actions"></slot>
773
- </div>
774
- `;
775
- }
776
- renderDesktopFacets() {
777
- if (!this.hasFacets) {
778
- return null;
779
- }
780
- return html `
781
- <ft-snap-scroll horizontal limitSize controls
782
- class="ft-search-bar--filters-container"
783
- part="filters-container">
784
- ${repeat(this.facets, facet => facet.key, facet => {
785
- const filter = facetToFilter(facet);
786
- 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; });
787
- return html `
788
- <ft-filter
789
- class="${hierachical ? "ft-search-bar--hierarchical-filter" : ""}"
790
- part="filters"
791
- id="${filter.id}"
792
- label="${filter.label}"
793
- filterPlaceHolder="${this.labelResolver.resolve("filterInputPlaceHolder", filter.label)}"
794
- clearButtonLabel="${this.labelResolver.resolve("clearFilterButton")}"
795
- moreValuesButtonLabel="${this.labelResolver.resolve("displayMoreFilterValuesButton")}"
796
- ?multivalued=${filter.multivalued}
797
- raiseSelectedOptions
798
- .options=${filter.options}
799
- .displayedValuesLimit=${10}
800
- @change=${(e) => this.setFilter(filter.id, filter.label, e.detail)}
801
- ></ft-filter>
802
- `;
803
- })}
804
- </ft-snap-scroll>
805
- `;
806
- }
807
- renderSelectedFacets() {
808
- if (!this.hasLocaleSelector && this.searchFilters.length === 0) {
809
- return null;
554
+ openMobileFilters(filterKey) {
555
+ if (this.isMobile) {
556
+ this.mobileMenuOpen = true;
557
+ this.displayFacets = true;
558
+ this.scrollToFacet = filterKey;
810
559
  }
811
- return html `
812
- <div class="ft-search-bar--selected-filters" part="selected-filters-container">
813
- ${this.hasLocaleSelector && (this.hasFacets || this.sizeCategory === FtSizeCategory.S) ? html `
814
- <ft-chip part="selected-filters">${(this.getLocaleLabel(this.contentLocale))}</ft-chip>
815
- ` : null}
816
- ${repeat(this.searchFilters, filter => filter.key, filter => repeat(filter.values, value => {
817
- let label = filter.label + ": " + getBreadcrumbFromValue(value);
818
- return html `
819
- <ft-tooltip inline text="${label}">
820
- <ft-chip part="selected-filters"
821
- removable
822
- label="${label}"
823
- @icon-click=${() => this.setFilter(filter.key, filter.label, filter.values.filter(v => v !== value))}>
824
- ${getLabelFromValue(value)}
825
- </ft-chip>
826
- </ft-tooltip>
827
- `;
828
- }))}
829
- </div>
830
- `;
831
560
  }
832
561
  async firstUpdated(props) {
833
562
  var _a, _b;
@@ -836,18 +565,19 @@ let FtSearchBar = class FtSearchBar extends FtLitElement {
836
565
  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 : [];
837
566
  }
838
567
  update(props) {
839
- var _a, _b;
568
+ var _a, _b, _c;
840
569
  if (props.has("labels")) {
841
570
  this.labelResolver = new ParametrizedLabelResolver(DEFAULT_LABELS, this.labels);
842
571
  }
843
572
  if (props.has("sizeCategory")) {
844
573
  this.mobileMenuOpen = false;
845
- this.displayFacets = this.displayFacets && this.sizeCategory !== FtSizeCategory.S;
574
+ this.displayFacets = this.displayFacets && !this.isMobile;
846
575
  }
847
576
  super.update(props);
848
577
  if ((props.has("availableContentLocales") || props.has("contentLocale")) && this.availableContentLocales.length > 0) {
849
- if (!this.availableContentLocales.some(l => l.lang === this.contentLocale)) {
850
- this.contentLocale = (_a = this.availableContentLocales[0]) === null || _a === void 0 ? void 0 : _a.lang;
578
+ const isKnown = (locale) => this.availableContentLocales.some(l => l.lang === locale);
579
+ if (!isKnown(this.contentLocale)) {
580
+ this.contentLocale = props.has("contentLocale") && isKnown(props.get("contentLocale")) ? props.get("contentLocale") : (_a = this.availableContentLocales[0]) === null || _a === void 0 ? void 0 : _a.lang;
851
581
  }
852
582
  }
853
583
  if (props.has("baseUrl") && this.baseUrl) {
@@ -856,6 +586,15 @@ let FtSearchBar = class FtSearchBar extends FtLitElement {
856
586
  }
857
587
  this.recentSearches = JSON.parse((_b = window.localStorage.getItem(this.recentSearchesStorageKey)) !== null && _b !== void 0 ? _b : "[]");
858
588
  }
589
+ if (props.has("selectedPreset")) {
590
+ const currentPreset = this.presets.find(p => p.name === this.selectedPreset);
591
+ if (currentPreset && !this.compareRequests(this.request, currentPreset)) {
592
+ this.setFiltersFromPreset(currentPreset);
593
+ }
594
+ }
595
+ if (["contentLocale", "searchFilters"].some(p => props.has(p))) {
596
+ this.selectedPreset = (_c = this.presets.find(p => this.compareRequests(p, this.request))) === null || _c === void 0 ? void 0 : _c.name;
597
+ }
859
598
  if (["baseUrl", "apiIntegrationIdentifier"].some(p => props.has(p))) {
860
599
  this.setApi();
861
600
  }
@@ -870,13 +609,17 @@ let FtSearchBar = class FtSearchBar extends FtLitElement {
870
609
  }
871
610
  }
872
611
  contentAvailableCallback(props) {
873
- var _a, _b;
612
+ var _a, _b, _c;
874
613
  super.contentAvailableCallback(props);
875
614
  if (props.has("displayFacets") && this.displayFacets) {
876
615
  (_a = this.floatingContainer) === null || _a === void 0 ? void 0 : _a.focus();
877
616
  }
878
617
  if (this.scrollToFacet != null && this.facetsLoaded) {
879
618
  (_b = this.scrollingFiltersContainer) === null || _b === void 0 ? void 0 : _b.scrollIndexIntoView(this.facets.findIndex(f => f.key === this.scrollToFacet));
619
+ const maybeFacet = (_c = this.shadowRoot) === null || _c === void 0 ? void 0 : _c.querySelector(`ft-accordion-item[data-facet-key="${this.scrollToFacet}"]`);
620
+ if (maybeFacet) {
621
+ maybeFacet.active = true;
622
+ }
880
623
  this.scrollToFacet = undefined;
881
624
  }
882
625
  }
@@ -890,11 +633,12 @@ let FtSearchBar = class FtSearchBar extends FtLitElement {
890
633
  this.api = window.fluidtopics ? new window.fluidtopics.FluidTopicsApi(this.baseUrl, this.apiIntegrationIdentifier) : undefined;
891
634
  }
892
635
  updateFacets() {
893
- if (this.displayedFilters.length > 0) {
636
+ if (this.facetsRequest.length > 0) {
894
637
  this.facetsLoaded = false;
895
638
  this.updateFacetsDebouncer.run(async () => {
896
639
  var _a, _b;
897
640
  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 : [];
641
+ this.facets.forEach(f => this.knownFacetLabels[f.key] = f.label);
898
642
  this.facetsLoaded = true;
899
643
  });
900
644
  }
@@ -966,8 +710,10 @@ let FtSearchBar = class FtSearchBar extends FtLitElement {
966
710
  this.recentSearches = [this.query, ...filteredRecentSearches];
967
711
  this.saveRecentSearches();
968
712
  }
969
- this.focus();
970
713
  this.dispatchEvent(new LaunchSearchEvent(this.request));
714
+ this.mobileMenuOpen = false;
715
+ this.displayFacets = false;
716
+ this.focus();
971
717
  }
972
718
  saveRecentSearches() {
973
719
  window.localStorage.setItem(this.recentSearchesStorageKey, JSON.stringify(this.recentSearches));
@@ -1009,6 +755,14 @@ let FtSearchBar = class FtSearchBar extends FtLitElement {
1009
755
  this.searchFilters = newFilters;
1010
756
  this.scrollToFacet = key;
1011
757
  }
758
+ setFiltersFromPreset(request) {
759
+ if (request != null) {
760
+ if (request.contentLocale != null) {
761
+ this.contentLocale = request.contentLocale;
762
+ }
763
+ this.searchFilters = request.filters.map(f => { var _a; return ({ ...f, label: (_a = this.knownFacetLabels[f.key]) !== null && _a !== void 0 ? _a : f.key }); });
764
+ }
765
+ }
1012
766
  clearFilters() {
1013
767
  this.facets.forEach(facet => flatDeep(facet.rootNodes, n => n.childNodes).forEach(n => n.selected = false));
1014
768
  this.searchFilters = [];
@@ -1057,6 +811,9 @@ FtSearchBar.elementDefinitions = {
1057
811
  "ft-typography": FtTypography,
1058
812
  "mwc-icon": Icon,
1059
813
  };
814
+ __decorate([
815
+ property({ type: Boolean })
816
+ ], FtSearchBar.prototype, "dense", void 0);
1060
817
  __decorate([
1061
818
  property({ type: String })
1062
819
  ], FtSearchBar.prototype, "baseUrl", void 0);
@@ -1078,6 +835,12 @@ __decorate([
1078
835
  __decorate([
1079
836
  jsonProperty([])
1080
837
  ], FtSearchBar.prototype, "displayedFilters", void 0);
838
+ __decorate([
839
+ jsonProperty([])
840
+ ], FtSearchBar.prototype, "presets", void 0);
841
+ __decorate([
842
+ property({ type: String, reflect: true })
843
+ ], FtSearchBar.prototype, "selectedPreset", void 0);
1081
844
  __decorate([
1082
845
  property()
1083
846
  ], FtSearchBar.prototype, "searchRequestSerializer", void 0);