@netlify/spark-ui 0.0.46-alpha.2 → 0.0.46-alpha.3
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/dist/components/preact/SearchModal/components/SearchModal/SearchModal.d.ts +1 -0
- package/dist/components/preact/SearchModal/components/SearchModal/SearchModal.js +20 -20
- package/dist/components/preact/SearchModal/hooks/useSearchLogger.d.ts +2 -1
- package/dist/components/preact/SearchModal/hooks/useSearchLogger.js +24 -20
- package/package.json +1 -1
- package/packages/components/preact/SearchModal/components/SearchModal/SearchModal.tsx +4 -3
- package/packages/components/preact/SearchModal/hooks/useSearchLogger.ts +32 -15
|
@@ -1,42 +1,42 @@
|
|
|
1
1
|
import { u as e } from "../../../../../chunks/jsxRuntime.module.Bzuv3cXw.js";
|
|
2
|
-
import { A as v, y as u, d as
|
|
3
|
-
import
|
|
2
|
+
import { A as v, y as u, d as S } from "../../../../../chunks/hooks.module.CNV9mxng.js";
|
|
3
|
+
import L from "../../../Modal/Modal.js";
|
|
4
4
|
import d from "../../../KeyboardKey/KeyboardKey.js";
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import { useSearch as
|
|
8
|
-
import { useSearchLogger as
|
|
5
|
+
import k from "../SearchWindow.js";
|
|
6
|
+
import w from "../SearchInput.js";
|
|
7
|
+
import { useSearch as I } from "../../hooks/useSearch.js";
|
|
8
|
+
import { useSearchLogger as b } from "../../hooks/useSearchLogger.js";
|
|
9
9
|
import { useKeyboardNav as O } from "../../hooks/useKeyboardNav.js";
|
|
10
10
|
import { useSearchHotkeys as P } from "../../hooks/useSearchHotkeys.js";
|
|
11
11
|
import { useSearchParams as E } from "../../hooks/useSearchParams.js";
|
|
12
12
|
import { useSearchToggles as K } from "../../hooks/useSearchToggles.js";
|
|
13
|
-
import '../../../../../assets/SearchModal.css';function M(
|
|
13
|
+
import '../../../../../assets/SearchModal.css';function M(o) {
|
|
14
14
|
const r = v(null);
|
|
15
15
|
return u(() => {
|
|
16
16
|
function t(i) {
|
|
17
|
-
r.current && !r.current.contains(i.target) &&
|
|
17
|
+
r.current && !r.current.contains(i.target) && o();
|
|
18
18
|
}
|
|
19
19
|
return document.addEventListener("mousedown", t), () => {
|
|
20
20
|
document.removeEventListener("mousedown", t);
|
|
21
21
|
};
|
|
22
|
-
}, [
|
|
22
|
+
}, [o]), r;
|
|
23
23
|
}
|
|
24
|
-
function
|
|
25
|
-
const [r, t] =
|
|
24
|
+
function B(o = { className: "", children: null, debug: !1 }) {
|
|
25
|
+
const [r, t] = S(!1);
|
|
26
26
|
u(() => {
|
|
27
27
|
let c;
|
|
28
|
-
const
|
|
28
|
+
const g = () => {
|
|
29
29
|
window.pagefind && (t(!0), c && clearInterval(c));
|
|
30
30
|
};
|
|
31
|
-
return
|
|
31
|
+
return g(), c = setInterval(g, 100), () => clearInterval(c);
|
|
32
32
|
}, []);
|
|
33
|
-
const { children: i, className: f,
|
|
34
|
-
return
|
|
35
|
-
|
|
36
|
-
}, [n]), /* @__PURE__ */ e(
|
|
37
|
-
/* @__PURE__ */ e(
|
|
33
|
+
const { children: i, className: f, debug: N, ...y } = o, { state: a, actions: h } = I(), [n, p] = S(!1), m = () => p(!0), l = () => p(!1), s = v(null), T = M(l);
|
|
34
|
+
return b(a, N), K(r, m), E(r, h.setSearchTerm, m), P(r, n, m, l), O(r, s, n, l), u(() => {
|
|
35
|
+
s.current && (n ? s.current.showModal() : s.current.close());
|
|
36
|
+
}, [n]), /* @__PURE__ */ e(L, { ref: s, className: `n-search-modal ${f || ""}`, ...y, children: /* @__PURE__ */ e("div", { ref: T, className: "n-search-container", children: [
|
|
37
|
+
/* @__PURE__ */ e(w, { setSearchTerm: h.setSearchTerm, initialValue: a.searchTerm }),
|
|
38
38
|
/* @__PURE__ */ e(
|
|
39
|
-
|
|
39
|
+
k,
|
|
40
40
|
{
|
|
41
41
|
searchLoading: a.isLoading,
|
|
42
42
|
searchTerm: a.searchTerm,
|
|
@@ -59,5 +59,5 @@ function z(s = { className: "", children: null }) {
|
|
|
59
59
|
] }) });
|
|
60
60
|
}
|
|
61
61
|
export {
|
|
62
|
-
|
|
62
|
+
B as default
|
|
63
63
|
};
|
|
@@ -12,6 +12,7 @@ import { SearchState } from '../types/search.types';
|
|
|
12
12
|
* @param {SearchState} [state] - The search state, which includes the current search term and the results of the search.
|
|
13
13
|
* - `state.searchTerm`: The current search query string.
|
|
14
14
|
* - `state.results`: The search results array. If it's empty, the hook will log a no-results event.
|
|
15
|
+
* @param {boolean} [debug=false] - Flag to enable debug mode. If true, additional debug information will be sent with the event payloads.
|
|
15
16
|
*
|
|
16
17
|
* @returns {Object} - An object with the following function:
|
|
17
18
|
* - `handleClick`: A callback function that should be attached to search result click events. It tracks `spark_search:result_clicked` events with the clicked result's title and URL.
|
|
@@ -22,6 +23,6 @@ import { SearchState } from '../types/search.types';
|
|
|
22
23
|
* // In your component, attach handleClick to the search result links
|
|
23
24
|
* <a href="result-url" onClick={handleClick}>Search Result</a>
|
|
24
25
|
*/
|
|
25
|
-
export declare function useSearchLogger(state?: SearchState): {
|
|
26
|
+
export declare function useSearchLogger(state?: SearchState, debug?: boolean): {
|
|
26
27
|
handleClick: (e: Event) => void;
|
|
27
28
|
};
|
|
@@ -1,33 +1,37 @@
|
|
|
1
|
-
import { A as k, y as
|
|
2
|
-
class
|
|
1
|
+
import { A as k, y as h, q as m } from "../../../../chunks/hooks.module.CNV9mxng.js";
|
|
2
|
+
class y {
|
|
3
3
|
/**
|
|
4
4
|
* Pushes an event payload into the dataLayer.
|
|
5
5
|
* @param eventName e.g. 'www:search_query_changed'
|
|
6
6
|
* @param payload additional key/value data
|
|
7
7
|
*/
|
|
8
|
-
track(
|
|
9
|
-
gtag("event",
|
|
8
|
+
track(l, u = {}) {
|
|
9
|
+
gtag("event", l, { ...u });
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
-
function
|
|
13
|
-
const
|
|
14
|
-
return
|
|
15
|
-
r != null && r.searchTerm
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
function p(r, l) {
|
|
13
|
+
const n = k(new y()).current;
|
|
14
|
+
return h(() => {
|
|
15
|
+
if (!(r != null && r.searchTerm)) return;
|
|
16
|
+
const c = { query: r == null ? void 0 : r.searchTerm };
|
|
17
|
+
l && (c.debug_mode = !0), n.track("spark_search:query_changed", c);
|
|
18
|
+
}, [r == null ? void 0 : r.searchTerm]), h(() => {
|
|
19
|
+
if (!(r != null && r.results)) return;
|
|
20
|
+
const c = { query: r == null ? void 0 : r.searchTerm };
|
|
21
|
+
l && (c.debug_mode = !0), r != null && r.searchTerm && r.results.length === 0 && n.track("spark_search:no_results", c);
|
|
18
22
|
}, [r == null ? void 0 : r.results]), {
|
|
19
|
-
handleClick:
|
|
20
|
-
var
|
|
21
|
-
const
|
|
22
|
-
if (!
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
handleClick: m((c) => {
|
|
24
|
+
var i;
|
|
25
|
+
const e = c.target.closest("a");
|
|
26
|
+
if (!e) return;
|
|
27
|
+
const d = (i = e.querySelector(".n-search-link-label")) == null ? void 0 : i.innerHTML, f = e.getAttribute("href"), o = {
|
|
28
|
+
resultTitle: d,
|
|
29
|
+
resultUrl: f
|
|
30
|
+
};
|
|
31
|
+
l && (o.debug_mode = !0), n.track("spark_search:result_clicked", o);
|
|
28
32
|
}, [])
|
|
29
33
|
};
|
|
30
34
|
}
|
|
31
35
|
export {
|
|
32
|
-
|
|
36
|
+
p as useSearchLogger
|
|
33
37
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@netlify/spark-ui",
|
|
3
3
|
"description": "Assets, design tokens, components, and utilities",
|
|
4
|
-
"version": "0.0.46-alpha.
|
|
4
|
+
"version": "0.0.46-alpha.3",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/components/preact/index.js",
|
|
7
7
|
"types": "dist/components/preact/index.d.ts",
|
|
@@ -20,9 +20,10 @@ import './SearchModal.css';
|
|
|
20
20
|
interface Props {
|
|
21
21
|
children: ComponentChildren;
|
|
22
22
|
className?: string;
|
|
23
|
+
debug?: boolean
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
function SearchModal(props: Props = {className: '', children: null}) {
|
|
26
|
+
function SearchModal(props: Props = {className: '', children: null, debug: false }) {
|
|
26
27
|
const [isPagefindLoaded, setIsPagefindLoaded] = useState(false);
|
|
27
28
|
|
|
28
29
|
// Poll for the existence of window.pagefind.
|
|
@@ -45,7 +46,7 @@ function SearchModal(props: Props = {className: '', children: null}) {
|
|
|
45
46
|
}, []);
|
|
46
47
|
|
|
47
48
|
|
|
48
|
-
const { children, className, ...rest } = props;
|
|
49
|
+
const { children, className, debug, ...rest } = props;
|
|
49
50
|
const { state, actions } = useSearch();
|
|
50
51
|
const [searchOpen, setSearchOpen] = useState(false);
|
|
51
52
|
|
|
@@ -55,7 +56,7 @@ function SearchModal(props: Props = {className: '', children: null}) {
|
|
|
55
56
|
const modalRef = useRef<HTMLDialogElement>(null);
|
|
56
57
|
const containerRef = useClickOutside<HTMLDivElement>(closeSearch);
|
|
57
58
|
|
|
58
|
-
useSearchLogger(state)
|
|
59
|
+
useSearchLogger(state, debug)
|
|
59
60
|
useSearchToggles(isPagefindLoaded, openSearch);
|
|
60
61
|
useSearchParams(isPagefindLoaded, actions.setSearchTerm, openSearch);
|
|
61
62
|
useSearchHotkeys(isPagefindLoaded, searchOpen, openSearch, closeSearch);
|
|
@@ -15,52 +15,69 @@ import Analytics from '../../../../analytics/analytics';
|
|
|
15
15
|
* @param {SearchState} [state] - The search state, which includes the current search term and the results of the search.
|
|
16
16
|
* - `state.searchTerm`: The current search query string.
|
|
17
17
|
* - `state.results`: The search results array. If it's empty, the hook will log a no-results event.
|
|
18
|
-
*
|
|
18
|
+
* @param {boolean} [debug=false] - Flag to enable debug mode. If true, additional debug information will be sent with the event payloads.
|
|
19
|
+
*
|
|
19
20
|
* @returns {Object} - An object with the following function:
|
|
20
21
|
* - `handleClick`: A callback function that should be attached to search result click events. It tracks `spark_search:result_clicked` events with the clicked result's title and URL.
|
|
21
22
|
*
|
|
22
23
|
* @example
|
|
23
24
|
* const { handleClick } = useSearchLogger(searchState);
|
|
24
|
-
*
|
|
25
|
+
*
|
|
25
26
|
* // In your component, attach handleClick to the search result links
|
|
26
27
|
* <a href="result-url" onClick={handleClick}>Search Result</a>
|
|
27
28
|
*/
|
|
28
29
|
|
|
29
|
-
export function useSearchLogger(state?: SearchState) {
|
|
30
|
+
export function useSearchLogger(state?: SearchState, debug?: boolean) {
|
|
30
31
|
const ref = useRef<Analytics>(new Analytics());
|
|
31
32
|
const analytics = ref.current;
|
|
32
33
|
|
|
33
34
|
// Log search query
|
|
34
35
|
useEffect(() => {
|
|
35
|
-
if (!state?.searchTerm) return
|
|
36
|
-
|
|
36
|
+
if (!state?.searchTerm) return;
|
|
37
|
+
const payload = { query: state?.searchTerm };
|
|
38
|
+
|
|
39
|
+
if (debug) {
|
|
40
|
+
payload.debug_mode = true;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
analytics.track('spark_search:query_changed', payload);
|
|
37
44
|
}, [state?.searchTerm]);
|
|
38
45
|
|
|
39
46
|
// Log zero‑hit searches
|
|
40
47
|
useEffect(() => {
|
|
41
|
-
if (!state?.results) return
|
|
48
|
+
if (!state?.results) return;
|
|
49
|
+
|
|
50
|
+
const payload = { query: state?.searchTerm };
|
|
51
|
+
|
|
52
|
+
if (debug) {
|
|
53
|
+
payload.debug_mode = true;
|
|
54
|
+
}
|
|
42
55
|
|
|
43
56
|
if (state?.searchTerm && state.results.length === 0) {
|
|
44
|
-
analytics.track('spark_search:no_results',
|
|
57
|
+
analytics.track('spark_search:no_results', payload);
|
|
45
58
|
}
|
|
46
59
|
}, [state?.results]);
|
|
47
60
|
|
|
48
61
|
const handleResultClick = useCallback((e: Event) => {
|
|
49
62
|
const anchor = (e.target as HTMLElement).closest('a');
|
|
50
|
-
|
|
51
|
-
if (!anchor) return
|
|
52
63
|
|
|
53
|
-
|
|
54
|
-
const url = anchor.getAttribute('href')
|
|
64
|
+
if (!anchor) return;
|
|
55
65
|
|
|
56
|
-
|
|
66
|
+
const label = anchor.querySelector('.n-search-link-label')?.innerHTML;
|
|
67
|
+
const url = anchor.getAttribute('href');
|
|
68
|
+
const payload = {
|
|
57
69
|
resultTitle: label,
|
|
58
70
|
resultUrl: url,
|
|
59
|
-
}
|
|
60
|
-
}, []);
|
|
71
|
+
};
|
|
61
72
|
|
|
73
|
+
if (debug) {
|
|
74
|
+
payload.debug_mode = true;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
analytics.track('spark_search:result_clicked', payload);
|
|
78
|
+
}, []);
|
|
62
79
|
|
|
63
80
|
return {
|
|
64
|
-
handleClick: handleResultClick
|
|
81
|
+
handleClick: handleResultClick,
|
|
65
82
|
};
|
|
66
83
|
}
|