"use client" import React, { useEffect, useMemo, useRef, useState } from "react" import { InstantSearch, SearchBox } from "react-instantsearch" import clsx from "clsx" import { SearchEmptyQueryBoundary } from "./EmptyQueryBoundary" import { SearchSuggestions, type SearchSuggestionType } from "./Suggestions" import { AlgoliaProps, useSearch } from "@/providers" import { checkArraySameElms } from "@/utils" import { SearchHitsWrapper } from "./Hits" import { SelectBadge, SpinnerLoading } from "@/components" import { useSearchNavigation, type OptionType } from "@/hooks" import { SearchFooter } from "./Footer" export type SearchProps = { algolia: AlgoliaProps isLoading?: boolean suggestions: SearchSuggestionType[] checkInternalPattern?: RegExp filterOptions?: OptionType[] } export const Search = ({ algolia, suggestions, isLoading = false, checkInternalPattern, filterOptions = [], }: SearchProps) => { const { isOpen, defaultFilters, searchClient, modalRef } = useSearch() const [filters, setFilters] = useState(defaultFilters) const searchBoxRef = useRef(null) const focusSearchInput = () => searchBoxRef.current?.querySelector("input")?.focus() useEffect(() => { if (!checkArraySameElms(defaultFilters, filters)) { setFilters(defaultFilters) } }, [defaultFilters]) useEffect(() => { if (isOpen && searchBoxRef.current) { focusSearchInput() } else if (!isOpen) { const focusedItem = modalRef.current?.querySelector( ":focus" ) as HTMLElement if ( focusedItem && focusedItem === searchBoxRef.current?.querySelector("input") ) { // remove focus focusedItem.blur() } } }, [isOpen]) const facetFilters = useMemo(() => { const filtersToUse = !filters.length || filters[0] === "all" ? filterOptions.map((option) => option.value) : filters return filtersToUse.map((filter) => "_tags:" + filter) }, [filters, defaultFilters]) useSearchNavigation({ getInputElm: () => searchBoxRef.current?.querySelector("input") as HTMLInputElement, focusInput: focusSearchInput, keyboardProps: { isLoading, }, }) return (
{filterOptions.length > 0 && ( setFilters(Array.isArray(value) ? [...value] : [value]) } addSelected={(value) => setFilters((prev) => [...prev, value])} removeSelected={(value) => setFilters((prev) => prev.filter((v) => v !== value)) } showClearButton={false} placeholder="Filters" handleAddAll={(isAllSelected: boolean) => { if (isAllSelected) { setFilters(defaultFilters) } else { setFilters(filterOptions.map((option) => option.value)) } }} className="px-docs_1 pt-docs_1 bg-medusa-bg-base z-10" /> )} {/* @ts-expect-error React v19 doesn't see this type as a React element */}
{/* @ts-expect-error React v19 doesn't see this type as a React element */} <>} resetIconComponent={() => ( Clear )} placeholder="Find something..." autoFocus formRef={searchBoxRef as React.RefObject} loadingIconComponent={() => } />
0 && "h-[calc(100%-95px)] lg:max-h-[calc(100%-140px)] lg:min-h-[calc(100%-140px)]", filterOptions.length === 0 && "h-[calc(100%-75px)] lg:max-h-[calc(100%-100px)] lg:min-h-[calc(100%-100px)]" )} > } >
) }