@cloudflare/ai-search-snippet 0.0.17 → 0.0.21
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 +5 -4
- package/dist/favicon.ico +0 -0
- package/dist/main.d.ts +6 -5
- package/dist/search-snippet.es.js +84 -62
- package/dist/search-snippet.es.js.map +1 -1
- package/dist/search-snippet.umd.js +48 -40
- package/dist/search-snippet.umd.js.map +1 -1
- package/package.json +11 -10
package/README.md
CHANGED
|
@@ -97,10 +97,11 @@ These attributes are available on all components:
|
|
|
97
97
|
|
|
98
98
|
Additional attributes for `<search-bar-snippet>` and `<search-modal-snippet>`:
|
|
99
99
|
|
|
100
|
-
| Attribute | Type
|
|
101
|
-
| ------------- |
|
|
102
|
-
| `max-results` | number
|
|
103
|
-
| `debounce-ms` | number
|
|
100
|
+
| Attribute | Type | Default | Description |
|
|
101
|
+
| ------------- | ------- | ------- | ------------------------------------ |
|
|
102
|
+
| `max-results` | number | `10` | Maximum search results to display |
|
|
103
|
+
| `debounce-ms` | number | `300` | Input debounce delay in milliseconds |
|
|
104
|
+
| `show-url` | boolean | `false` | Show URL in search results |
|
|
104
105
|
|
|
105
106
|
### Modal-Specific Attributes
|
|
106
107
|
|
package/dist/favicon.ico
ADDED
|
Binary file
|
package/dist/main.d.ts
CHANGED
|
@@ -198,14 +198,13 @@ declare class SearchBarSnippet extends HTMLElement {
|
|
|
198
198
|
private inputElement;
|
|
199
199
|
private resultsContainer;
|
|
200
200
|
private searchButton;
|
|
201
|
-
private isLoading;
|
|
202
|
-
private currentQuery;
|
|
203
201
|
private debouncedSearch;
|
|
202
|
+
private currentSearchController;
|
|
204
203
|
private handleInputChange;
|
|
205
204
|
private handleInputKeydownEnter;
|
|
206
205
|
private handleInputKeydownEscape;
|
|
207
206
|
private handleSearchButtonClick;
|
|
208
|
-
static get observedAttributes(): readonly ["api-url", "placeholder", "max-results", "debounce-ms", "theme", "hide-branding"];
|
|
207
|
+
static get observedAttributes(): readonly ["api-url", "placeholder", "max-results", "debounce-ms", "theme", "hide-branding", "show-url"];
|
|
209
208
|
constructor();
|
|
210
209
|
connectedCallback(): void;
|
|
211
210
|
disconnectedCallback(): void;
|
|
@@ -247,17 +246,17 @@ export declare class SearchModalSnippet extends HTMLElement {
|
|
|
247
246
|
private resultsContainer;
|
|
248
247
|
private footerCount;
|
|
249
248
|
private isOpen;
|
|
250
|
-
private isLoading;
|
|
251
249
|
private results;
|
|
252
250
|
private activeIndex;
|
|
253
251
|
private debouncedSearch;
|
|
252
|
+
private currentSearchController;
|
|
254
253
|
private handleGlobalKeydown;
|
|
255
254
|
private handleInputChange;
|
|
256
255
|
private handleInputKeydown;
|
|
257
256
|
private handleBackdropClick;
|
|
258
257
|
private savedBodyStyles;
|
|
259
258
|
private savedHtmlOverflow;
|
|
260
|
-
static get observedAttributes(): readonly ["api-url", "placeholder", "max-results", "theme", "shortcut", "use-meta-key", "debounce-ms", "hide-branding"];
|
|
259
|
+
static get observedAttributes(): readonly ["api-url", "placeholder", "max-results", "theme", "shortcut", "use-meta-key", "debounce-ms", "hide-branding", "show-url"];
|
|
261
260
|
constructor();
|
|
262
261
|
connectedCallback(): void;
|
|
263
262
|
disconnectedCallback(): void;
|
|
@@ -349,6 +348,8 @@ export declare interface SearchSnippetProps {
|
|
|
349
348
|
theme?: Theme;
|
|
350
349
|
/** Hide the "Powered by Cloudflare AI Search" branding */
|
|
351
350
|
hideBranding?: boolean;
|
|
351
|
+
/** Show URL in search results (default: false) */
|
|
352
|
+
showUrl?: boolean;
|
|
352
353
|
}
|
|
353
354
|
|
|
354
355
|
/**
|
|
@@ -42,10 +42,10 @@ function S(o = "id") {
|
|
|
42
42
|
function u(o, i) {
|
|
43
43
|
return o !== null ? o : i;
|
|
44
44
|
}
|
|
45
|
-
function
|
|
45
|
+
function v(o, i) {
|
|
46
46
|
return o === null ? i : o === "true" || o === "";
|
|
47
47
|
}
|
|
48
|
-
function
|
|
48
|
+
function f(o, i) {
|
|
49
49
|
if (o === null) return i;
|
|
50
50
|
const e = Number.parseInt(o, 10);
|
|
51
51
|
return Number.isNaN(e) ? i : e;
|
|
@@ -132,7 +132,7 @@ class P extends N {
|
|
|
132
132
|
type: "result",
|
|
133
133
|
id: d.id,
|
|
134
134
|
title: C(d.item.metadata.title),
|
|
135
|
-
description: C(d.item.metadata.description),
|
|
135
|
+
description: d.item.metadata.description ? C(d.item.metadata.description) : "",
|
|
136
136
|
url: d.item.key,
|
|
137
137
|
image: d.item.metadata.image || void 0,
|
|
138
138
|
metadata: d.item.metadata
|
|
@@ -556,6 +556,7 @@ const $ = `
|
|
|
556
556
|
--search-snippet-surface: #f8f9fa;
|
|
557
557
|
--search-snippet-text-color: #212529;
|
|
558
558
|
--search-snippet-text-secondary: #6c757d;
|
|
559
|
+
--search-snippet-text-description: #495057;
|
|
559
560
|
--search-snippet-border-color: #dee2e6;
|
|
560
561
|
--search-snippet-hover-background: #f1f3f5;
|
|
561
562
|
--search-snippet-focus-ring: #0066cc40;
|
|
@@ -667,6 +668,7 @@ const $ = `
|
|
|
667
668
|
--search-snippet-surface: #f8f9fa;
|
|
668
669
|
--search-snippet-text-color: #212529;
|
|
669
670
|
--search-snippet-text-secondary: #6c757d;
|
|
671
|
+
--search-snippet-text-description: #495057;
|
|
670
672
|
--search-snippet-border-color: #dee2e6;
|
|
671
673
|
--search-snippet-hover-background: #f1f3f5;
|
|
672
674
|
--search-snippet-focus-ring: #0066cc40;
|
|
@@ -695,6 +697,7 @@ const $ = `
|
|
|
695
697
|
--search-snippet-surface: #25262b;
|
|
696
698
|
--search-snippet-text-color: #c1c2c5;
|
|
697
699
|
--search-snippet-text-secondary: #909296;
|
|
700
|
+
--search-snippet-text-description: #adb5bd;
|
|
698
701
|
--search-snippet-border-color: #373a40;
|
|
699
702
|
--search-snippet-hover-background: #2c2e33;
|
|
700
703
|
--search-snippet-focus-ring: #4dabf740;
|
|
@@ -971,7 +974,7 @@ function V(o) {
|
|
|
971
974
|
const c = e[n], h = c.match(/^(#{1,6})\s+(.+)$/);
|
|
972
975
|
if (h) {
|
|
973
976
|
const p = h[1].length, k = h[2];
|
|
974
|
-
t.push(`<h${p}>${
|
|
977
|
+
t.push(`<h${p}>${b(k)}</h${p}>`);
|
|
975
978
|
continue;
|
|
976
979
|
}
|
|
977
980
|
if (c.match(/^---+$/)) {
|
|
@@ -980,29 +983,29 @@ function V(o) {
|
|
|
980
983
|
}
|
|
981
984
|
if (c.match(/^>\s+/)) {
|
|
982
985
|
const p = c.replace(/^>\s+/, "");
|
|
983
|
-
t.push(`<blockquote>${
|
|
986
|
+
t.push(`<blockquote>${b(p)}</blockquote>`);
|
|
984
987
|
continue;
|
|
985
988
|
}
|
|
986
989
|
const d = c.match(/^[-*]\s+(.+)$/);
|
|
987
990
|
if (d) {
|
|
988
|
-
(!s || a !== "ul") && (s && t.push(`</${a}>`), t.push("<ul>"), s = !0, a = "ul"), t.push(`<li>${
|
|
991
|
+
(!s || a !== "ul") && (s && t.push(`</${a}>`), t.push("<ul>"), s = !0, a = "ul"), t.push(`<li>${b(d[1])}</li>`);
|
|
989
992
|
continue;
|
|
990
993
|
}
|
|
991
994
|
const g = c.match(/^\d+\.\s+(.+)$/);
|
|
992
995
|
if (g) {
|
|
993
|
-
(!s || a !== "ol") && (s && t.push(`</${a}>`), t.push("<ol>"), s = !0, a = "ol"), t.push(`<li>${
|
|
996
|
+
(!s || a !== "ol") && (s && t.push(`</${a}>`), t.push("<ol>"), s = !0, a = "ol"), t.push(`<li>${b(g[1])}</li>`);
|
|
994
997
|
continue;
|
|
995
998
|
}
|
|
996
999
|
if (s && (t.push(`</${a}>`), s = !1, a = ""), c.trim() === "") {
|
|
997
1000
|
t.push("<br />");
|
|
998
1001
|
continue;
|
|
999
1002
|
}
|
|
1000
|
-
t.push(`<p>${
|
|
1003
|
+
t.push(`<p>${b(c)}</p>`);
|
|
1001
1004
|
}
|
|
1002
1005
|
return s && t.push(`</${a}>`), t.join(`
|
|
1003
1006
|
`);
|
|
1004
1007
|
}
|
|
1005
|
-
function
|
|
1008
|
+
function b(o) {
|
|
1006
1009
|
let i = o;
|
|
1007
1010
|
return i = i.replace(/`([^`]+)`/g, "<code>$1</code>"), i = i.replace(/\*\*\*(.+?)\*\*\*/g, "<strong><em>$1</em></strong>"), i = i.replace(/___(.+?)___/g, "<strong><em>$1</em></strong>"), i = i.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>"), i = i.replace(/__(.+?)__/g, "<strong>$1</strong>"), i = i.replace(/\*(.+?)\*/g, "<em>$1</em>"), i = i.replace(/_(.+?)_/g, "<em>$1</em>"), i = i.replace(
|
|
1008
1011
|
/\[([^\]]+)\]\(([^)]+)\)/g,
|
|
@@ -1271,7 +1274,7 @@ class O extends HTMLElement {
|
|
|
1271
1274
|
apiUrl: u(this.getAttribute("api-url"), "http://localhost:3000"),
|
|
1272
1275
|
placeholder: u(this.getAttribute("placeholder"), "Type a message..."),
|
|
1273
1276
|
theme: u(this.getAttribute("theme"), "auto"),
|
|
1274
|
-
hideBranding:
|
|
1277
|
+
hideBranding: v(this.getAttribute("hide-branding"), !1)
|
|
1275
1278
|
};
|
|
1276
1279
|
}
|
|
1277
1280
|
initializeClient() {
|
|
@@ -1557,7 +1560,7 @@ class D extends HTMLElement {
|
|
|
1557
1560
|
apiUrl: u(this.getAttribute("api-url"), "http://localhost:3000"),
|
|
1558
1561
|
placeholder: u(this.getAttribute("placeholder"), "Type a message..."),
|
|
1559
1562
|
theme: u(this.getAttribute("theme"), "auto"),
|
|
1560
|
-
hideBranding:
|
|
1563
|
+
hideBranding: v(this.getAttribute("hide-branding"), !1)
|
|
1561
1564
|
};
|
|
1562
1565
|
}
|
|
1563
1566
|
initializeClient() {
|
|
@@ -2189,7 +2192,7 @@ const U = `
|
|
|
2189
2192
|
gap: var(--search-snippet-spacing-sm);
|
|
2190
2193
|
}
|
|
2191
2194
|
|
|
2192
|
-
.search-result-item {
|
|
2195
|
+
a.search-result-item {
|
|
2193
2196
|
display: flex;
|
|
2194
2197
|
flex-direction: row;
|
|
2195
2198
|
align-items: flex-start;
|
|
@@ -2200,6 +2203,8 @@ const U = `
|
|
|
2200
2203
|
border-radius: var(--search-snippet-border-radius);
|
|
2201
2204
|
cursor: pointer;
|
|
2202
2205
|
transition: var(--search-snippet-transition);
|
|
2206
|
+
text-decoration: none;
|
|
2207
|
+
color: inherit;
|
|
2203
2208
|
}
|
|
2204
2209
|
|
|
2205
2210
|
/* Image thumbnail container */
|
|
@@ -2267,14 +2272,14 @@ const U = `
|
|
|
2267
2272
|
min-width: 0;
|
|
2268
2273
|
}
|
|
2269
2274
|
|
|
2270
|
-
.search-result-item:hover {
|
|
2275
|
+
a.search-result-item:hover {
|
|
2271
2276
|
background: var(--search-snippet-hover-background);
|
|
2272
2277
|
border-color: var(--search-snippet-primary-color);
|
|
2273
2278
|
transform: translateY(-1px);
|
|
2274
2279
|
box-shadow: var(--search-snippet-result-item-shadow);
|
|
2275
2280
|
}
|
|
2276
2281
|
|
|
2277
|
-
.search-result-item:focus-visible {
|
|
2282
|
+
a.search-result-item:focus-visible {
|
|
2278
2283
|
outline: 2px solid var(--search-snippet-primary-color);
|
|
2279
2284
|
outline-offset: 2px;
|
|
2280
2285
|
}
|
|
@@ -2292,7 +2297,7 @@ const U = `
|
|
|
2292
2297
|
|
|
2293
2298
|
.search-result-snippet {
|
|
2294
2299
|
font-size: var(--search-snippet-font-size-sm);
|
|
2295
|
-
color: var(--search-snippet-text-
|
|
2300
|
+
color: var(--search-snippet-text-description);
|
|
2296
2301
|
line-height: 1.6;
|
|
2297
2302
|
display: -webkit-box;
|
|
2298
2303
|
-webkit-line-clamp: 3;
|
|
@@ -2394,9 +2399,8 @@ class F extends HTMLElement {
|
|
|
2394
2399
|
r(this, "inputElement", null);
|
|
2395
2400
|
r(this, "resultsContainer", null);
|
|
2396
2401
|
r(this, "searchButton", null);
|
|
2397
|
-
r(this, "isLoading", !1);
|
|
2398
|
-
r(this, "currentQuery", "");
|
|
2399
2402
|
r(this, "debouncedSearch", null);
|
|
2403
|
+
r(this, "currentSearchController", null);
|
|
2400
2404
|
// Event handler references for cleanup
|
|
2401
2405
|
r(this, "handleInputChange", null);
|
|
2402
2406
|
r(this, "handleInputKeydownEnter", null);
|
|
@@ -2411,7 +2415,8 @@ class F extends HTMLElement {
|
|
|
2411
2415
|
"max-results",
|
|
2412
2416
|
"debounce-ms",
|
|
2413
2417
|
"theme",
|
|
2414
|
-
"hide-branding"
|
|
2418
|
+
"hide-branding",
|
|
2419
|
+
"show-url"
|
|
2415
2420
|
];
|
|
2416
2421
|
}
|
|
2417
2422
|
connectedCallback() {
|
|
@@ -2427,10 +2432,11 @@ class F extends HTMLElement {
|
|
|
2427
2432
|
return {
|
|
2428
2433
|
apiUrl: u(this.getAttribute("api-url"), "http://localhost:3000"),
|
|
2429
2434
|
placeholder: u(this.getAttribute("placeholder"), "Search..."),
|
|
2430
|
-
maxResults:
|
|
2431
|
-
debounceMs:
|
|
2435
|
+
maxResults: f(this.getAttribute("max-results"), 10),
|
|
2436
|
+
debounceMs: f(this.getAttribute("debounce-ms"), 300),
|
|
2432
2437
|
theme: u(this.getAttribute("theme"), "auto"),
|
|
2433
|
-
hideBranding:
|
|
2438
|
+
hideBranding: v(this.getAttribute("hide-branding"), !1),
|
|
2439
|
+
showUrl: v(this.getAttribute("show-url"), !1)
|
|
2434
2440
|
};
|
|
2435
2441
|
}
|
|
2436
2442
|
initializeClient() {
|
|
@@ -2494,15 +2500,20 @@ ${U}`, this.container = document.createElement("div"), this.container.className
|
|
|
2494
2500
|
}, this.searchButton.addEventListener("click", this.handleSearchButtonClick)));
|
|
2495
2501
|
}
|
|
2496
2502
|
async performSearch(e) {
|
|
2497
|
-
if (
|
|
2498
|
-
this.
|
|
2503
|
+
if (this.client) {
|
|
2504
|
+
this.currentSearchController && (this.currentSearchController.abort(), this.currentSearchController = null), this.currentSearchController = new AbortController(), this.showLoadingState();
|
|
2499
2505
|
try {
|
|
2500
|
-
const t = await this.client.search(e, {
|
|
2506
|
+
const t = await this.client.search(e, {
|
|
2507
|
+
streaming: !1,
|
|
2508
|
+
signal: this.currentSearchController.signal
|
|
2509
|
+
});
|
|
2501
2510
|
this.displayResults(t, e);
|
|
2502
2511
|
} catch (t) {
|
|
2512
|
+
if (t.name === "AbortError")
|
|
2513
|
+
return;
|
|
2503
2514
|
this.showErrorState(t.message);
|
|
2504
2515
|
} finally {
|
|
2505
|
-
this.
|
|
2516
|
+
this.currentSearchController = null;
|
|
2506
2517
|
}
|
|
2507
2518
|
}
|
|
2508
2519
|
}
|
|
@@ -2526,16 +2537,16 @@ ${U}`, this.container = document.createElement("div"), this.container.className
|
|
|
2526
2537
|
this.resultsContainer.innerHTML = n, this.attachResultHandlers();
|
|
2527
2538
|
}
|
|
2528
2539
|
renderResult(e) {
|
|
2529
|
-
const t = this.renderResultImage(e.image, e.title);
|
|
2540
|
+
const t = this.getProps(), s = this.renderResultImage(e.image, e.title);
|
|
2530
2541
|
return `
|
|
2531
|
-
<
|
|
2532
|
-
${
|
|
2542
|
+
<a href="${e.url ? l(e.url) : "#"}" class="search-result-item" data-result-id="${l(e.url || "")}">
|
|
2543
|
+
${s}
|
|
2533
2544
|
<div class="search-result-content">
|
|
2534
2545
|
<div class="search-result-title">${l(e.title || "")}</div>
|
|
2535
2546
|
<div class="search-result-snippet">${l(e.description || "")}</div>
|
|
2536
|
-
${e.url ? `<
|
|
2547
|
+
${t.showUrl && e.url ? `<span class="search-result-url">${l(e.url)}</span>` : ""}
|
|
2537
2548
|
</div>
|
|
2538
|
-
</
|
|
2549
|
+
</a>
|
|
2539
2550
|
`;
|
|
2540
2551
|
}
|
|
2541
2552
|
renderResultImage(e, t) {
|
|
@@ -2561,11 +2572,8 @@ ${U}`, this.container = document.createElement("div"), this.container.className
|
|
|
2561
2572
|
const e = this.container?.querySelectorAll(".search-result-item");
|
|
2562
2573
|
if (!e) return;
|
|
2563
2574
|
for (const s of e)
|
|
2564
|
-
s.addEventListener("click", () => {
|
|
2565
|
-
|
|
2566
|
-
console.log("Result clicked:", a);
|
|
2567
|
-
}), s.addEventListener("keydown", (a) => {
|
|
2568
|
-
(a.key === "Enter" || a.key === " ") && s.click();
|
|
2575
|
+
s.getAttribute("href") === "#" && s.addEventListener("click", (n) => {
|
|
2576
|
+
n.preventDefault();
|
|
2569
2577
|
});
|
|
2570
2578
|
this.container?.querySelectorAll(".search-result-image")?.forEach((s) => {
|
|
2571
2579
|
s.addEventListener("load", () => {
|
|
@@ -2628,7 +2636,7 @@ ${U}`, this.container = document.createElement("div"), this.container.className
|
|
|
2628
2636
|
t === "auto" ? this.removeAttribute("theme") : this.setAttribute("theme", t);
|
|
2629
2637
|
}
|
|
2630
2638
|
cleanup() {
|
|
2631
|
-
this.client && this.client.cancelAllRequests(), this.inputElement && (this.handleInputChange && this.inputElement.removeEventListener("input", this.handleInputChange), this.handleInputKeydownEnter && this.inputElement.removeEventListener("keydown", this.handleInputKeydownEnter), this.handleInputKeydownEscape && window.removeEventListener("keydown", this.handleInputKeydownEscape)), this.searchButton && this.handleSearchButtonClick && this.searchButton.removeEventListener("click", this.handleSearchButtonClick), this.handleInputChange = null, this.handleInputKeydownEnter = null, this.handleInputKeydownEscape = null, this.handleSearchButtonClick = null;
|
|
2639
|
+
this.currentSearchController && (this.currentSearchController.abort(), this.currentSearchController = null), this.client && this.client.cancelAllRequests(), this.inputElement && (this.handleInputChange && this.inputElement.removeEventListener("input", this.handleInputChange), this.handleInputKeydownEnter && this.inputElement.removeEventListener("keydown", this.handleInputKeydownEnter), this.handleInputKeydownEscape && window.removeEventListener("keydown", this.handleInputKeydownEscape)), this.searchButton && this.handleSearchButtonClick && this.searchButton.removeEventListener("click", this.handleSearchButtonClick), this.handleInputChange = null, this.handleInputKeydownEnter = null, this.handleInputKeydownEscape = null, this.handleSearchButtonClick = null;
|
|
2632
2640
|
}
|
|
2633
2641
|
// Public API
|
|
2634
2642
|
async search(e) {
|
|
@@ -2771,7 +2779,7 @@ const G = `
|
|
|
2771
2779
|
gap: var(--search-snippet-spacing-xs);
|
|
2772
2780
|
}
|
|
2773
2781
|
|
|
2774
|
-
.modal-result-item {
|
|
2782
|
+
a.modal-result-item {
|
|
2775
2783
|
padding: var(--search-snippet-spacing-md);
|
|
2776
2784
|
background: transparent;
|
|
2777
2785
|
border: var(--search-snippet-border-width) solid transparent;
|
|
@@ -2782,6 +2790,8 @@ const G = `
|
|
|
2782
2790
|
flex-direction: row;
|
|
2783
2791
|
align-items: flex-start;
|
|
2784
2792
|
gap: var(--search-snippet-spacing-md);
|
|
2793
|
+
text-decoration: none;
|
|
2794
|
+
color: inherit;
|
|
2785
2795
|
}
|
|
2786
2796
|
|
|
2787
2797
|
/* Image thumbnail container */
|
|
@@ -2852,18 +2862,18 @@ const G = `
|
|
|
2852
2862
|
gap: var(--search-snippet-spacing-xs);
|
|
2853
2863
|
}
|
|
2854
2864
|
|
|
2855
|
-
.modal-result-item:hover,
|
|
2856
|
-
.modal-result-item.active {
|
|
2865
|
+
a.modal-result-item:hover,
|
|
2866
|
+
a.modal-result-item.active {
|
|
2857
2867
|
background: var(--search-snippet-hover-background);
|
|
2858
2868
|
border-color: var(--search-snippet-border-color);
|
|
2859
2869
|
}
|
|
2860
2870
|
|
|
2861
|
-
.modal-result-item.active {
|
|
2871
|
+
a.modal-result-item.active {
|
|
2862
2872
|
border-color: var(--search-snippet-primary-color);
|
|
2863
2873
|
background: var(--search-snippet-focus-ring);
|
|
2864
2874
|
}
|
|
2865
2875
|
|
|
2866
|
-
.modal-result-item:focus-visible {
|
|
2876
|
+
a.modal-result-item:focus-visible {
|
|
2867
2877
|
outline: 2px solid var(--search-snippet-primary-color);
|
|
2868
2878
|
outline-offset: -2px;
|
|
2869
2879
|
}
|
|
@@ -2880,7 +2890,7 @@ const G = `
|
|
|
2880
2890
|
|
|
2881
2891
|
.modal-result-description {
|
|
2882
2892
|
font-size: var(--search-snippet-font-size-sm);
|
|
2883
|
-
color: var(--search-snippet-text-
|
|
2893
|
+
color: var(--search-snippet-text-description);
|
|
2884
2894
|
line-height: 1.5;
|
|
2885
2895
|
display: -webkit-box;
|
|
2886
2896
|
-webkit-line-clamp: 2;
|
|
@@ -3045,10 +3055,10 @@ class Y extends HTMLElement {
|
|
|
3045
3055
|
r(this, "resultsContainer", null);
|
|
3046
3056
|
r(this, "footerCount", null);
|
|
3047
3057
|
r(this, "isOpen", !1);
|
|
3048
|
-
r(this, "isLoading", !1);
|
|
3049
3058
|
r(this, "results", []);
|
|
3050
3059
|
r(this, "activeIndex", -1);
|
|
3051
3060
|
r(this, "debouncedSearch", null);
|
|
3061
|
+
r(this, "currentSearchController", null);
|
|
3052
3062
|
// Event handler references for cleanup
|
|
3053
3063
|
r(this, "handleGlobalKeydown", null);
|
|
3054
3064
|
r(this, "handleInputChange", null);
|
|
@@ -3068,7 +3078,8 @@ class Y extends HTMLElement {
|
|
|
3068
3078
|
"shortcut",
|
|
3069
3079
|
"use-meta-key",
|
|
3070
3080
|
"debounce-ms",
|
|
3071
|
-
"hide-branding"
|
|
3081
|
+
"hide-branding",
|
|
3082
|
+
"show-url"
|
|
3072
3083
|
];
|
|
3073
3084
|
}
|
|
3074
3085
|
connectedCallback() {
|
|
@@ -3084,12 +3095,13 @@ class Y extends HTMLElement {
|
|
|
3084
3095
|
return {
|
|
3085
3096
|
apiUrl: u(this.getAttribute("api-url"), "http://localhost:3000"),
|
|
3086
3097
|
placeholder: u(this.getAttribute("placeholder"), "Search..."),
|
|
3087
|
-
maxResults:
|
|
3088
|
-
debounceMs:
|
|
3098
|
+
maxResults: f(this.getAttribute("max-results"), 10),
|
|
3099
|
+
debounceMs: f(this.getAttribute("debounce-ms"), 300),
|
|
3089
3100
|
theme: u(this.getAttribute("theme"), "auto"),
|
|
3090
3101
|
shortcut: u(this.getAttribute("shortcut"), "k"),
|
|
3091
3102
|
useMetaKey: this.getAttribute("use-meta-key") !== "false",
|
|
3092
|
-
hideBranding:
|
|
3103
|
+
hideBranding: v(this.getAttribute("hide-branding"), !1),
|
|
3104
|
+
showUrl: v(this.getAttribute("show-url"), !1)
|
|
3093
3105
|
};
|
|
3094
3106
|
}
|
|
3095
3107
|
initializeClient() {
|
|
@@ -3201,8 +3213,8 @@ ${G}`;
|
|
|
3201
3213
|
}
|
|
3202
3214
|
selectActiveResult() {
|
|
3203
3215
|
if (this.activeIndex < 0 || this.activeIndex >= this.results.length) {
|
|
3204
|
-
const
|
|
3205
|
-
|
|
3216
|
+
const s = this.inputElement?.value.trim();
|
|
3217
|
+
s && s.length > 0 && this.performSearch(s);
|
|
3206
3218
|
return;
|
|
3207
3219
|
}
|
|
3208
3220
|
const e = this.results[this.activeIndex];
|
|
@@ -3211,18 +3223,27 @@ ${G}`;
|
|
|
3211
3223
|
result: e,
|
|
3212
3224
|
index: this.activeIndex
|
|
3213
3225
|
})
|
|
3214
|
-
)
|
|
3226
|
+
);
|
|
3227
|
+
const t = this.resultsContainer?.querySelector(
|
|
3228
|
+
`.modal-result-item[data-index="${this.activeIndex}"]`
|
|
3229
|
+
);
|
|
3230
|
+
t && e.url && t.click(), this.close();
|
|
3215
3231
|
}
|
|
3216
3232
|
async performSearch(e) {
|
|
3217
|
-
if (
|
|
3218
|
-
this.
|
|
3233
|
+
if (this.client) {
|
|
3234
|
+
this.currentSearchController && (this.currentSearchController.abort(), this.currentSearchController = null), this.currentSearchController = new AbortController(), this.showLoadingState();
|
|
3219
3235
|
try {
|
|
3220
|
-
const t = await this.client.search(e, {
|
|
3236
|
+
const t = await this.client.search(e, {
|
|
3237
|
+
streaming: !1,
|
|
3238
|
+
signal: this.currentSearchController.signal
|
|
3239
|
+
}), s = this.getProps();
|
|
3221
3240
|
this.results = t.slice(0, s.maxResults || 10), this.activeIndex = this.results.length > 0 ? 0 : -1, this.displayResults(this.results, e);
|
|
3222
3241
|
} catch (t) {
|
|
3242
|
+
if (t.name === "AbortError")
|
|
3243
|
+
return;
|
|
3223
3244
|
this.showErrorState(t.message);
|
|
3224
3245
|
} finally {
|
|
3225
|
-
this.
|
|
3246
|
+
this.currentSearchController = null;
|
|
3226
3247
|
}
|
|
3227
3248
|
}
|
|
3228
3249
|
}
|
|
@@ -3236,9 +3257,10 @@ ${G}`;
|
|
|
3236
3257
|
this.resultsContainer.innerHTML = s, this.footerCount && (this.footerCount.textContent = `${e.length} result${e.length === 1 ? "" : "s"}`), this.inputElement && this.inputElement.setAttribute("aria-expanded", "true"), this.attachResultHandlers(), this.updateActiveResult();
|
|
3237
3258
|
}
|
|
3238
3259
|
renderResult(e, t) {
|
|
3239
|
-
const s = this.renderResultImage(e.image, e.title);
|
|
3260
|
+
const s = this.getProps(), a = this.renderResultImage(e.image, e.title);
|
|
3240
3261
|
return `
|
|
3241
|
-
<
|
|
3262
|
+
<a
|
|
3263
|
+
href="${e.url ? l(e.url) : "#"}"
|
|
3242
3264
|
class="modal-result-item${t === this.activeIndex ? " active" : ""}"
|
|
3243
3265
|
role="option"
|
|
3244
3266
|
id="result-${t}"
|
|
@@ -3247,13 +3269,13 @@ ${G}`;
|
|
|
3247
3269
|
data-index="${t}"
|
|
3248
3270
|
data-url="${l(e.url || "")}"
|
|
3249
3271
|
>
|
|
3250
|
-
${
|
|
3272
|
+
${a}
|
|
3251
3273
|
<div class="modal-result-content">
|
|
3252
3274
|
<div class="modal-result-title">${l(e.title || "")}</div>
|
|
3253
3275
|
${e.description ? `<div class="modal-result-description">${l(e.description)}</div>` : ""}
|
|
3254
|
-
${e.url ? `<
|
|
3276
|
+
${s.showUrl && e.url ? `<span class="modal-result-url">${l(e.url)}</span>` : ""}
|
|
3255
3277
|
</div>
|
|
3256
|
-
</
|
|
3278
|
+
</a>
|
|
3257
3279
|
`;
|
|
3258
3280
|
}
|
|
3259
3281
|
renderResultImage(e, t) {
|
|
@@ -3279,8 +3301,8 @@ ${G}`;
|
|
|
3279
3301
|
const e = this.resultsContainer?.querySelectorAll(".modal-result-item");
|
|
3280
3302
|
if (!e) return;
|
|
3281
3303
|
e.forEach((s, a) => {
|
|
3282
|
-
s.addEventListener("click", (
|
|
3283
|
-
|
|
3304
|
+
s.getAttribute("href") === "#" && s.addEventListener("click", (c) => {
|
|
3305
|
+
c.preventDefault();
|
|
3284
3306
|
}), s.addEventListener("mouseenter", () => {
|
|
3285
3307
|
this.activeIndex = a, this.updateActiveResult();
|
|
3286
3308
|
});
|
|
@@ -3357,7 +3379,7 @@ ${G}`;
|
|
|
3357
3379
|
document.documentElement.style.overflow = this.savedHtmlOverflow || "", document.body.style.overflow = this.savedBodyStyles.overflow, document.body.style.position = this.savedBodyStyles.position, document.body.style.top = this.savedBodyStyles.top, document.body.style.width = this.savedBodyStyles.width, window.scrollTo(0, e), this.savedBodyStyles = null, this.savedHtmlOverflow = null;
|
|
3358
3380
|
}
|
|
3359
3381
|
cleanup() {
|
|
3360
|
-
this.handleGlobalKeydown && (document.removeEventListener("keydown", this.handleGlobalKeydown), this.handleGlobalKeydown = null), this.inputElement && (this.handleInputChange && this.inputElement.removeEventListener("input", this.handleInputChange), this.handleInputKeydown && this.inputElement.removeEventListener("keydown", this.handleInputKeydown)), this.backdrop && this.handleBackdropClick && this.backdrop.removeEventListener("click", this.handleBackdropClick), this.handleInputChange = null, this.handleInputKeydown = null, this.handleBackdropClick = null, this.client && this.client.cancelAllRequests();
|
|
3382
|
+
this.currentSearchController && (this.currentSearchController.abort(), this.currentSearchController = null), this.handleGlobalKeydown && (document.removeEventListener("keydown", this.handleGlobalKeydown), this.handleGlobalKeydown = null), this.inputElement && (this.handleInputChange && this.inputElement.removeEventListener("input", this.handleInputChange), this.handleInputKeydown && this.inputElement.removeEventListener("keydown", this.handleInputKeydown)), this.backdrop && this.handleBackdropClick && this.backdrop.removeEventListener("click", this.handleBackdropClick), this.handleInputChange = null, this.handleInputKeydown = null, this.handleBackdropClick = null, this.client && this.client.cancelAllRequests();
|
|
3361
3383
|
}
|
|
3362
3384
|
// Public API
|
|
3363
3385
|
/**
|