Documentation
Latest
Latest
  • Reactify Search
  • Getting Started
  • Guides
    • Upgrade workflow
    • Upgrade v4 to v5
    • Liquid Theme
    • SSR
  • Release Notes
  • Troubleshooting
    • Categorising Issues
    • Common Issues
    • Debugger
    • CodeSandbox
    • Further Troubleshooting
  • Security Overview
  • Components
    • Component Basics
    • ReactifySearchProvider
    • Sensors
    • Search
    • SortBy
    • ClearAll
    • FiltersSelected
    • Filters
    • Filter
    • Results
    • Stats
    • Suggestions
    • CustomComponent
  • Hooks
    • useSearch
    • useSortBy
    • useFilters
    • useResults
  • Classes
    • ReactifySearchLiquidFactory
Powered by GitBook
On this page
  • Purpose
  • Usage
  • Props

Was this helpful?

  1. Components

Results

The Result component renders the search results and pagination content.

Purpose

The Results component renders the result cards and pagination components.

Usage

See the useResults page for more usage details.

import React from "react";
import { Results } from "@usereactify/search";

import { ExampleResultCardProduct } from "./ExampleResultCardProduct";
import { ExampleResultCardCallout } from "./ExampleResultCardCallout";
import { ExampleResultPaginationNextPrev } from "./ExampleResultPaginationNextPrev";
import { ExampleResultPaginationNumbered } from "./ExampleResultPaginationNumbered";
import { ExampleResultPaginationLoadMore } from "./ExampleResultPaginationLoadMore";
import { ExampleResultPaginationInfiniteScroll } from "./ExampleResultPaginationInfiniteScroll";

export const Component: React.FC = () => {
  return (
    <Results
      listStyle={{
        display: "grid",
        gap: "10px",
        gridTemplateColumns: "repeat(4, minmax(0, 1fr))",
      }}
      gridColumns={4}
      renderResultCardProduct={ExampleResultCardProduct}
      renderResultCardCallout={ExampleResultCardCallout}
      renderPaginationNextPrev={ExampleResultPaginationNextPrev}
      renderPaginationNumbered={ExampleResultPaginationNumbered}
      renderPaginationLoadMore={ExampleResultPaginationLoadMore}
      renderPaginationInfiniteScroll={ExampleResultPaginationInfiniteScroll}
    />
  );
};
import React from "react";
import { ResultCardProductProps } from "@usereactify/search";

export type ExampleResultCardProductProps = React.ComponentProps<
  NonNullable<ResultCardProductProps["render"]>
>;

export const ExampleResultCardProduct: React.FC<ExampleResultCardProductProps> =
  (props) => {
    return (
      <div ref={props.itemRef} className="rs__result-card-product">
        <a
          className="rs__result-card-product__link"
          onClick={props.handleClick}
          href={`/products/${props.product.handle}`}
        >
          {props.product.image && (
            <img
              className="rs__result-card-product__image"
              src={props.product.image}
              width="100%"
            />
          )}
          <span className="rs__result-card-product__title">
            {props.product.title}
          </span>
        </a>
        <span className="rs__result-card-product__price">
          {props.formattedPrice}
        </span>
        {props.onSale && (
          <span
            className="rs__result-card-product__price-sale"
            style={{
              textDecoration: "line-through",
            }}
          >
            {props.formattedCompareAtPrice}
          </span>
        )}
      </div>
    );
  };
import React from "react";
import { ResultCardCalloutProps } from "@usereactify/search";

export type ExampleResultCardCalloutProps = React.ComponentProps<
  NonNullable<ResultCardCalloutProps["render"]>
>;

