Skip to content

Commit

Permalink
feat: Algolia infinite scroll (#1984)
Browse files Browse the repository at this point in the history
* Adding infinite scroll
* Add ability to specify the placeholder for search box
* Wire up toggle to show results on empty query
  • Loading branch information
ryscheng authored Aug 23, 2024
1 parent d1145ec commit c76e35e
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 11 deletions.
41 changes: 30 additions & 11 deletions apps/frontend/components/widgets/algolia.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import "instantsearch.css/themes/algolia.css";
import algoliasearch from "algoliasearch/lite";
import React, { ReactElement } from "react";
import { SearchBox, useHits } from "react-instantsearch";
import React, { ReactElement, useEffect, useRef } from "react";
import { SearchBox, useInfiniteHits } from "react-instantsearch";
import { InstantSearchNext } from "react-instantsearch-nextjs";
import { DataProvider } from "@plasmicapp/loader-nextjs";
import {
Expand All @@ -14,26 +14,46 @@ import {

const searchClient = algoliasearch(ALGOLIA_APPLICATION_ID, ALGOLIA_API_KEY);
const PLASMIC_KEY = "searchItem";
const DEFAULT_PLACEHOLDER = "Search...";

type AlgoliaSearchListProps = {
className?: string; // Plasmic CSS class
children?: ReactElement; // Show this per item
indexName?: string; // Choose a custom Algolia index
placeholder?: string; // Placeholder for search box
showResultsOnEmptyQuery?: boolean; // Show some results even if no query
};

function HitsContainer(props: AlgoliaSearchListProps) {
const { children } = props;
const { hits, results } = useHits();
//console.log(hits);
const { children, showResultsOnEmptyQuery } = props;
const { results, items, isLastPage, showMore } = useInfiniteHits();
const sentinelRef = useRef(null);
//console.log(results);

useEffect(() => {
if (sentinelRef.current !== null) {
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting && !isLastPage) {
showMore();
}
});
});
observer.observe(sentinelRef.current);
return () => {
observer.disconnect();
};
}
}, [isLastPage, showMore]);

return (
<div>
{results?.query &&
hits.map((hit) => (
{(showResultsOnEmptyQuery || results?.query) &&
items.map((hit) => (
<div key={hit.objectID}>
<DataProvider name={PLASMIC_KEY} data={hit}>
{children}
<div ref={sentinelRef} aria-hidden="true" />
</DataProvider>
</div>
))}
Expand All @@ -47,12 +67,11 @@ function HitsContainer(props: AlgoliaSearchListProps) {
function AlgoliaSearchList(props: AlgoliaSearchListProps) {
const {
className,
//children: rawChildren,
indexName: rawIndexName,
//showResultsOnEmptyQuery,
placeholder: rawPlaceholder,
} = props;
//const children = rawChildren ?? <SearchIcon />;
const indexName = rawIndexName ?? ALGOLIA_INDEX;
const placeholder = rawPlaceholder ?? DEFAULT_PLACEHOLDER;

return (
<div className={className}>
Expand All @@ -61,7 +80,7 @@ function AlgoliaSearchList(props: AlgoliaSearchListProps) {
indexName={indexName}
insights
>
<SearchBox placeholder={"Search projects..."} autoFocus={true} />
<SearchBox placeholder={placeholder} autoFocus={true} />
<HitsContainer {...props} />
</InstantSearchNext>
</div>
Expand Down
1 change: 1 addition & 0 deletions apps/frontend/plasmic-init-client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ PLASMIC.registerComponent(
defaultValue: ALGOLIA_INDEX,
helpText: "Algolia index",
},
placeholder: "string",
showResultsOnEmptyQuery: {
type: "boolean",
helpText: "Show some results even if user has no query",
Expand Down

0 comments on commit c76e35e

Please sign in to comment.