All files / src/components/SearchBox index.tsx

55.55% Statements 10/18
45.45% Branches 5/11
37.5% Functions 3/8
55.55% Lines 10/18

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110                                2x   2x   2x 2x         2x                 2x 6x               6x     6x                                                                                   6x                                        
import React, { Component } from "react";
import { navigate, withPrefix } from "gatsby";
import "./index.scss";
import ReactGA from "react-ga4";
import {
  SearchClient,
  SearchIndex,
} from "algoliasearch/dist/algoliasearch-lite";
import { RequestOptions } from "@algolia/transporter";
import { SearchOptions } from "@algolia/client-search";
 
let algoliasearch: CallableFunction;
let autocomplete: CallableFunction;
let client: SearchClient;
let index: SearchIndex;
 
Eif (typeof window !== "undefined") {
  // eslint-disable-next-line global-require
  algoliasearch = require("algoliasearch/lite");
  // eslint-disable-next-line global-require
  autocomplete = require("autocomplete.js");
  client = algoliasearch(
    process.env.GATSBY_ALGOLIA_APP_ID || process.env.STORYBOOK_ALGOLIA_APP_ID,
    process.env.GATSBY_ALGOLIA_SEARCH_API_KEY ||
      process.env.STORYBOOK_ALGOLIA_SEARCH_API_KEY
  );
  index = client.initIndex(
    process.env.GATSBY_ALGOLIA_INDEX_NAME ||
      process.env.STORYBOOK_ALGOLIA_INDEX_NAME ||
      "posts"
  );
}
 
// https://github.com/algolia/algoliasearch-client-javascript/issues/1152
const source =
  (index: SearchIndex, parameters: RequestOptions & SearchOptions) =>
  (query: string, cb: CallableFunction) =>
    index
      .search(query, parameters)
      .then((res) => cb(res.hits, res))
      .catch((err) => cb([], err));
 
class SearchBox extends Component {
  componentDidMount() {
    Iif (typeof window === "undefined") {
      return;
    }
    autocomplete("#algolia-search-input", { hint: false }, [
      {
        source: source(index, { hitsPerPage: 3 }),
        displayKey: "title",
        templates: {
          suggestion({
            _highlightResult: { title, description },
          }: {
            _highlightResult: {
              title: {
                value: string;
              };
              description: {
                value: string;
              };
            };
          }) {
            return `
                <b><p class="title">${title.value}</p></b>
                <p class="description">${description.value}</p>
                `;
          },
          footer:
            '<div class="branding"><img src="https://i.imgur.com/HXG1uHY.png" alt="Powered by Algolia" decoding="async" /></div>',
        },
      },
    ]).on(
      "autocomplete:selected",
      (event: { _args: { path: string }[] }, suggestion: { url: string }) => {
        navigate(suggestion.url);
        ReactGA.event({
          category: "User",
          // eslint-disable-next-line no-underscore-dangle
          action: `Click Searchbox item: ${event._args[0].path}`,
        });
        // eslint-disable-next-line no-underscore-dangle
        navigate(withPrefix(event._args[0].path));
      }
    );
  }
 
  render() {
    return (
      <div>
        <p>
          <label htmlFor="algolia-search-input">
            <span className="icon-search" />
            &nbsp;SearchBox
          </label>
        </p>
        <input
          type="search"
          id="algolia-search-input"
          placeholder="Enter the keyword..."
          data-testid="algolia-search-input"
        />
      </div>
    );
  }
}
 
export default SearchBox;