1.1.4 • Published 3 years ago

wmk-search v1.1.4

Weekly downloads
-
License
ISC
Repository
-
Last release
3 years ago

wmk-search

Helps create instant feedback search given a search index from a general GraphQL query of plural content models. Search prompt and results appear in an overlay drawer.

Components

There are two main components and a file with a couple other default utility components (which can be replaced by components of your choice).

SeachSliderOpen

This component renders the button / icon that initiates the search process.

It uses the following props:

interface SearchSliderOpenProps {
  isSearchOpen: boolean;
  setIsSearchOpen: React.Dispatch<React.SetStateAction<boolean>>;
  className?: string;
  children: React.ReactNode;
  style?: CSS.StandardProperties;
}

It is important that a parent component declares and manages the isSearchOpen and setIsSearchOpen state variables. These variables track and modify the open state of the search drawer component.

SearchSliderDrawer

This is where most of the magic happens, and the component was designed to be as flexible as possible, thus there are a lot of props / configuration options:

interface SearchSliderDrawerProps {
  isSearchOpen: boolean;
  setIsSearchOpen: React.Dispatch<React.SetStateAction<boolean>>;
  query: SearchIndexQuery;
  Result?: ({ result }: { result: SearchLink }) => JSX.Element;
  CloseIcon?: () => JSX.Element;
  className?: string;
  style?: CSS.StandardProperties;
  useAlgorithm?: (
    event: React.ChangeEvent<HTMLInputElement>,
    setSearchKey: React.Dispatch<React.SetStateAction<string>>,
    index: SearchIndex,
    setSearchResults: React.Dispatch<React.SetStateAction<IndexedSearch[]>>
  ) => void;
  resultConversion: (results: IndexedSearch) => SearchLink;
}

searchKey, setSearchKey, searchResults and setSearchResults are all managed internally, and do not need to be declared.

[searchKey, setSearchKey];

These variable track and modify the search query the user types into the search input.

[searchResults, setSearchResults];

These variables store and manage the array of objects that match the search key.

query: SearchIndexQuery;

This is the result of a query on several "all" nodes. Because we are potentially querying a lot of data, rather than using full fragments, queries should contain just enough data for search comparison and to generate the result link. You may want to query things such as thumbnail images or descriptions, but the more data you query, the more data and processor intensive using search will be. Example query that matches the SearchIndexQuery type definition:

{
  blog: allContentfulBlog {
    edges {
      node {
        title
        slug
      }
    }
  }
  files: allContentfulAsset {
    edges {
      node {
        title
        url
      }
    }
  }
  news: allContentfulNews {
    edges {
      node {
        title
        slug
      }
    }
  }
}

Using the graphql aliases is helpful, as the resultant IndexedSearch will have a type property that corresponds to the topmost name of every graph

You would then instantiate the SearchIndex class with your query data:

new SearchIndex(query);

The resultConversion method is important, it is what you use to process raw query data and return something that matches the SearchLink interface:

export interface SearchLink {
  to: string;
  text: string;
  target?: "blank" | "self";
}

The idea is to map over each item within the IndexedSearch array. There should be enough information to tell which __typename each result initiated from so you can properly construct the to and text strings. T

The and components render each individual result (given SearchLink data), and the button / icon that will close the SearchDrawer.

useAlgorithim

If you want to modify the default search behavior beyond just checking for entry titles, there is the useAlgorithim method. With this hook, you recieve the input event, a setter to modify value the input is hooked up to, the search index, and a setter to modify the search results.

Example: Modifying the search algorithm to compare titles and a stringified array of keywords

<SearchDrawer
  useAlgorithm={(e, setKey, index, setResults) => {
    const search = e.currentTarget.value;
    const results = index.index.filter((item) => {
      // if keywords do not exist, return an empty array
      const keywords = item.node?.keywords ? item.node.keywords : [];
      // join the arry to the title string
      const searchString = item.node.title + " " + keywords.join(", ");
      // set up a regular expression to match the search query, case insensitive
      const regex = new RegExp(search, "i");
      // if there is a match, return the data from the search index
      return Array.isArray(searchString.match(regex));
    });
    setResults(results);
    setKey(search);
  }}
/>
1.1.4

3 years ago

1.1.3

3 years ago

1.1.2

3 years ago

1.1.1

3 years ago

1.1.0

3 years ago

1.0.11

3 years ago

1.0.10

3 years ago

1.0.9

3 years ago

1.0.8

3 years ago

1.0.7

3 years ago

1.0.6

3 years ago

1.0.5

3 years ago

1.0.4

3 years ago

1.0.3

3 years ago

1.0.2

3 years ago

1.0.1

3 years ago

1.0.0

3 years ago