@netlify/spark-ui 0.0.41 → 0.0.42-alpha.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.
Files changed (26) hide show
  1. package/dist/analytics/logger.d.ts +13 -0
  2. package/dist/chunks/{compat.module.AxtqoZMv.js → compat.module.DT16W4Wr.js} +1 -1
  3. package/dist/chunks/hooks.module.CNV9mxng.js +138 -0
  4. package/dist/components/preact/Modal/Modal.js +1 -1
  5. package/dist/components/preact/SearchModal/components/SearchInput.js +1 -1
  6. package/dist/components/preact/SearchModal/components/SearchLink/SearchLink.js +18 -13
  7. package/dist/components/preact/SearchModal/components/SearchModal/SearchModal.js +23 -22
  8. package/dist/components/preact/SearchModal/components/SearchToggle/SearchToggle.js +1 -1
  9. package/dist/components/preact/SearchModal/components/SearchWindow.js +1 -1
  10. package/dist/components/preact/SearchModal/hooks/index.d.ts +1 -0
  11. package/dist/components/preact/SearchModal/hooks/index.js +10 -8
  12. package/dist/components/preact/SearchModal/hooks/useKeyboardNav.js +1 -1
  13. package/dist/components/preact/SearchModal/hooks/useSearch.js +1 -1
  14. package/dist/components/preact/SearchModal/hooks/useSearchHotkeys.js +1 -1
  15. package/dist/components/preact/SearchModal/hooks/useSearchLogger.d.ts +18 -0
  16. package/dist/components/preact/SearchModal/hooks/useSearchLogger.js +43 -0
  17. package/dist/components/preact/SearchModal/hooks/useSearchParams.js +1 -1
  18. package/dist/components/preact/SearchModal/hooks/useSearchToggles.js +1 -1
  19. package/dist/components/preact/index.js +1 -1
  20. package/package.json +1 -1
  21. package/packages/analytics/logger.ts +26 -0
  22. package/packages/components/preact/SearchModal/components/SearchLink/SearchLink.tsx +4 -1
  23. package/packages/components/preact/SearchModal/components/SearchModal/SearchModal.tsx +3 -1
  24. package/packages/components/preact/SearchModal/hooks/index.ts +1 -0
  25. package/packages/components/preact/SearchModal/hooks/useSearchLogger.ts +61 -0
  26. package/dist/chunks/hooks.module.BFfOesdf.js +0 -132
@@ -0,0 +1,13 @@
1
+ export declare class Logger {
2
+ private dataLayer;
3
+ /**
4
+ * @param dl Optional injected dataLayer array. Defaults to window.dataLayer.
5
+ */
6
+ constructor(dl?: any[]);
7
+ /**
8
+ * Pushes an event payload into the dataLayer.
9
+ * @param eventName e.g. 'searchResultClick'
10
+ * @param payload additional key/value data
11
+ */
12
+ push(eventName: string, payload?: Record<string, any>): void;
13
+ }
@@ -1,5 +1,5 @@
1
1
  import { Component as f, options as a, createElement as d, Fragment as h, toChildArray as v } from "preact";