export const ExampleResultCardCallout: React.FC<ExampleResultCardCalloutProps> =
  (props) => {
    const styleProp = React.useMemo<React.HTMLAttributes<HTMLElement>["style"]>(
      () => ({
        gridRow: `span ${props.callout.displayRows ?? 1}`,
        gridColumn: `span ${props.callout.displayColumns ?? 1}`,
      }),
      [props.callout]
    );

    return (
      <div
        className="rs__result-card-callout"
        ref={props.itemRef}
        style={styleProp}
      >
        <a
          className="rs__result-card-callout__link"
          onClick={props.handleClick}
          {...(!!props.callout.link && { href: props.callout.link })}
        >
          {props.callout.desktopImage && (
            <img
              className="rs__result-card-callout__image"
              src={props.callout.desktopImage}
              width="100%"
            />
          )}
          <span className="rs__result-card-callout__title">
            {props.callout.title}
          </span>
        </a>
      </div>
    );
  };
import React from "react";
import { ResultPaginationNumberedProps } from "@usereactify/search";

export type ExampleResultPaginationNumberedProps = React.ComponentProps<
  NonNullable<ResultPaginationNumberedProps["render"]>
>;

export const ExampleResultPaginationNumbered: React.FC<ExampleResultPaginationNumberedProps> =
  (props) => {
    return (
      <nav className="rs__pagination__nav">
        {props.currentPage > 0 && (
          <a
            className="rs__pagination__prev-link"
            rel="prev"
            href={props.buildPagePath(props.currentPage)}
            onClick={(event) => props.handlePreviousPage(event)}
          >
            {"Prev"}
          </a>
        )}
        {!props.pagesToShow.includes(0) && (
          <a
            className="rs__pagination__pagenumber-link"
            href={props.buildPagePath(1)}
            onClick={(event) => props.handlePageChange(0, event)}
            rel={0 === props.currentPage - 1 ? `prev` : undefined}
          >
            {"1"}
          </a>
        )}
        {!props.pagesToShow.includes(1) && <span>...</span>}
        {props.pagesToShow.map((page) =>
          page === props.currentPage ? (
            <span className="rs__pagination__pagenumber-active" key={page + 1}>
              {page + 1}
            </span>
          ) : (
            <a
              className="rs__pagination__pagenumber-link"
              key={page + 1}
              href={props.buildPagePath(page + 1)}
              onClick={(event) => props.handlePageChange(page, event)}
              rel={
                page === props.currentPage + 1
                  ? `next`
                  : page === props.currentPage - 1
                  ? `prev`
                  : undefined
              }
            >
              {page + 1}
            </a>
          )
        )}
        {!props.pagesToShow.includes(props.totalPages - 2) && <span>...</span>}
        {!props.pagesToShow.includes(props.totalPages - 1) && (
          <a
            className="rs__pagination__pagenumber-link"
            href={props.buildPagePath(props.totalPages)}
            onClick={(event) =>
              props.handlePageChange(props.totalPages - 1, event)
            }
            rel={
              props.totalPages - 1 === props.currentPage + 1
                ? `next`
                : props.totalPages - 1 === props.currentPage - 1
                ? `prev`
                : undefined
            }
          >
            {props.totalPages}
          </a>
        )}
        {props.currentPage + 1 < props.totalPages && (
          <a
            className="rs__pagination__next-link"
            rel="next"
            href={props.buildPagePath(props.currentPage + 2)}
            onClick={(event) => props.handleNextPage(event)}
          >
            {"Next"}
          </a>
        )}
      </nav>
    );
  };
import React from "react";
import { ResultPaginationNextPrevProps } from "@usereactify/search";

export type ExampleResultPaginationNextPrevProps = React.ComponentProps<
  NonNullable<ResultPaginationNextPrevProps["render"]>
>;

export const ExampleResultPaginationNextPrev: React.FC<ExampleResultPaginationNextPrevProps> =
  (props) => {
    return (
      <nav className="rs__pagination__nav">
        {props.hasPreviousPage && (
          <a
            className="rs__pagination__prev-link"
            rel="prev"
            onClick={props.handlePreviousPage}
            href={props.buildPagePath(props.actualCurrentPage - 1)}
          >
            {"Prev"}
          </a>
        )}
        {props.hasNextPage && (
          <a
            className="rs__pagination__next-link"
            rel="next"
            onClick={props.handleNextPage}
            href={props.buildPagePath(props.actualCurrentPage + 1)}
          >
            {"Next"}
          </a>
        )}
      </nav>
    );
  };
