@fluid-topics/ft-search-bar 0.3.0 → 0.3.1

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,16 @@
1
+ import { FtSearchBar } from "../ft-search-bar";
2
+ import { FacetsChipsManager } from "./FacetsChipsManager";
3
+ import { SuggestManager } from "./SuggestManager";
4
+ export declare class DesktopSearchBarManager {
5
+ private searchBar;
6
+ private selectedFacetsManager;
7
+ private suggestManager;
8
+ constructor(searchBar: FtSearchBar, selectedFacetsManager?: FacetsChipsManager, suggestManager?: SuggestManager);
9
+ static styles: import("lit").CSSResult;
10
+ render(): import("lit-html").TemplateResult<1>;
11
+ private renderSearchBarLeftAction;
12
+ private renderDesktopSearchBarButtons;
13
+ private onSearchBarKeyDown;
14
+ private onSearchBarKeyUp;
15
+ }
16
+ //# sourceMappingURL=DesktopSearchBarManager.d.ts.map
@@ -0,0 +1,131 @@
1
+ import { css, html, nothing } from "lit";
2
+ import { repeat } from "lit/directives/repeat.js";
3
+ import { FacetsChipsManager } from "./FacetsChipsManager";
4
+ import { SuggestManager } from "./SuggestManager";
5
+ import { classMap } from "lit/directives/class-map.js";
6
+ export class DesktopSearchBarManager {
7
+ constructor(searchBar, selectedFacetsManager, suggestManager) {
8
+ this.searchBar = searchBar;
9
+ this.selectedFacetsManager = selectedFacetsManager !== null && selectedFacetsManager !== void 0 ? selectedFacetsManager : new FacetsChipsManager(searchBar);
10
+ this.suggestManager = suggestManager !== null && suggestManager !== void 0 ? suggestManager : new SuggestManager(searchBar);
11
+ }
12
+ render() {
13
+ const rootClasses = {
14
+ "ft-search-bar--container": true,
15
+ "ft-search-bar--dense": this.searchBar.dense,
16
+ "ft-search-bar--desktop": true,
17
+ "ft-search-bar--floating-panel-open": this.searchBar.displayFacets && !this.searchBar.forceMenuOpen,
18
+ "ft-search-bar--forced-open": this.searchBar.forceMenuOpen
19
+ };
20
+ return html `
21
+ <div class="${classMap(rootClasses)}" part="container" tabindex="-1">
22
+ <div class="ft-search-bar" part="search-bar">
23
+ ${(this.renderSearchBarLeftAction())}
24
+ <div class="ft-search-bar--input-container" part="input-container" tabindex="-1">
25
+ <div class="ft-search-bar--input-outline" part="input-outline">
26
+ ${this.searchBar.dense ? this.selectedFacetsManager.render() : nothing}
27
+ <input class="ft-search-bar--input ft-typography--body2"
28
+ part="input"
29
+ type="text"
30
+ placeholder="${this.searchBar.labelResolver.resolve("inputPlaceHolder")}"
31
+ value="${this.searchBar.query}"
32
+ @keydown=${(e) => this.onSearchBarKeyDown(e)}
33
+ @keyup=${(e) => this.onSearchBarKeyUp(e)}>
34
+ </div>
35
+ ${this.suggestManager.render()}
36
+ </div>
37
+ ${this.renderDesktopSearchBarButtons()}
38
+ ${this.searchBar.renderDesktopFloatingMenu()}
39
+ </div>
40
+ ${this.searchBar.dense
41
+ ? nothing
42
+ : this.searchBar.forceMenuOpen ? this.searchBar.renderDesktopMenu()
43
+ : this.selectedFacetsManager.render()}
44
+ </div>
45
+ `;
46
+ }
47
+ renderSearchBarLeftAction() {
48
+ if (this.searchBar.hasFacets()) {
49
+ return this.searchBar.forceMenuOpen ? nothing : html `
50
+ <ft-button class="ft-search-bar--filters-opener ft-search-bar--left-action"
51
+ part="filters-opener"
52
+ trailingIcon
53
+ icon="${this.searchBar.displayFacets ? "expand_less" : "expand_more"}"
54
+ @click=${(e) => {
55
+ e.stopPropagation();
56
+ this.searchBar.displayFacets = !this.searchBar.displayFacets;
57
+ }}
58
+ @focusin=${(e) => e.stopPropagation()}>
59
+ ${this.searchBar.labelResolver.resolve("filtersButton")}
60
+ </ft-button>
61
+ `;
62
+ }
63
+ else if (this.searchBar.hasLocaleSelector()) {
64
+ return html `
65
+ <ft-select outlined
66
+ class="ft-search-bar--content-locale ft-search-bar--left-action"
67
+ part="content-locale select-ft-locale"
68
+ .exportpartsPrefixes=${["content-locale", "select-ft-locale"]}
69
+ @change=${(e) => this.searchBar.contentLocale = e.detail == null ? undefined : e.detail}>
70
+ ${repeat(this.searchBar.availableContentLocales, l => l.lang, l => html `
71
+ <ft-select-option .value=${l.lang}
72
+ label="${l.label}"
73
+ ?selected=${l.lang === this.searchBar.contentLocale}>
74
+ </ft-select-option>
75
+ `)}
76
+ </ft-select>
77
+ `;
78
+ }
79
+ return nothing;
80
+ }
81
+ renderDesktopSearchBarButtons() {
82
+ return html `
83
+ <div class="ft-search-bar--actions"
84
+ part="search-bar-actions">
85
+ ${this.searchBar.query ? html `
86
+ <ft-button class="ft-search-bar--clear-query"
87
+ part="clear-query"
88
+ icon="close"
89
+ round dense
90
+ label="${this.searchBar.labelResolver.resolve("clearInputButton")}"
91
+ @click=${() => this.searchBar.setQuery("")}
92
+ ></ft-button>
93
+ <div class="ft-search-bar--separator"></div>
94
+ ` : null}
95
+ <ft-button class="ft-search-bar--launch-search"
96
+ part="launch-search-in-bar"
97
+ icon="search"
98
+ round dense
99
+ label="${this.searchBar.labelResolver.resolve("searchButton")}"
100
+ @click=${() => this.searchBar.launchSearch()}
101
+ ></ft-button>
102
+ </div>
103
+ `;
104
+ }
105
+ onSearchBarKeyDown(e) {
106
+ var _a;
107
+ switch (e.key) {
108
+ case "Escape":
109
+ this.searchBar.mobileMenuOpen = false;
110
+ (_a = this.searchBar.input) === null || _a === void 0 ? void 0 : _a.blur();
111
+ break;
112
+ case "ArrowDown":
113
+ e.stopPropagation();
114
+ e.preventDefault();
115
+ this.suggestManager.focusFirstSuggestion();
116
+ break;
117
+ }
118
+ }
119
+ onSearchBarKeyUp(e) {
120
+ const input = e.composedPath()[0];
121
+ this.searchBar.query = input.value;
122
+ if (e.key === "Enter") {
123
+ this.searchBar.launchSearch();
124
+ }
125
+ }
126
+ }
127
+ //language=css
128
+ DesktopSearchBarManager.styles = css `
129
+
130
+ `;
131
+ //# sourceMappingURL=DesktopSearchBarManager.js.map
@@ -0,0 +1,10 @@
1
+ import type { FtSearchBar } from "../ft-search-bar";
2
+ export declare class FacetsChipsManager {
3
+ private searchBar;
4
+ constructor(searchBar: FtSearchBar);
5
+ static styles: import("lit").CSSResult;
6
+ render(): import("lit-html").TemplateResult<1>;
7
+ private openMobileFilters;
8
+ getLocaleLabel(locale: string | undefined): string | undefined;
9
+ }
10
+ //# sourceMappingURL=FacetsChipsManager.d.ts.map
@@ -0,0 +1,129 @@
1
+ import { css, html, nothing } from "lit";
2
+ import { repeat } from "lit/directives/repeat.js";
3
+ import { getBreadcrumbFromValue, getLabelFromValue, getSelectedValues } from "../converters";
4
+ import { setVariable } from "@fluid-topics/ft-wc-utils";
5
+ import { FtSnapScrollCssVariables } from "@fluid-topics/ft-snap-scroll";
6
+ import { FtChipCssVariables } from "@fluid-topics/ft-chip";
7
+ export class FacetsChipsManager {
8
+ constructor(searchBar) {
9
+ this.searchBar = searchBar;
10
+ }
11
+ render() {
12
+ if (!this.searchBar.hasLocaleSelector() && !this.searchBar.hasFacets()) {
13
+ return html ``;
14
+ }
15
+ const isMobile = this.searchBar.isMobile();
16
+ const useSnapScroll = (!isMobile && this.searchBar.dense) || (isMobile && this.searchBar.isMobileMenuOpen());
17
+ const filters = html `
18
+ ${this.searchBar.hasLocaleSelector() && (this.searchBar.hasFacets() || isMobile) ? html `
19
+ <ft-chip part="selected-filters selected-filter-ft-locale"
20
+ ?dense=${this.searchBar.dense && !isMobile}
21
+ ?clickable=${isMobile}
22
+ @click=${() => this.openMobileFilters("ft:locale")}
23
+ data-key="ft:locale"
24
+ data-value="${this.searchBar.contentLocale}">
25
+ ${(this.getLocaleLabel(this.searchBar.contentLocale))}
26
+ </ft-chip>
27
+ ` : null}
28
+ ${repeat(this.searchBar.facets, facet => facet.key, facet => {
29
+ const values = getSelectedValues(facet);
30
+ return repeat(values, value => {
31
+ let label = facet.label + ": " + getBreadcrumbFromValue(value);
32
+ const keyWithNoColumn = facet.key.replace(":", "-");
33
+ const chip = html `
34
+ <ft-chip
35
+ part="selected-filters selected-filter-${keyWithNoColumn}"
36
+ ?dense=${this.searchBar.dense && !isMobile}
37
+ ?clickable=${isMobile}
38
+ ?removable=${!isMobile}
39
+ icon=${isMobile ? nothing : "close"}
40
+ label="${label}"
41
+ title=${useSnapScroll ? label : nothing}
42
+ @click=${() => this.openMobileFilters(facet.key)}
43
+ @icon-click=${() => this.searchBar.setFilter(facet.key, values.filter(v => v !== value))}
44
+ data-key="${facet.key}"
45
+ data-value="${value}">
46
+ ${getLabelFromValue(value)}
47
+ </ft-chip>
48
+ `;
49
+ return useSnapScroll ? chip : html `
50
+ <ft-tooltip inline text="${label}">
51
+ ${chip}
52
+ </ft-tooltip>
53
+ `;
54
+ });
55
+ })}
56
+ ${isMobile ? html `
57
+ <ft-chip part="selected-filters mobile-filters-opener"
58
+ icon="add"
59
+ clickable
60
+ @click=${() => {
61
+ this.searchBar.mobileMenuOpen = true;
62
+ this.searchBar.displayFacets = true;
63
+ }}>
64
+ ${this.searchBar.labelResolver.resolve("filtersButton")}
65
+ </ft-chip>
66
+ ` : nothing}
67
+ `;
68
+ return useSnapScroll
69
+ ? html `
70
+ <ft-snap-scroll horizontal controls hideScrollbar limitSize
71
+ class="ft-search-bar--selected-filters"
72
+ part="selected-filters-container"
73
+ exportpartsPrefix="selected-filters-container">
74
+ ${filters}
75
+ </ft-snap-scroll>
76
+ `
77
+ : html `
78
+ <div class="ft-search-bar--selected-filters" part="selected-filters-container">
79
+ ${filters}
80
+ </div>
81
+ `;
82
+ }
83
+ openMobileFilters(filterKey) {
84
+ if (this.searchBar.isMobile()) {
85
+ this.searchBar.mobileMenuOpen = true;
86
+ this.searchBar.displayFacets = true;
87
+ this.searchBar.scrollToFacet = filterKey;
88
+ }
89
+ }
90
+ getLocaleLabel(locale) {
91
+ var _a;
92
+ return (_a = this.searchBar.availableContentLocales.filter(l => { var _a; return ((_a = l.lang) !== null && _a !== void 0 ? _a : "").toLowerCase() === (locale !== null && locale !== void 0 ? locale : "").toLowerCase(); })
93
+ .map(l => l.label)
94
+ .pop()) !== null && _a !== void 0 ? _a : locale;
95
+ }
96
+ }
97
+ //language=css
98
+ FacetsChipsManager.styles = css `
99
+ .ft-search-bar--selected-filters:not(ft-snap-scroll) {
100
+ flex-shrink: 0;
101
+ display: flex;
102
+ flex-direction: row;
103
+ flex-wrap: wrap;
104
+ gap: 8px;
105
+ }
106
+
107
+ ft-snap-scroll.ft-search-bar--selected-filters {
108
+ overflow: hidden;
109
+ ${setVariable(FtSnapScrollCssVariables.gap, "4px")};
110
+ }
111
+
112
+ ft-snap-scroll.ft-search-bar--selected-filters::part(content) {
113
+ align-items: center;
114
+ }
115
+
116
+ .ft-search-bar--desktop ft-snap-scroll.ft-search-bar--selected-filters {
117
+ ${setVariable(FtChipCssVariables.iconSize, "17px")};
118
+ ${setVariable(FtChipCssVariables.fontSize, "12px")};
119
+ }
120
+
121
+ .ft-search-bar--selected-filters * {
122
+ max-width: 100%;
123
+ }
124
+
125
+ .ft-search-bar--selected-filters ft-chip {
126
+ flex-grow: 0;
127
+ }
128
+ `;
129
+ //# sourceMappingURL=FacetsChipsManager.js.map
@@ -0,0 +1,14 @@
1
+ import { FtSearchBar } from "../ft-search-bar";
2
+ import { FacetsChipsManager } from "./FacetsChipsManager";
3
+ import { SuggestManager } from "./SuggestManager";
4
+ export declare class MobileSearchBarManager {
5
+ private searchBar;
6
+ private selectedFacetsManager;
7
+ private suggestManager;
8
+ constructor(searchBar: FtSearchBar, selectedFacetsManager?: FacetsChipsManager, suggestManager?: SuggestManager);
9
+ static styles: import("lit").CSSResult;
10
+ render(): import("lit-html").TemplateResult<1>;
11
+ private renderMobileSearchBarButtons;
12
+ private onSearchBarKeyUp;
13
+ }
14
+ //# sourceMappingURL=MobileSearchBarManager.d.ts.map
@@ -0,0 +1,92 @@
1
+ import { css, html, nothing } from "lit";
2
+ import { FacetsChipsManager } from "./FacetsChipsManager";
3
+ import { SuggestManager } from "./SuggestManager";
4
+ import { classMap } from "lit/directives/class-map.js";
5
+ export class MobileSearchBarManager {
6
+ constructor(searchBar, selectedFacetsManager, suggestManager) {
7
+ this.searchBar = searchBar;
8
+ this.selectedFacetsManager = selectedFacetsManager !== null && selectedFacetsManager !== void 0 ? selectedFacetsManager : new FacetsChipsManager(searchBar);
9
+ this.suggestManager = suggestManager !== null && suggestManager !== void 0 ? suggestManager : new SuggestManager(searchBar);
10
+ }
11
+ render() {
12
+ const rootClasses = {
13
+ "ft-search-bar--container": true,
14
+ "ft-search-bar--mobile": true,
15
+ "ft-search-bar--mobile-menu-open": this.searchBar.isMobileMenuOpen(),
16
+ "ft-search-bar--forced-open": this.searchBar.forceMobileMenuOpen,
17
+ };
18
+ return html `
19
+ <div class="${classMap(rootClasses)}" part="container" tabindex="-1">
20
+ <div class="ft-search-bar">
21
+ <div class="ft-search-bar--input-container" part="input-container">
22
+ <div class="ft-search-bar--input-outline" part="input-outline">
23
+ <input class="ft-search-bar--input ft-typography--body2"
24
+ part="input"
25
+ type="text"
26
+ placeholder="${this.searchBar.labelResolver.resolve("inputPlaceHolder")}"
27
+ value="${this.searchBar.query}"
28
+ @keyup=${(e) => this.onSearchBarKeyUp(e)}
29
+ @focus=${() => {
30
+ this.searchBar.mobileMenuOpen = true;
31
+ this.searchBar.displayFacets = false;
32
+ }}>
33
+ </div>
34
+ </div>
35
+ ${this.renderMobileSearchBarButtons()}
36
+ </div>
37
+ ${this.searchBar.displayFacets ? this.searchBar.renderFacetsActions() : this.selectedFacetsManager.render()}
38
+ ${this.searchBar.displayFacets ? this.searchBar.renderMobileFacets() : this.suggestManager.render()}
39
+ ${this.searchBar.isMobileMenuOpen() || this.searchBar.displayFacets ? html `
40
+ <ft-button class="ft-search-bar--launch-search"
41
+ part="launch-search-in-panel"
42
+ icon="search"
43
+ @click=${this.searchBar.launchSearch}>
44
+ ${this.searchBar.labelResolver.resolve("searchButton")}
45
+ </ft-button>
46
+ ` : nothing}
47
+ </div>
48
+ `;
49
+ }
50
+ renderMobileSearchBarButtons() {
51
+ const displayClearButton = this.searchBar.query || (this.searchBar.isMobileMenuOpen() && !this.searchBar.forceMobileMenuOpen);
52
+ return html `
53
+ <div class="ft-search-bar--actions" part="search-bar-actions">
54
+ ${displayClearButton ? html `
55
+ <ft-button class="ft-search-bar--clear-query"
56
+ part="clear-query"
57
+ icon="close"
58
+ round
59
+ label="${this.searchBar.labelResolver.resolve("clearInputButton")}"
60
+ tooltipPosition="left"
61
+ @click=${() => {
62
+ this.searchBar.setQuery("");
63
+ this.searchBar.mobileMenuOpen = false;
64
+ this.searchBar.displayFacets = false;
65
+ }}
66
+ ></ft-button>
67
+ <div class="ft-search-bar--separator"></div>
68
+ ` : nothing}
69
+ <ft-button class="ft-search-bar--launch-search"
70
+ part="launch-search-in-bar"
71
+ icon="search"
72
+ round
73
+ label="${this.searchBar.labelResolver.resolve("searchButton")}"
74
+ tooltipPosition="left"
75
+ @click=${() => { var _a; return this.searchBar.isMobileMenuOpen() ? this.searchBar.launchSearch() : (_a = this.searchBar.input) === null || _a === void 0 ? void 0 : _a.focus(); }}
76
+ ></ft-button>
77
+ </div>
78
+ `;
79
+ }
80
+ onSearchBarKeyUp(e) {
81
+ const input = e.composedPath()[0];
82
+ this.searchBar.query = input.value;
83
+ if (e.key === "Enter") {
84
+ this.searchBar.launchSearch();
85
+ }
86
+ }
87
+ }
88
+ //language=css
89
+ MobileSearchBarManager.styles = css `
90
+
91
+ `;
92
+ //# sourceMappingURL=MobileSearchBarManager.js.map
@@ -0,0 +1,20 @@
1
+ import type { FtSearchBar } from "../ft-search-bar";
2
+ export declare class SuggestManager {
3
+ private searchBar;
4
+ private updateDebouncer;
5
+ constructor(searchBar: FtSearchBar, debounceTime?: number);
6
+ static styles: import("lit").CSSResult;
7
+ render(): import("lit-html").TemplateResult<1>;
8
+ update(): Promise<void>;
9
+ private onSuggestKeyDown;
10
+ private onSuggestKeyUp;
11
+ private onSuggestClick;
12
+ private onSuggestSelected;
13
+ private removeRecentSearch;
14
+ private getIcon;
15
+ private getFocusedSuggestionElement;
16
+ private getLastSuggestionElement;
17
+ private getFirstSuggestionElement;
18
+ focusFirstSuggestion(): void;
19
+ }
20
+ //# sourceMappingURL=SuggestManager.d.ts.map
@@ -0,0 +1,215 @@
1
+ import { css, html } from "lit";
2
+ import { repeat } from "lit/directives/repeat.js";
3
+ import { FtIcons, FtIconVariants, resolveFileFormatIcon } from "@fluid-topics/ft-icon";
4
+ import { Debouncer } from "@fluid-topics/ft-wc-utils";
5
+ import { FtSearchBarCssVariables } from "../ft-search-bar.css";
6
+ export class SuggestManager {
7
+ constructor(searchBar, debounceTime = 300) {
8
+ this.searchBar = searchBar;
9
+ this.updateDebouncer = new Debouncer(debounceTime);
10
+ }
11
+ render() {
12
+ const filteredRecentSearches = this.searchBar.recentSearches.filter(q => q.toLowerCase().includes(this.searchBar.query.toLowerCase()));
13
+ const shouldDisplaySuggestions = this.searchBar.suggestions.length > 0 || filteredRecentSearches.length > 0;
14
+ return html `
15
+ <div class="ft-search-bar--suggestions ${shouldDisplaySuggestions ? "ft-search-bar--suggestions-not-empty" : ""}"
16
+ part="suggestions-container"
17
+ @keydown=${(e) => this.onSuggestKeyDown(e)}>
18
+ ${repeat(filteredRecentSearches.slice(0, 5), query => query, query => html `
19
+ <a href="${this.searchBar.searchRequestSerializer({
20
+ ...this.searchBar.request,
21
+ query: query
22
+ })}"
23
+ part="suggestions"
24
+ class="ft-search-bar--suggestion ft-search-bar--recent-search"
25
+ @keyup=${(e) => this.onSuggestKeyUp(e, query)}
26
+ @click=${(e) => this.onSuggestClick(e, query)}>
27
+ <ft-ripple></ft-ripple>
28
+ <ft-icon variant="material" part="suggestion-icon">history</ft-icon>
29
+ <ft-typography variant="body1">${query}</ft-typography>
30
+ <ft-button icon="close"
31
+ round
32
+ part="remove-suggestion"
33
+ ?dense=${!this.searchBar.isMobile}
34
+ label="${this.searchBar.labelResolver.resolve("removeRecentSearch")}"
35
+ tooltipPosition="left"
36
+ @click=${(e) => this.removeRecentSearch(e, query)}></ft-button>
37
+ </a>
38
+ `)}
39
+ ${repeat(this.searchBar.suggestions, suggest => suggest.value, suggest => html `
40
+ <a href="${this.searchBar.searchRequestSerializer({
41
+ ...this.searchBar.request,
42
+ query: suggest.value
43
+ })}"
44
+ part="suggestions"
45
+ class="ft-search-bar--suggestion"
46
+ @keyup=${(e) => this.onSuggestKeyUp(e, suggest.value)}
47
+ @click=${(e) => this.onSuggestClick(e, suggest.value)}>
48
+ <ft-ripple></ft-ripple>
49
+ ${this.getIcon(suggest)}
50
+ <ft-typography variant="body1">${suggest.value}</ft-typography>
51
+ </a>
52
+ `)}
53
+ </div>
54
+ `;
55
+ }
56
+ update() {
57
+ return new Promise((accept, reject) => {
58
+ this.updateDebouncer.run(async () => {
59
+ this.searchBar.suggestions = this.searchBar.api && this.searchBar.query.length > 2
60
+ ? await this.searchBar.api.getSuggestions(this.searchBar.suggestRequest).then(r => r.suggestions).catch(() => [])
61
+ : [];
62
+ accept();
63
+ });
64
+ });
65
+ }
66
+ onSuggestKeyDown(e) {
67
+ var _a, _b, _c, _d, _e, _f;
68
+ switch (e.key) {
69
+ case "ArrowUp":
70
+ (_c = ((_b = (_a = this.getFocusedSuggestionElement()) === null || _a === void 0 ? void 0 : _a.previousElementSibling) !== null && _b !== void 0 ? _b : this.getLastSuggestionElement())) === null || _c === void 0 ? void 0 : _c.focus();
71
+ e.preventDefault();
72
+ e.stopPropagation();
73
+ break;
74
+ case "ArrowDown":
75
+ (_f = ((_e = (_d = this.getFocusedSuggestionElement()) === null || _d === void 0 ? void 0 : _d.nextElementSibling) !== null && _e !== void 0 ? _e : this.getFirstSuggestionElement())) === null || _f === void 0 ? void 0 : _f.focus();
76
+ e.preventDefault();
77
+ e.stopPropagation();
78
+ break;
79
+ }
80
+ }
81
+ onSuggestKeyUp(e, suggest) {
82
+ if (e.key === "Enter" || e.key === " ") {
83
+ this.onSuggestSelected(e, suggest);
84
+ }
85
+ }
86
+ onSuggestClick(e, suggest) {
87
+ if (!e.ctrlKey && !e.metaKey) {
88
+ this.onSuggestSelected(e, suggest);
89
+ }
90
+ }
91
+ onSuggestSelected(e, suggest) {
92
+ e.preventDefault();
93
+ this.searchBar.setQuery(suggest);
94
+ this.searchBar.launchSearch();
95
+ }
96
+ removeRecentSearch(e, query) {
97
+ var _a, _b;
98
+ e.preventDefault();
99
+ e.stopPropagation();
100
+ let currentFocuseElement = e.target.closest(".ft-search-bar--suggestion");
101
+ const thingToFocus = (_b = (_a = currentFocuseElement === null || currentFocuseElement === void 0 ? void 0 : currentFocuseElement.previousElementSibling) !== null && _a !== void 0 ? _a : currentFocuseElement === null || currentFocuseElement === void 0 ? void 0 : currentFocuseElement.nextElementSibling) !== null && _b !== void 0 ? _b : this.searchBar.input;
102
+ thingToFocus === null || thingToFocus === void 0 ? void 0 : thingToFocus.focus();
103
+ this.searchBar.recentSearches = this.searchBar.recentSearches.filter(q => q.toLowerCase() !== query.toLowerCase());
104
+ this.searchBar.saveRecentSearches();
105
+ }
106
+ getIcon(suggest) {
107
+ const iconVariant = suggest.type === "DOCUMENT" ? FtIconVariants.file_format : FtIconVariants.fluid_topics;
108
+ let icon;
109
+ switch (suggest.type) {
110
+ case "MAP":
111
+ icon = suggest.editorialType === "BOOK" ? FtIcons.BOOK : FtIcons.ARTICLE;
112
+ break;
113
+ case "DOCUMENT":
114
+ icon = resolveFileFormatIcon(suggest.mimeType, suggest.filenameExtension);
115
+ break;
116
+ case "TOPIC":
117
+ icon = FtIcons.TOPICS;
118
+ break;
119
+ }
120
+ return html `
121
+ <ft-icon variant="${iconVariant}" part="suggestion-icon">
122
+ ${icon}
123
+ </ft-icon>
124
+ `;
125
+ }
126
+ getFocusedSuggestionElement() {
127
+ return this.searchBar.querySelector(".ft-search-bar--suggestion:focus-within");
128
+ }
129
+ getLastSuggestionElement() {
130
+ let suggestions = this.searchBar.querySelectorAll(".ft-search-bar--suggestion");
131
+ return suggestions.length > 0 ? suggestions[suggestions.length - 1] : null;
132
+ }
133
+ getFirstSuggestionElement() {
134
+ return this.searchBar.querySelector(".ft-search-bar--suggestion");
135
+ }
136
+ focusFirstSuggestion() {
137
+ var _a;
138
+ (_a = this.getFirstSuggestionElement()) === null || _a === void 0 ? void 0 : _a.focus();
139
+ }
140
+ }
141
+ //language=css
142
+ SuggestManager.styles = css `
143
+ .ft-search-bar--mobile .ft-search-bar--suggestions {
144
+ flex-grow: 1;
145
+ flex-shrink: 1;
146
+ overflow-y: auto;
147
+ height: 0;
148
+ }
149
+
150
+ .ft-search-bar--mobile-menu-open .ft-search-bar--suggestions {
151
+ border-top: 1px solid ${FtSearchBarCssVariables.colorOutline};
152
+ }
153
+
154
+ .ft-search-bar--mobile-menu-open .ft-search-bar--suggestions {
155
+ height: initial;
156
+ }
157
+
158
+ .ft-search-bar--floating-panel,
159
+ .ft-search-bar--desktop .ft-search-bar--suggestions {
160
+ position: absolute;
161
+ z-index: ${FtSearchBarCssVariables.floatingZIndex};
162
+ top: 100%;
163
+ left: -1px;
164
+ right: -1px;
165
+ display: none;
166
+ background: ${FtSearchBarCssVariables.colorSurface};
167
+ border: 1px solid ${FtSearchBarCssVariables.colorOutline};
168
+ border-radius: 0 0 ${FtSearchBarCssVariables.borderRadius} ${FtSearchBarCssVariables.borderRadius};
169
+ box-shadow: ${FtSearchBarCssVariables.elevation02};
170
+ outline: none;
171
+ }
172
+
173
+ .ft-search-bar--desktop .ft-search-bar--suggestions {
174
+ top: calc(100% + 2px);
175
+ }
176
+
177
+ .ft-search-bar--input-container:focus-within .ft-search-bar--suggestions-not-empty {
178
+ display: block;
179
+ }
180
+
181
+ .ft-search-bar--suggestion {
182
+ text-decoration: none;
183
+ position: relative;
184
+ display: flex;
185
+ align-items: center;
186
+ padding: 8px;
187
+ gap: 8px;
188
+ cursor: pointer;
189
+ color: ${FtSearchBarCssVariables.colorOnSurface};
190
+ min-height: 52px;
191
+ }
192
+
193
+ .ft-search-bar--suggestion > *:not(ft-ripple) {
194
+ position: relative;
195
+ }
196
+
197
+ .ft-search-bar--desktop .ft-search-bar--suggestion {
198
+ min-height: 44px;
199
+ }
200
+
201
+ .ft-search-bar--suggestion:focus {
202
+ outline: none;
203
+ }
204
+
205
+ .ft-search-bar--recent-search + .ft-search-bar--suggestion:not(.ft-search-bar--recent-search) {
206
+ border-top: 1px solid ${FtSearchBarCssVariables.colorOutline};
207
+ }
208
+
209
+ .ft-search-bar--suggestion ft-typography {
210
+ display: block;
211
+ flex-grow: 1;
212
+ flex-shrink: 1;
213
+ }
214
+ `;
215
+ //# sourceMappingURL=SuggestManager.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluid-topics/ft-search-bar",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Search bar component using Fluid Topics public API",
5
5
  "keywords": [
6
6
  "Lit"
@@ -11,26 +11,26 @@
11
11
  "web": "build/ft-search-bar.min.js",
12
12
  "typings": "build/index",
13
13
  "files": [
14
- "build/*.ts",
15
- "build/*.js"
14
+ "build/**/*.ts",
15
+ "build/**/*.js"
16
16
  ],
17
17
  "repository": {
18
18
  "type": "git",
19
19
  "url": "ssh://git@scm.mrs.antidot.net:2222/fluidtopics/ft-web-components.git"
20
20
  },
21
21
  "dependencies": {
22
- "@fluid-topics/ft-accordion": "^0.3.0",
23
- "@fluid-topics/ft-button": "^0.3.0",
24
- "@fluid-topics/ft-chip": "^0.3.0",
25
- "@fluid-topics/ft-filter": "^0.3.0",
26
- "@fluid-topics/ft-icon": "^0.3.0",
27
- "@fluid-topics/ft-select": "^0.3.0",
28
- "@fluid-topics/ft-size-watcher": "^0.3.0",
29
- "@fluid-topics/ft-skeleton": "^0.3.0",
30
- "@fluid-topics/ft-snap-scroll": "^0.3.0",
31
- "@fluid-topics/ft-tooltip": "^0.3.0",
32
- "@fluid-topics/ft-typography": "^0.3.0",
33
- "@fluid-topics/ft-wc-utils": "^0.3.0",
22
+ "@fluid-topics/ft-accordion": "0.3.1",
23
+ "@fluid-topics/ft-button": "0.3.1",
24
+ "@fluid-topics/ft-chip": "0.3.1",
25
+ "@fluid-topics/ft-filter": "0.3.1",
26
+ "@fluid-topics/ft-icon": "0.3.1",
27
+ "@fluid-topics/ft-select": "0.3.1",
28
+ "@fluid-topics/ft-size-watcher": "0.3.1",
29
+ "@fluid-topics/ft-skeleton": "0.3.1",
30
+ "@fluid-topics/ft-snap-scroll": "0.3.1",
31
+ "@fluid-topics/ft-tooltip": "0.3.1",
32
+ "@fluid-topics/ft-typography": "0.3.1",
33
+ "@fluid-topics/ft-wc-utils": "0.3.1",
34
34
  "lit": "2.2.8"
35
35
  },
36
36
  "devDependencies": {
@@ -39,5 +39,5 @@
39
39
  "peerDependencies": {
40
40
  "@fluid-topics/public-api": "1.0.18"
41
41
  },
42
- "gitHead": "2019aceb4a578402211f951ec3d68dbc0acf25c7"
42
+ "gitHead": "59991498f66c54210024c0fc6702955901f94952"
43
43
  }