2
- import "./hooks.module.BFfOesdf.js";
2
+ import "./hooks.module.CNV9mxng.js";
3
3
  function C(e, t) {
4
4
  for (var r in t) e[r] = t[r];
5
5
  return e;
@@ -0,0 +1,138 @@
1
+ import { options as x } from "preact";
2
+ var v, n, H, y, m = 0, C = [], u = x, A = u.__b, q = u.__r, F = u.diffed, g = u.__c, k = u.unmount, T = u.__;
3
+ function d(_, t) {
4
+ u.__h && u.__h(n, _, m || t), m = 0;
5
+ var r = n.__H || (n.__H = { __: [], __h: [] });
6
+ return _ >= r.__.length && r.__.push({}), r.__[_];
7
+ }
8
+ function S(_) {
9
+ return m = 1, z(j, _);
10
+ }
11
+ function z(_, t, r) {
12
+ var o = d(v++, 2);
13
+ if (o.t = _, !o.__c && (o.__ = [r ? r(t) : j(void 0, t), function(c) {
14
+ var e = o.__N ? o.__N[0] : o.__[0], f = o.t(e, c);
15
+ e !== f && (o.__N = [f, o.__[1]], o.__c.setState({}));
16
+ }], o.__c = n, !n.__f)) {
17
+ var a = function(c, e, f) {
18
+ if (!o.__c.__H) return !0;
19
+ var l = o.__c.__H.__.filter(function(i) {
20
+ return !!i.__c;
21
+ });
22
+ if (l.every(function(i) {
23
+ return !i.__N;
24
+ })) return !h || h.call(this, c, e, f);
25
+ var E = o.__c.props !== c;
26
+ return l.forEach(function(i) {
27
+ if (i.__N) {
28
+ var w = i.__[0];
29
+ i.__ = i.__N, i.__N = void 0, w !== i.__[0] && (E = !0);
30
+ }
31
+ }), h && h.call(this, c, e, f) || E;
32
+ };
33
+ n.__f = !0;
34
+ var h = n.shouldComponentUpdate, N = n.componentWillUpdate;
35
+ n.componentWillUpdate = function(c, e, f) {
36
+ if (this.__e) {
37
+ var l = h;
38
+ h = void 0, a(c, e, f), h = l;
39
+ }
40
+ N && N.call(this, c, e, f);
41
+ }, n.shouldComponentUpdate = a;
42
+ }
43
+ return o.__N || o.__;
44
+ }
45
+ function G(_, t) {
46
+ var r = d(v++, 3);
47
+ !u.__s && W(r.__H, t) && (r.__ = _, r.u = t, n.__H.__h.push(r));
48
+ }
49
+ function I(_) {
50
+ return m = 5, b(function() {
51
+ return { current: _ };
52
+ }, []);
53
+ }
54
+ function b(_, t) {
55
+ var r = d(v++, 7);
56
+ return W(r.__H, t) && (r.__ = _(), r.__H = t, r.__h = _), r.__;
57
+ }
58
+ function J(_, t) {
59
+ return m = 8, b(function() {
60
+ return _;
61
+ }, t);
62
+ }
63
+ function B() {
64
+ for (var _; _ = C.shift(); ) if (_.__P && _.__H) try {
65
+ _.__H.__h.forEach(s), _.__H.__h.forEach(p), _.__H.__h = [];
66
+ } catch (t) {
67
+ _.__H.__h = [], u.__e(t, _.__v);
68
+ }
69
+ }
70
+ u.__b = function(_) {
71
+ n = null, A && A(_);
72
+ }, u.__ = function(_, t) {
73
+ _ && t.__k && t.__k.__m && (_.__m = t.__k.__m), T && T(_, t);
74
+ }, u.__r = function(_) {
75
+ q && q(_), v = 0;
76
+ var t = (n = _.__c).__H;
77
+ t && (H === n ? (t.__h = [], n.__h = [], t.__.forEach(function(r) {
78
+ r.__N && (r.__ = r.__N), r.u = r.__N = void 0;
79
+ })) : (t.__h.forEach(s), t.__h.forEach(p), t.__h = [], v = 0)), H = n;
80
+ }, u.diffed = function(_) {
81
+ F && F(_);
82
+ var t = _.__c;
83
+ t && t.__H && (t.__H.__h.length && (C.push(t) !== 1 && y === u.requestAnimationFrame || ((y = u.requestAnimationFrame) || D)(B)), t.__H.__.forEach(function(r) {
84
+ r.u && (r.__H = r.u), r.u = void 0;
85
+ })), H = n = null;
86
+ }, u.__c = function(_, t) {
87
+ t.some(function(r) {
88
+ try {
89
+ r.__h.forEach(s), r.__h = r.__h.filter(function(o) {
90
+ return !o.__ || p(o);
91
+ });
92
+ } catch (o) {
93
+ t.some(function(a) {
94
+ a.__h && (a.__h = []);
95
+ }), t = [], u.__e(o, r.__v);
96
+ }
97
+ }), g && g(_, t);
98
+ }, u.unmount = function(_) {
99
+ k && k(_);
100
+ var t, r = _.__c;
101
+ r && r.__H && (r.__H.__.forEach(function(o) {
102
+ try {
103
+ s(o);
104
+ } catch (a) {
105
+ t = a;
106
+ }
107
+ }), r.__H = void 0, t && u.__e(t, r.__v));
108
+ };
109
+ var U = typeof requestAnimationFrame == "function";
110
+ function D(_) {
111
+ var t, r = function() {
112
+ clearTimeout(o), U && cancelAnimationFrame(t), setTimeout(_);
113
+ }, o = setTimeout(r, 100);
114
+ U && (t = requestAnimationFrame(r));
115
+ }
116
+ function s(_) {
117
+ var t = n, r = _.__c;
118
+ typeof r == "function" && (_.__c = void 0, r()), n = t;
119
+ }
120
+ function p(_) {
121
+ var t = n;
122
+ _.__c = _.__(), n = t;
123
+ }
124
+ function W(_, t) {
125
+ return !_ || _.length !== t.length || t.some(function(r, o) {
126
+ return r !== _[o];
127
+ });
128
+ }
129
+ function j(_, t) {
130
+ return typeof t == "function" ? t(_) : t;
131
+ }
132
+ export {
133
+ I as A,
134
+ b as T,
135
+ S as d,
136
+ J as q,
137
+ G as y
138
+ };
@@ -1,5 +1,5 @@
1
1
  import { u as l } from "../../../chunks/jsxRuntime.module.Bzuv3cXw.js";
2
- import { D as d } from "../../../chunks/compat.module.AxtqoZMv.js";
2
+ import { D as d } from "../../../chunks/compat.module.DT16W4Wr.js";
3
3
  const u = d(function({ children: o, className: r, ...a }, t) {
4
4
  return /* @__PURE__ */ l("dialog", { ref: t, className: r, role: "dialog", "aria-modal": "true", ...a, children: o });
5
5
  });
@@ -1,5 +1,5 @@
1
1
  import { u as e } from "../../../../chunks/jsxRuntime.module.Bzuv3cXw.js";
2
- import { d as i, y as s } from "../../../../chunks/hooks.module.BFfOesdf.js";
2
+ import { d as i, y as s } from "../../../../chunks/hooks.module.CNV9mxng.js";
3
3
  import h from "../../Icon/index.js";
4
4
  const m = (a) => {
5
5
  const [t, l] = i(""), c = (r) => {
@@ -1,17 +1,22 @@
1
1
  import { u as a } from "../../../../../chunks/jsxRuntime.module.Bzuv3cXw.js";
2
- import s from "../../../Icon/index.js";
3
- import '../../../../../assets/SearchLink.css';const m = ({ icon: e, label: c, url: r, excerpt: l, resource: n }) => /* @__PURE__ */ a("a", { className: "n-search-link", href: r, children: [
4
- e && /* @__PURE__ */ a("span", { className: "n-search-link-icon", children: /* @__PURE__ */ a(s, { name: e }) }),
5
- /* @__PURE__ */ a("div", { className: "n-search-link-body", children: [
6
- /* @__PURE__ */ a("p", { className: "n-search-link-title", children: [
7
- /* @__PURE__ */ a("span", { className: "n-search-link-label", children: c }),
8
- " ",
9
- n && /* @__PURE__ */ a("span", { className: "n-search-link-badge", "data-resource": n, children: n })
2
+ import "../../../../../chunks/hooks.module.CNV9mxng.js";
3
+ import { useSearchLogger as h } from "../../hooks/useSearchLogger.js";
4
+ import c from "../../../Icon/index.js";
5
+ import '../../../../../assets/SearchLink.css';const k = ({ icon: n, label: s, url: r, excerpt: l, resource: e }) => {
6
+ const { handleClick: i } = h();
7
+ return /* @__PURE__ */ a("a", { className: "n-search-link", href: r, onClick: i, children: [
8
+ n && /* @__PURE__ */ a("span", { className: "n-search-link-icon", children: /* @__PURE__ */ a(c, { name: n }) }),
9
+ /* @__PURE__ */ a("div", { className: "n-search-link-body", children: [
10
+ /* @__PURE__ */ a("p", { className: "n-search-link-title", children: [
11
+ /* @__PURE__ */ a("span", { className: "n-search-link-label", children: s }),
12
+ " ",
13
+ e && /* @__PURE__ */ a("span", { className: "n-search-link-badge", "data-resource": e, children: e })
14
+ ] }),
15
+ l && /* @__PURE__ */ a("p", { className: "n-search-link-excerpt", dangerouslySetInnerHTML: { __html: l } })
10
16
  ] }),
11
- l && /* @__PURE__ */ a("p", { className: "n-search-link-excerpt", dangerouslySetInnerHTML: { __html: l } })
12
- ] }),
13
- /* @__PURE__ */ a("div", { className: "n-search-link-icon", children: /* @__PURE__ */ a(s, { name: "caretRight" }) })
14
- ] });
17
+ /* @__PURE__ */ a("div", { className: "n-search-link-icon", children: /* @__PURE__ */ a(c, { name: "caretRight" }) })
18
+ ] });
19
+ };
15
20
  export {
16
- m as default
21
+ k as default
17
22
  };
@@ -1,16 +1,17 @@
1
1
  import { u as e } from "../../../../../chunks/jsxRuntime.module.Bzuv3cXw.js";
2
- import { A as N, y as u, d as v } from "../../../../../chunks/hooks.module.BFfOesdf.js";
2
+ import { A as v, y as u, d as g } from "../../../../../chunks/hooks.module.CNV9mxng.js";
3
3
  import T from "../../../Modal/Modal.js";
4
4
  import d from "../../../KeyboardKey/KeyboardKey.js";
5
- import k from "../SearchWindow.js";
6
- import w from "../SearchInput.js";
7
- import { useSearch as I } from "../../hooks/useSearch.js";
8
- import { useKeyboardNav as L } from "../../hooks/useKeyboardNav.js";
9
- import { useSearchHotkeys as O } from "../../hooks/useSearchHotkeys.js";
10
- import { useSearchParams as P } from "../../hooks/useSearchParams.js";
11
- import { useSearchToggles as E } from "../../hooks/useSearchToggles.js";
12
- import '../../../../../assets/SearchModal.css';function K(s) {
13
- const r = N(null);
5
+ import L from "../SearchWindow.js";
6
+ import k from "../SearchInput.js";
7
+ import { useSearch as w } from "../../hooks/useSearch.js";
8
+ import { useSearchLogger as I } from "../../hooks/useSearchLogger.js";
9
+ import { useKeyboardNav as O } from "../../hooks/useKeyboardNav.js";
10
+ import { useSearchHotkeys as P } from "../../hooks/useSearchHotkeys.js";
11
+ import { useSearchParams as E } from "../../hooks/useSearchParams.js";
12
+ import { useSearchToggles as K } from "../../hooks/useSearchToggles.js";
13
+ import '../../../../../assets/SearchModal.css';function M(s) {
14
+ const r = v(null);
14
15
  return u(() => {
15
16
  function t(i) {
16
17
  r.current && !r.current.contains(i.target) && s();
@@ -20,8 +21,8 @@ import '../../../../../assets/SearchModal.css';function K(s) {
20
21
  };
21
22
  }, [s]), r;
22
23
  }
23
- function j(s = { className: "", children: null }) {
24
- const [r, t] = v(!1);
24
+ function z(s = { className: "", children: null }) {
25
+ const [r, t] = g(!1);
25
26
  u(() => {
26
27
  let c;
27
28
  const S = () => {
@@ -29,17 +30,17 @@ function j(s = { className: "", children: null }) {
29
30
  };
30
31
  return S(), c = setInterval(S, 100), () => clearInterval(c);
31
32
  }, []);
32
- const { children: i, className: f, ...g } = s, { state: n, actions: h } = I(), [o, p] = v(!1), l = () => p(!0), m = () => p(!1), a = N(null), y = K(m);
33
- return E(r, l), P(r, h.setSearchTerm, l), O(r, o, l, m), L(r, a, o, m), u(() => {
34
- a.current && (o ? a.current.showModal() : a.current.close());
35
- }, [o]), /* @__PURE__ */ e(T, { ref: a, className: `n-search-modal ${f || ""}`, ...g, children: /* @__PURE__ */ e("div", { ref: y, className: "n-search-container", children: [
36
- /* @__PURE__ */ e(w, { setSearchTerm: h.setSearchTerm, initialValue: n.searchTerm }),
33
+ const { children: i, className: f, ...N } = s, { state: a, actions: h } = w(), [n, p] = g(!1), m = () => p(!0), l = () => p(!1), o = v(null), y = M(l);
34
+ return I(a), K(r, m), E(r, h.setSearchTerm, m), P(r, n, m, l), O(r, o, n, l), u(() => {
35
+ o.current && (n ? o.current.showModal() : o.current.close());
36
+ }, [n]), /* @__PURE__ */ e(T, { ref: o, className: `n-search-modal ${f || ""}`, ...N, children: /* @__PURE__ */ e("div", { ref: y, className: "n-search-container", children: [
37
+ /* @__PURE__ */ e(k, { setSearchTerm: h.setSearchTerm, initialValue: a.searchTerm }),
37
38
  /* @__PURE__ */ e(
38
- k,
39
+ L,
39
40
  {
40
- searchLoading: n.isLoading,
41
- searchTerm: n.searchTerm,
42
- results: n.results,
41
+ searchLoading: a.isLoading,
42
+ searchTerm: a.searchTerm,
43
+ results: a.results,
43
44
  children: i
44
45
  }
45
46
  ),
@@ -58,5 +59,5 @@ function j(s = { className: "", children: null }) {
58
59
  ] }) });
59
60
  }
60
61
  export {
61
- j as default
62
+ z as default
62
63
  };
@@ -1,5 +1,5 @@
1
1
  import { u as e } from "../../../../../chunks/jsxRuntime.module.Bzuv3cXw.js";
2
- import { D as t } from "../../../../../chunks/compat.module.AxtqoZMv.js";
2
+ import { D as t } from "../../../../../chunks/compat.module.DT16W4Wr.js";
3
3
  import o from "../../../Icon/index.js";
4
4
  import '../../../../../assets/SearchToggle.css';const s = t(function(r, a) {
5
5
  return /* @__PURE__ */ e("button", { id: r.id, ref: a, class: "n-search-toggle", disabled: !0, "data-ntl-search-toggle": !0, children: [
@@ -1,5 +1,5 @@
1
1
  import { u as e } from "../../../../chunks/jsxRuntime.module.Bzuv3cXw.js";
2
- import { T as o } from "../../../../chunks/hooks.module.BFfOesdf.js";
2
+ import { T as o } from "../../../../chunks/hooks.module.CNV9mxng.js";
3
3
  import t from "./SearchHeading/SearchHeading.js";
4
4
  import a from "./SearchLink/SearchLink.js";
5
5
  const h = ({
@@ -1,4 +1,5 @@
1
1
  export { useSearch } from '../hooks/useSearch';
2
+ export { useSearchLogger } from './useSearchLogger';
2
3
  export { useKeyboardNav } from '../hooks/useKeyboardNav';
3
4
  export { useSearchHotkeys } from '../hooks/useSearchHotkeys';
4
5
  export { useSearchParams } from '../hooks/useSearchParams';
@@ -1,12 +1,14 @@
1
1
  import { useSearch as o } from "./useSearch.js";
2
- import { useKeyboardNav as s } from "./useKeyboardNav.js";
3
- import { useSearchHotkeys as t } from "./useSearchHotkeys.js";
4
- import { useSearchParams as p } from "./useSearchParams.js";
5
- import { useSearchToggles as x } from "./useSearchToggles.js";
2
+ import { useSearchLogger as s } from "./useSearchLogger.js";
3
+ import { useKeyboardNav as t } from "./useKeyboardNav.js";
4
+ import { useSearchHotkeys as p } from "./useSearchHotkeys.js";
5
+ import { useSearchParams as x } from "./useSearchParams.js";
6
+ import { useSearchToggles as h } from "./useSearchToggles.js";
6
7
  export {
7
- s as useKeyboardNav,
8
+ t as useKeyboardNav,
8
9
  o as useSearch,
9
- t as useSearchHotkeys,
10
- p as useSearchParams,
11
- x as useSearchToggles
10
+ p as useSearchHotkeys,
11
+ s as useSearchLogger,
12
+ x as useSearchParams,
13
+ h as useSearchToggles
12
14
  };
@@ -1,4 +1,4 @@
1
- import { y as l } from "../../../../chunks/hooks.module.BFfOesdf.js";
1
+ import { y as l } from "../../../../chunks/hooks.module.CNV9mxng.js";
2
2
  function s(r, t, o, c) {
3
3
  l(() => {
4
4
  if (!r) return;
@@ -1,4 +1,4 @@
1
- import { A as i, y as S, d as T } from "../../../../chunks/hooks.module.BFfOesdf.js";
1
+ import { A as i, y as S, d as T } from "../../../../chunks/hooks.module.CNV9mxng.js";
2
2
  function L(o, n) {
3
3
  const e = i(null), s = i("");
4
4
  return S(() => () => {
@@ -1,4 +1,4 @@
1
- import { y as u } from "../../../../chunks/hooks.module.BFfOesdf.js";
1
+ import { y as u } from "../../../../chunks/hooks.module.CNV9mxng.js";
2
2
  function a(t, r, n, o) {
3
3
  u(() => {
4
4
  if (!t) return;
@@ -0,0 +1,18 @@
1
+ import { SearchState } from '../types/search.types';
2
+ /**
3
+ * Hook that logs search-related events to your analytics Logger.
4
+ *
5
+ * It will:
6
+ * - Push a `searchQueryChanged` event whenever the search term changes.
7
+ * - Push a `searchNoResults` event whenever a non-empty query returns zero results.
8
+ * - Provide a click handler (`handleClick`) to log `searchResultClick` events.
9
+ *
10
+ * @param {SearchState} state - The current search state, containing:
11
+ * - `searchTerm` (string): the text the user has searched for.
12
+ * - `results` (Array<any>): the array of result objects returned.
13
+ * @returns {{ handleClick: (e: Event) => void }}
14
+ * An object with a `handleClick` function that you can attach to result links to log clicks.
15
+ */
16
+ export declare function useSearchLogger(state?: SearchState): {
17
+ handleClick: (e: Event) => void;
18
+ };
@@ -0,0 +1,43 @@
1
+ var a = Object.defineProperty;
2
+ var y = (r, e, c) => e in r ? a(r, e, { enumerable: !0, configurable: !0, writable: !0, value: c }) : r[e] = c;
3
+ var h = (r, e, c) => y(r, typeof e != "symbol" ? e + "" : e, c);
4
+ import { A as d, y as l, q as g } from "../../../../chunks/hooks.module.CNV9mxng.js";
5
+ class L {
6
+ /**
7
+ * @param dl Optional injected dataLayer array. Defaults to window.dataLayer.
8
+ */
9
+ constructor(e) {
10
+ h(this, "dataLayer");
11
+ this.dataLayer = Array.isArray(e) ? e : window.dataLayer, Array.isArray(this.dataLayer) || (window.dataLayer = [], this.dataLayer = window.dataLayer);
12
+ }
13
+ /**
14
+ * Pushes an event payload into the dataLayer.
15
+ * @param eventName e.g. 'searchResultClick'
16
+ * @param payload additional key/value data
17
+ */
18
+ push(e, c = {}) {
19
+ this.dataLayer.push({ event: e, ...c });
20
+ }
21
+ }
22
+ function m(r) {
23
+ const e = d(new L());
24
+ return l(() => {
25
+ r != null && r.searchTerm && (console.log("Pushing searchQueryChanged"), e.current.push("searchQueryChanged", { query: r == null ? void 0 : r.searchTerm }));
26
+ }, [r == null ? void 0 : r.searchTerm]), l(() => {
27
+ r != null && r.results && r != null && r.searchTerm && r.results.length === 0 && (console.log("Pushing searchNoResults"), e.current.push("searchNoResults", { query: r == null ? void 0 : r.searchTerm }));
28
+ }, [r == null ? void 0 : r.results]), {
29
+ handleClick: g((o) => {
30
+ var u;
31
+ const n = o.target.closest("a");
32
+ if (!n) return;
33
+ const i = (u = n.querySelector(".n-search-link-label")) == null ? void 0 : u.innerHTML, s = n.getAttribute("href");
34
+ e.current.push("searchResultClick", {
35
+ searchResultTitle: i,
36
+ searchResultURL: s
37
+ });
38
+ }, [])
39
+ };
40
+ }
41
+ export {
42
+ m as useSearchLogger
43
+ };
@@ -1,4 +1,4 @@
1
- import { y as c } from "../../../../chunks/hooks.module.BFfOesdf.js";
1
+ import { y as c } from "../../../../chunks/hooks.module.CNV9mxng.js";
2
2
  function n(r, o, a) {
3
3
  c(() => {
4
4
  if (typeof location > "u" || r) return;
@@ -1,4 +1,4 @@
1
- import { y as l } from "../../../../chunks/hooks.module.BFfOesdf.js";
1
+ import { y as l } from "../../../../chunks/hooks.module.CNV9mxng.js";
2
2
  function i(c, r) {
3
3
  l(() => {
4
4
  if (!c) return;
@@ -5,7 +5,7 @@ import { default as s } from "./SearchModal/components/SearchLink/SearchLink.js"
5
5
  import { default as x } from "./SearchModal/components/SearchHeading/SearchHeading.js";
6
6
  import { default as h } from "./SearchModal/components/SearchToggle/SearchToggle.js";
7
7
  import "preact";
8
- import "../../chunks/hooks.module.BFfOesdf.js";
8
+ import "../../chunks/hooks.module.CNV9mxng.js";
9
9
  import { default as S } from "./SearchModal/components/SearchModal/SearchModal.js";
10
10
  export {
11
11
  m as Icon,
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.41",
4
+ "version": "0.0.42-alpha.1",
5
5
  "type": "module",
6
6
  "main": "dist/components/preact/index.js",
7
7
  "types": "dist/components/preact/index.d.ts",
@@ -0,0 +1,26 @@
1
+ export class Logger {
2
+ private dataLayer: any[];
3
+
4
+ /**
5
+ * @param dl Optional injected dataLayer array. Defaults to window.dataLayer.
6
+ */
7
+ constructor(dl?: any[]) {
8
+ // Use injected or global dataLayer
9
+ this.dataLayer = Array.isArray(dl) ? dl : (window as any).dataLayer;
10
+
11
+ // If for some reason it's not an array, initialize it
12
+ if (!Array.isArray(this.dataLayer)) {
13
+ (window as any).dataLayer = [];
14
+ this.dataLayer = (window as any).dataLayer;
15
+ }
16
+ }
17
+
18
+ /**
19
+ * Pushes an event payload into the dataLayer.
20
+ * @param eventName e.g. 'searchResultClick'
21
+ * @param payload additional key/value data
22
+ */
23
+ push(eventName: string, payload: Record<string, any> = {}): void {
24
+ this.dataLayer.push({ event: eventName, ...payload });
25
+ }
26
+ }
@@ -1,11 +1,14 @@
1
1
  import type { SearchLinkProps } from '../../types/search.types';
2
+ import { useSearchLogger } from '../../hooks';
2
3
  import './SearchLink.css';
3
4
 
4
5
  import Icon from '../../../Icon';
5
6
 
6
7
  const SearchLink = ({ icon, label, url, excerpt, resource }: SearchLinkProps) => {
8
+ const { handleClick } = useSearchLogger()
9
+
7
10
  return (
8
- <a className="n-search-link" href={url}>
11
+ <a className="n-search-link" href={url} onClick={handleClick}>
9
12
  {icon && (
10
13
  <span className="n-search-link-icon">
11
14
  <Icon name={icon} />
@@ -12,6 +12,7 @@ import {
12
12
  useSearchHotkeys,
13
13
  useSearchParams,
14
14
  useSearchToggles,
15
+ useSearchLogger,
15
16
  } from '../../hooks';
16
17
 
17
18
  import './SearchModal.css';
@@ -54,7 +55,8 @@ function SearchModal(props: Props = {className: '', children: null}) {
54
55
  const modalRef = useRef<HTMLDialogElement>(null);
55
56
  const containerRef = useClickOutside<HTMLDivElement>(closeSearch);
56
57
 
57
- useSearchToggles(isPagefindLoaded, openSearch);
58
+ useSearchLogger(state)
59
+ useSearchToggles(isPagefindLoaded, openSearch);
58
60
  useSearchParams(isPagefindLoaded, actions.setSearchTerm, openSearch);
59
61
  useSearchHotkeys(isPagefindLoaded, searchOpen, openSearch, closeSearch);
60
62
  useKeyboardNav(isPagefindLoaded, modalRef, searchOpen, closeSearch);
@@ -1,4 +1,5 @@
1
1
  export { useSearch } from '../hooks/useSearch';
2
+ export { useSearchLogger } from './useSearchLogger';
2
3
  export { useKeyboardNav } from '../hooks/useKeyboardNav';
3
4
  export { useSearchHotkeys } from '../hooks/useSearchHotkeys';
4
5
  export { useSearchParams } from '../hooks/useSearchParams';
@@ -0,0 +1,61 @@
1
+ import type { SearchState } from '../types/search.types';
2
+ import { useEffect, useRef, useCallback } from 'preact/hooks';
3
+ import { Logger } from '../../../../analytics/logger';
4
+
5
+ /**
6
+ * Hook that logs search-related events to your analytics Logger.
7
+ *
8
+ * It will:
9
+ * - Push a `searchQueryChanged` event whenever the search term changes.
10
+ * - Push a `searchNoResults` event whenever a non-empty query returns zero results.
11
+ * - Provide a click handler (`handleClick`) to log `searchResultClick` events.
12
+ *
13
+ * @param {SearchState} state - The current search state, containing:
14
+ * - `searchTerm` (string): the text the user has searched for.
15
+ * - `results` (Array<any>): the array of result objects returned.
16
+ * @returns {{ handleClick: (e: Event) => void }}
17
+ * An object with a `handleClick` function that you can attach to result links to log clicks.
18
+ */
19
+
20
+
21
+ export function useSearchLogger(state?: SearchState) {
22
+ const loggerRef = useRef<Logger>(new Logger());
23
+
24
+ // Log search query
25
+ useEffect(() => {
26
+ if (!state?.searchTerm) return
27
+
28
+ console.log('Pushing searchQueryChanged')
29
+ loggerRef.current.push('searchQueryChanged', { query: state?.searchTerm });
30
+ }, [state?.searchTerm]);
31
+
32
+ // Log zero‑hit searches
33
+ useEffect(() => {
34
+ if (!state?.results) return
35
+
36
+ if (state?.searchTerm && state.results.length === 0) {
37
+ console.log('Pushing searchNoResults')
38
+
39
+ loggerRef.current.push('searchNoResults', { query: state?.searchTerm });
40
+ }
41
+ }, [state?.results]);
42
+
43
+ const handleResultClick = useCallback((e: Event) => {
44
+ const anchor = (e.target as HTMLElement).closest('a');
45
+
46
+ if (!anchor) return
47
+
48
+ const label = anchor.querySelector('.n-search-link-label')?.innerHTML
49
+ const url = anchor.getAttribute('href')
50
+
51
+ loggerRef.current.push('searchResultClick', {
52
+ searchResultTitle: label,
53
+ searchResultURL: url,
54
+ });
55
+ }, []);
56
+
57
+
58
+ return {
59
+ handleClick: handleResultClick
60
+ };
61
+ }
@@ -1,132 +0,0 @@
1
- import { options as w } from "preact";
2
- var v, u, H, y, s = 0, C = [], n = w, A = n.__b, F = n.__r, g = n.diffed, k = n.__c, q = n.unmount, T = n.__;
3
- function d(_, t) {
4
- n.__h && n.__h(u, _, s || t), s = 0;
5
- var r = u.__H || (u.__H = { __: [], __h: [] });
6
- return _ >= r.__.length && r.__.push({}), r.__[_];
7
- }
8
- function S(_) {
9
- return s = 1, x(W, _);
10
- }
11
- function x(_, t, r) {
12
- var o = d(v++, 2);
13
- if (o.t = _, !o.__c && (o.__ = [r ? r(t) : W(void 0, t), function(c) {
14
- var e = o.__N ? o.__N[0] : o.__[0], f = o.t(e, c);
15
- e !== f && (o.__N = [f, o.__[1]], o.__c.setState({}));
16
- }], o.__c = u, !u.__f)) {
17
- var a = function(c, e, f) {
18
- if (!o.__c.__H) return !0;
19
- var m = o.__c.__H.__.filter(function(i) {
20
- return !!i.__c;
21
- });
22
- if (m.every(function(i) {
23
- return !i.__N;
24
- })) return !h || h.call(this, c, e, f);
25
- var E = o.__c.props !== c;
26
- return m.forEach(function(i) {
27
- if (i.__N) {
28
- var j = i.__[0];
29
- i.__ = i.__N, i.__N = void 0, j !== i.__[0] && (E = !0);
30
- }
31
- }), h && h.call(this, c, e, f) || E;
32
- };
33
- u.__f = !0;
34
- var h = u.shouldComponentUpdate, N = u.componentWillUpdate;
35
- u.componentWillUpdate = function(c, e, f) {
36
- if (this.__e) {
37
- var m = h;
38
- h = void 0, a(c, e, f), h = m;
39
- }
40
- N && N.call(this, c, e, f);
41
- }, u.shouldComponentUpdate = a;
42
- }
43
- return o.__N || o.__;
44
- }
45
- function G(_, t) {
46
- var r = d(v++, 3);
47
- !n.__s && b(r.__H, t) && (r.__ = _, r.u = t, u.__H.__h.push(r));
48
- }
49
- function I(_) {
50
- return s = 5, z(function() {
51
- return { current: _ };
52
- }, []);
53
- }
54
- function z(_, t) {
55
- var r = d(v++, 7);
56
- return b(r.__H, t) && (r.__ = _(), r.__H = t, r.__h = _), r.__;
57
- }
58
- function B() {
59
- for (var _; _ = C.shift(); ) if (_.__P && _.__H) try {
60
- _.__H.__h.forEach(l), _.__H.__h.forEach(p), _.__H.__h = [];
61
- } catch (t) {
62
- _.__H.__h = [], n.__e(t, _.__v);
63
- }
64
- }
65
- n.__b = function(_) {
66
- u = null, A && A(_);
67
- }, n.__ = function(_, t) {
68
- _ && t.__k && t.__k.__m && (_.__m = t.__k.__m), T && T(_, t);
69
- }, n.__r = function(_) {
70
- F && F(_), v = 0;
71
- var t = (u = _.__c).__H;
72
- t && (H === u ? (t.__h = [], u.__h = [], t.__.forEach(function(r) {
73
- r.__N && (r.__ = r.__N), r.u = r.__N = void 0;
74
- })) : (t.__h.forEach(l), t.__h.forEach(p), t.__h = [], v = 0)), H = u;
75
- }, n.diffed = function(_) {
76
- g && g(_);
77
- var t = _.__c;
78
- t && t.__H && (t.__H.__h.length && (C.push(t) !== 1 && y === n.requestAnimationFrame || ((y = n.requestAnimationFrame) || D)(B)), t.__H.__.forEach(function(r) {
79
- r.u && (r.__H = r.u), r.u = void 0;
80
- })), H = u = null;
81
- }, n.__c = function(_, t) {
82
- t.some(function(r) {
83
- try {
84
- r.__h.forEach(l), r.__h = r.__h.filter(function(o) {
85
- return !o.__ || p(o);
86
- });
87
- } catch (o) {
88
- t.some(function(a) {
89
- a.__h && (a.__h = []);
90
- }), t = [], n.__e(o, r.__v);
91
- }
92
- }), k && k(_, t);
93
- }, n.unmount = function(_) {
94
- q && q(_);
95
- var t, r = _.__c;
96
- r && r.__H && (r.__H.__.forEach(function(o) {
97
- try {
98
- l(o);
99
- } catch (a) {
100
- t = a;
101
- }
102
- }), r.__H = void 0, t && n.__e(t, r.__v));
103
- };
104
- var U = typeof requestAnimationFrame == "function";
105
- function D(_) {
106
- var t, r = function() {
107
- clearTimeout(o), U && cancelAnimationFrame(t), setTimeout(_);
108
- }, o = setTimeout(r, 100);
109
- U && (t = requestAnimationFrame(r));
110
- }
111
- function l(_) {
112
- var t = u, r = _.__c;
113
- typeof r == "function" && (_.__c = void 0, r()), u = t;
114
- }
115
- function p(_) {
116
- var t = u;
117
- _.__c = _.__(), u = t;
118
- }
119
- function b(_, t) {
120
- return !_ || _.length !== t.length || t.some(function(r, o) {
121
- return r !== _[o];
122
- });
123
- }
124
- function W(_, t) {
125
- return typeof t == "function" ? t(_) : t;
126
- }
127
- export {
128
- I as A,
129
- z as T,
130
- S as d,
131
- G as y
132
- };