import React from "react";
import { ResultPaginationLoadMoreProps } from "@usereactify/search";

export type ExampleResultPaginationLoadMoreProps = React.ComponentProps<
  NonNullable<ResultPaginationLoadMoreProps["render"]>
>;

export const ExampleResultPaginationLoadMore: React.FC<ExampleResultPaginationLoadMoreProps> =
  (props) => {
    return (
      <button
        className="rs__pagination__loadmore-button"
        onClick={() => props.handleLoadMore()}
        disabled={!props.hasMore}
      >
        {"Load more"}
      </button>
    );
  };
import React from "react";
import { ResultPaginationInfiniteScrollProps } from "@usereactify/search"";

export type ExampleResultPaginationInfiniteScrollProps = React.ComponentProps<
  NonNullable<ResultPaginationInfiniteScrollProps["render"]>
>;

export const ExampleResultPaginationInfiniteScroll: React.FC<ExampleResultPaginationInfiniteScrollProps> =
  (props) => {
    if (props.loading) {
      return (
        <div className="rs__pagination__infinitescroll-loading">
          {"Loading..."}
        </div>
      );
    }

    return null;
  };

Props

type ResultsProps = {
  /** Style prop for the list wrapper */
  listStyle?: React.HTMLAttributes<HTMLElement>["style"];
  /** Classname prop for the list wrapper */
  listClassName?: string;
  /** Render method called when an error occurs */
  renderError?: React.FC<{ error: ReactivesearchError }>;
  /** Render method called while loading for the first time */
  renderLoading?: React.FC;
  /** Render method called when no results are found */
  renderNoResults?: React.FC;
  /** Render method called once for each product result */
  renderResultCardProduct?: React.FC<
    ReturnType<typeof useProductPrice> & {
      pagePosition: number;
      document: ResultProduct;
      product: ResultProduct;
      itemRef: (node?: Element | null) => void;
      handleClick: () => void;
    }
  >;
  /** Render method called once for each callout result */
  renderResultCardCallout?: React.FC<{
    pagePosition: number;
    document: ResultCallout;
    callout: ResultCallout["callout"];
    itemRef: (node?: Element | null) => void;
    handleClick: () => void;
  }>;
  /** Render method called for pagination type "pagination" */
  renderPaginationNumbered?: React.FC<ReturnType<typeof usePagination>>;
  /** Render method called for pagination type "next_prev" */
  renderPaginationNextPrev?: React.FC<ReturnType<typeof usePagination>>;
  /** Render method called for pagination type "load_more" */
  renderPaginationLoadMore?: React.FC<ReturnType<typeof usePaginationLoadable>>;
  /** Render method called for pagination type "infinite_scroll" */
  renderPaginationInfiniteScroll?: React.FC<
    ReturnType<typeof usePaginationLoadable>
  >;
  /** Used to determine which filler callouts to use when there is an uneven grid */
  gridColumns?: number;
  /** Advanced Usage: Override the default amount of results per page */
  pageSize?: number;
  /** Advanced Usage: Override the default scrollTarget used to determine when infinite load should be triggered (infinite scroll) */
  infiniteScrollContainer?: React.ComponentProps<
    typeof ReactiveList
  >["scrollTarget"];
  /** Advanced Usage: Provide a specific result position to trigger loading more results (infinite scroll) */
  infiniteScrollPosition?: number;
  /** Advanced Usage: Shows subsequent loading states after initial results are loaded */
  showSubsequentLoadingStates?: boolean;
};
PreviousFilterNextStats

Last updated 6 months ago

Was this helpful?