All files / src/components/SearchBar SearchSuggestions.tsx

0% Statements 0/12
0% Branches 0/9
0% Functions 0/3
0% Lines 0/11

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                                                                                                                                                                                                               
import {
  Box,
  UnorderedList,
  ListProps,
  forwardRef,
  Divider,
  Stack,
  Text,
} from "@chakra-ui/react";
import { FunctionComponent } from "react";
import { useHistory } from "react-router-dom";
import { useSearchBarState } from "./SearchBar";
import testIds from "./testIds";
import { ExtendedCatalogPackage } from "../../api/catalog-search";
import { eventName } from "../../contexts/Analytics/util";
import { useCatalogResults } from "../../hooks/useCatalogResults";
import { useDebounce } from "../../hooks/useDebounce";
import { getPackagePath } from "../../util/url";
import { Card, CardProps } from "../Card";
import { CDKTypeBadge } from "../CDKType";
import { SearchItem } from "../SearchItem";
 
/**
 * A suggestion component which can be used to extend the `<SearchBar />` behavior with a list of
 * recommended results
 * ```tsx
 * import { SearchBar, SearchSuggestions } from "components/SearchBar";
 *
 * <SearchBar>
 *   <SearchSuggestions />
 * </SearchBar>
 * ```
 */
export const SearchSuggestions: FunctionComponent = forwardRef<
  CardProps & ListProps,
  "ul"
>((props, ref) => {
  const { dataEvent, query, isOpen } = useSearchBarState();
  const debouncedQuery = useDebounce(query);
 
  const { push } = useHistory();
 
  const { page: recommendations } = useCatalogResults({
    limit: 5,
    offset: 0,
    query: debouncedQuery,
  });
 
  if (!isOpen || recommendations.length < 1 || !debouncedQuery) {
    return null;
  }
 
  return (
    <Card
      as={UnorderedList}
      data-testid={testIds.suggestionsList}
      left={0}
      ml={0}
      pos="absolute"
      pt={10}
      px={0}
      ref={ref}
      right={0}
      top={0}
      zIndex={2}
      {...props}
    >
      {recommendations.map((pkg: ExtendedCatalogPackage, i) => {
        const navigate = () => push(getPackagePath(pkg));
        const { constructFrameworks } = pkg;
 
        return (
          <>
            {i > 0 && <Divider mx={4} w="auto" />}
            <SearchItem
              data-event={
                dataEvent
                  ? eventName(dataEvent, "Suggestion", pkg.name)
                  : undefined
              }
              data-testid={testIds.suggestion}
              key={pkg.id}
              name={
                <Stack align="center" direction="row" spacing={4}>
                  <Box w="5.5rem">
                    <CDKTypeBadge
                      constructFrameworks={constructFrameworks}
                      w="min-content"
                    />
                  </Box>
                  <Text color="textPrimary">{pkg.name}</Text>
                </Stack>
              }
              onClick={navigate}
              py={2}
              textAlign="left"
            />
          </>
        );
      })}
    </Card>
  );
});