@fluid-topics/ft-search-breadcrumbs 1.4.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.
package/README.md ADDED
@@ -0,0 +1,19 @@
1
+ search breadcrumbs component
2
+
3
+ ## Install
4
+
5
+ ```shell
6
+ npm install @fluid-topics/ft-search-breadcrumbs
7
+ yarn add @fluid-topics/ft-search-breadcrumbs
8
+ ```
9
+
10
+ ## Usage
11
+
12
+ ```typescript
13
+ import { html } from "lit"
14
+ import "@fluid-topics/ft-search-breadcrumbs"
15
+
16
+ function render() {
17
+ return html` <ft-search-breadcrumbs foo="bar"></ft-search-breadcrumbs> `
18
+ }
19
+ ```
@@ -0,0 +1,7 @@
1
+ import { DefaultI18nMessages, I18nMessageContext, I18nMessages } from "@fluid-topics/ft-i18n/build/generator/I18nMessageContext";
2
+ export interface SearchBreadcrumbsMessages extends I18nMessages {
3
+ olAriaLabel(): string;
4
+ menuShowMore(): string;
5
+ }
6
+ export declare const searchBreadcrumbsContext: I18nMessageContext<SearchBreadcrumbsMessages>;
7
+ export declare const searchBreadcrumbsDefaultMessages: DefaultI18nMessages<SearchBreadcrumbsMessages>;
@@ -0,0 +1,6 @@
1
+ import { I18nMessageContext, } from "@fluid-topics/ft-i18n/build/generator/I18nMessageContext";
2
+ export const searchBreadcrumbsContext = I18nMessageContext.build("searchBreadcrumbsComponent");
3
+ export const searchBreadcrumbsDefaultMessages = {
4
+ olAriaLabel: "Breadcrumb",
5
+ menuShowMore: "Show more",
6
+ };
@@ -0,0 +1,44 @@
1
+ import { PropertyValues } from "lit";
2
+ import { ElementDefinitionsMap } from "@fluid-topics/ft-wc-utils";
3
+ import { FtSearchBreadcrumbsProperties } from "./ft-search-breadcrumbs.properties";
4
+ import { FtSearchResultComponent } from "@fluid-topics/ft-search-result-context/build/registration";
5
+ import { FtSearchResultClusterEntry } from "@fluid-topics/public-api";
6
+ interface FtSearchBreadcrumbsProperty {
7
+ id?: string;
8
+ breadcrumb: Array<string>;
9
+ result: FtSearchResultClusterEntry;
10
+ }
11
+ declare const FtSearchBreadcrumbs_base: typeof FtSearchResultComponent & import("@fluid-topics/ft-wc-utils").Constructor<import("@fluid-topics/ft-i18n").FtLitElementWithI18nInterface>;
12
+ export declare class FtSearchBreadcrumbs extends FtSearchBreadcrumbs_base implements FtSearchBreadcrumbsProperties {
13
+ static elementDefinitions: ElementDefinitionsMap;
14
+ static styles: import("lit").CSSResult;
15
+ separator: string;
16
+ multiline?: boolean;
17
+ truncate?: boolean;
18
+ truncateThreshold?: number;
19
+ truncateStartOffset?: number;
20
+ truncateEndOffset?: number;
21
+ useAsClusterSwitch: boolean;
22
+ goToDocumentOnSwitch: boolean;
23
+ private breadcrumbs;
24
+ private selectedBreadcrumbId?;
25
+ constructor();
26
+ get hasMultiBreadcrumbs(): boolean;
27
+ get selectedBreadcrumb(): FtSearchBreadcrumbsProperty | undefined;
28
+ protected buildArrayBreadcrumbs(): void;
29
+ protected willUpdate(props: PropertyValues): void;
30
+ protected onBreadcrumbSelected(e: CustomEvent): void;
31
+ protected render(): import("lit-html").TemplateResult<1>;
32
+ private renderBreadcrumb;
33
+ private renderSplitBreadcrumb;
34
+ private renderBreadcrumbItems;
35
+ private renderTruncateBreadcrumb;
36
+ private renderBreadcrumbItem;
37
+ private renderSelectBreadcrumb;
38
+ private renderBreadcrumbMenu;
39
+ private onResultClick;
40
+ private onAuxClick;
41
+ private onContextMenu;
42
+ private renderSeparator;
43
+ }
44
+ export {};
@@ -0,0 +1,202 @@
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 { html, nothing, } from "lit";
8
+ import { property, state, } from "lit/decorators.js";
9
+ import { repeat } from "lit/directives/repeat.js";
10
+ import { when } from "lit/directives/when.js";
11
+ import { classMap } from "lit/directives/class-map.js";
12
+ import { accessBreadcrumb, accessResultId, numberProperty, } from "@fluid-topics/ft-wc-utils";
13
+ import { styles } from "./ft-search-breadcrumbs.styles";
14
+ import { FtTypography, FtTypographyVariants, } from "@fluid-topics/ft-typography";
15
+ import { withI18n } from "@fluid-topics/ft-i18n";
16
+ import { searchBreadcrumbsContext, searchBreadcrumbsDefaultMessages, } from "./SearchBreadcrumbsMessages";
17
+ import { FtRipple } from "@fluid-topics/ft-ripple";
18
+ import { FtSearchResultComponent } from "@fluid-topics/ft-search-result-context/build/registration";
19
+ import { FtSelect, FtSelectOption, } from "@fluid-topics/ft-select";
20
+ import { getResultUrl } from "@fluid-topics/ft-search-result-context/build/utils";
21
+ import { SearchResultClickEvent, SearchResultOpenContextMenuEvent, } from "@fluid-topics/ft-search-context/build/utils";
22
+ import { splitBreadcrumbForMenu } from "@fluid-topics/ft-reader-breadcrumbs/build/helpers/FtReaderBreadcrumbsMenuHelper";
23
+ class FtSearchBreadcrumbs extends withI18n(FtSearchResultComponent) {
24
+ constructor() {
25
+ super();
26
+ this.separator = ">";
27
+ this.useAsClusterSwitch = false;
28
+ this.goToDocumentOnSwitch = false;
29
+ this.breadcrumbs = [];
30
+ this.addI18nContext(searchBreadcrumbsContext, searchBreadcrumbsDefaultMessages);
31
+ }
32
+ get hasMultiBreadcrumbs() {
33
+ return this.breadcrumbs.length > 1 && this.useAsClusterSwitch;
34
+ }
35
+ get selectedBreadcrumb() {
36
+ return this.breadcrumbs.find((b) => b.id === this.selectedBreadcrumbId);
37
+ }
38
+ buildArrayBreadcrumbs() {
39
+ const newBreadcrumbs = [];
40
+ if (this.cluster) {
41
+ this.cluster.entries.forEach((entry) => {
42
+ newBreadcrumbs.push({ id: accessResultId(entry), breadcrumb: accessBreadcrumb(entry), result: entry });
43
+ });
44
+ }
45
+ this.breadcrumbs = newBreadcrumbs;
46
+ this.selectedBreadcrumbId = accessResultId(this.result);
47
+ }
48
+ willUpdate(props) {
49
+ super.willUpdate(props);
50
+ this.buildArrayBreadcrumbs();
51
+ }
52
+ onBreadcrumbSelected(e) {
53
+ var _a, _b;
54
+ e.stopPropagation();
55
+ this.selectedBreadcrumbId = e.detail;
56
+ const resultSelected = (_a = this.selectedBreadcrumb) === null || _a === void 0 ? void 0 : _a.result;
57
+ if (resultSelected) {
58
+ (_b = this.resultStateManager) === null || _b === void 0 ? void 0 : _b.selectResult(resultSelected);
59
+ }
60
+ }
61
+ render() {
62
+ return html `
63
+ ${when(this.hasMultiBreadcrumbs, () => this.renderSelectBreadcrumb(), () => when(this.breadcrumbs.length > 0, () => this.renderBreadcrumb(this.breadcrumbs[0])))}
64
+ `;
65
+ }
66
+ renderBreadcrumb(breadcrumb, slot) {
67
+ const cssClasses = {
68
+ "ft-search-breadcrumbs": true,
69
+ "multiline": !!this.multiline,
70
+ };
71
+ return html `
72
+ <ol slot="${slot}" part="breadcrumb-list" class="${classMap(cssClasses)}" aria-label="${searchBreadcrumbsContext.messages.olAriaLabel()}">
73
+ ${this.renderSplitBreadcrumb(breadcrumb)}
74
+ </ol>`;
75
+ }
76
+ renderSplitBreadcrumb(breadcrumbs) {
77
+ var _a;
78
+ if (!this.truncate || breadcrumbs.breadcrumb.length < ((_a = this.truncateThreshold) !== null && _a !== void 0 ? _a : 0)) {
79
+ return this.renderBreadcrumbItems(breadcrumbs.breadcrumb);
80
+ }
81
+ const splitBreadcrumbs = splitBreadcrumbForMenu(breadcrumbs.breadcrumb, this.truncateStartOffset, this.truncateEndOffset);
82
+ return html `
83
+ ${this.renderBreadcrumbItems(splitBreadcrumbs.beforeMenu)}
84
+ ${splitBreadcrumbs.beforeMenu.length > 0 ? this.renderSeparator() : nothing}
85
+ ${when(splitBreadcrumbs.inMenu.length > 0, () => this.renderTruncateBreadcrumb())}
86
+ ${this.renderBreadcrumbItems(splitBreadcrumbs.afterMenu)}`;
87
+ }
88
+ renderBreadcrumbItems(breadcrumbItems) {
89
+ return repeat(breadcrumbItems, (breadcrumbItem, index) => {
90
+ const isLastElement = index === breadcrumbItems.length - 1;
91
+ return html `
92
+ ${this.renderBreadcrumbItem(breadcrumbItem, breadcrumbItem, isLastElement)}
93
+ ${isLastElement ? nothing : this.renderSeparator()}`;
94
+ });
95
+ }
96
+ renderTruncateBreadcrumb() {
97
+ return html `
98
+ ${this.renderBreadcrumbItem("...", undefined)}
99
+ ${this.renderSeparator()}`;
100
+ }
101
+ renderBreadcrumbItem(item, title, isCurrent = false) {
102
+ return html `
103
+ <li>
104
+ <ft-typography
105
+ title="${title}"
106
+ part="${isCurrent ? "breadcrumb-current-item" : "breadcrumb-label"}"
107
+ variant="${FtTypographyVariants.body2}"
108
+ ?aria-current=${isCurrent ? "page" : undefined}>
109
+ ${item}
110
+ </ft-typography>
111
+ </li>`;
112
+ }
113
+ renderSelectBreadcrumb() {
114
+ var _a;
115
+ const selectedBreadcrumb = (_a = this.selectedBreadcrumb) !== null && _a !== void 0 ? _a : this.breadcrumbs[0];
116
+ return html `
117
+ <ft-select
118
+ outlined
119
+ @change=${this.onBreadcrumbSelected}
120
+ >
121
+ ${this.renderBreadcrumb(selectedBreadcrumb, "input-value")}
122
+ ${repeat(this.breadcrumbs, (item) => item.id, (item) => this.renderBreadcrumbMenu(item))}
123
+ </ft-select>`;
124
+ }
125
+ renderBreadcrumbMenu(item) {
126
+ if (this.selectedBreadcrumbId === item.id) {
127
+ return nothing;
128
+ }
129
+ return when(this.goToDocumentOnSwitch, () => html `
130
+ <a href="${getResultUrl(item.result)}" @click=${() => this.onResultClick(item.result)}
131
+ @auxclick=${(e) => this.onAuxClick(e, item.result)}
132
+ @contextmenu=${() => this.onContextMenu(item.result)}>
133
+ ${this.renderBreadcrumb(item)}
134
+ </a>`, () => {
135
+ var _a;
136
+ return html `
137
+ <ft-select-option
138
+ value="${(_a = item.id) !== null && _a !== void 0 ? _a : "ft:no_value"}"
139
+ >
140
+ ${this.renderBreadcrumb(item)}
141
+ </ft-select-option>
142
+ `;
143
+ });
144
+ }
145
+ onResultClick(result) {
146
+ this.dispatchEvent(new SearchResultClickEvent(result, this.rank));
147
+ }
148
+ onAuxClick(e, result) {
149
+ if (e.button == 1) {
150
+ this.onResultClick(result);
151
+ }
152
+ }
153
+ onContextMenu(result) {
154
+ this.dispatchEvent(new SearchResultOpenContextMenuEvent(result, this.rank));
155
+ }
156
+ renderSeparator() {
157
+ return html `
158
+ <li part="breadcrumb-separator" class="separator" aria-hidden="true">
159
+ <ft-typography element="span" variant="${FtTypographyVariants.body2}">
160
+ ${this.separator}
161
+ </ft-typography>
162
+ </li>`;
163
+ }
164
+ }
165
+ FtSearchBreadcrumbs.elementDefinitions = {
166
+ "ft-typography": FtTypography,
167
+ "ft-ripple": FtRipple,
168
+ "ft-select": FtSelect,
169
+ "ft-select-option": FtSelectOption,
170
+ };
171
+ FtSearchBreadcrumbs.styles = styles;
172
+ __decorate([
173
+ property()
174
+ ], FtSearchBreadcrumbs.prototype, "separator", void 0);
175
+ __decorate([
176
+ property({ type: Boolean })
177
+ ], FtSearchBreadcrumbs.prototype, "multiline", void 0);
178
+ __decorate([
179
+ property({ type: Boolean })
180
+ ], FtSearchBreadcrumbs.prototype, "truncate", void 0);
181
+ __decorate([
182
+ numberProperty()
183
+ ], FtSearchBreadcrumbs.prototype, "truncateThreshold", void 0);
184
+ __decorate([
185
+ numberProperty()
186
+ ], FtSearchBreadcrumbs.prototype, "truncateStartOffset", void 0);
187
+ __decorate([
188
+ numberProperty()
189
+ ], FtSearchBreadcrumbs.prototype, "truncateEndOffset", void 0);
190
+ __decorate([
191
+ property({ type: Boolean })
192
+ ], FtSearchBreadcrumbs.prototype, "useAsClusterSwitch", void 0);
193
+ __decorate([
194
+ property({ type: Boolean })
195
+ ], FtSearchBreadcrumbs.prototype, "goToDocumentOnSwitch", void 0);
196
+ __decorate([
197
+ state()
198
+ ], FtSearchBreadcrumbs.prototype, "breadcrumbs", void 0);
199
+ __decorate([
200
+ state()
201
+ ], FtSearchBreadcrumbs.prototype, "selectedBreadcrumbId", void 0);
202
+ export { FtSearchBreadcrumbs };