react-instantsearch-dom#SearchBox JavaScript Examples
The following examples show how to use
react-instantsearch-dom#SearchBox.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.js From my-personal-blog-gatsby with MIT License | 6 votes |
Search = ({ algolia }) => {
const searchClient = algoliasearch(algolia.appId, algolia.searchOnlyApiKey);
return (
<s.SearchWrapper>
<InstantSearch searchClient={searchClient} indexName={algolia.indexName}>
<SearchBox autoFocus translations={{ placeholder: 'Pesquisar...' }} />
<Stats
translations={{
stats(nbHits, timeSpentMs) {
return `${nbHits} resultados encontrados em ${timeSpentMs}ms`;
},
}}
/>
<Hits hitComponent={Hit} />
</InstantSearch>
</s.SearchWrapper>
);
}
Example #2
Source File: Algolia.js From gatsby-airtable-design-project with BSD Zero Clause License | 6 votes |
Search = () => {
return (
<Wrapper>
<Title title="Algolia Search" />
<InstantSearch
indexName={process.env.GATSBY_ALGOLIA_INDEX_NAME}
searchClient={searchClient}
>
<SearchBox />
<Container className="section-center">
<NewHits />
</Container>
</InstantSearch>
</Wrapper>
)
}
Example #3
Source File: index.jsx From elliot-serverless-ecommerce with MIT License | 6 votes |
Search = () => {
const [search, toggleSearch] = useState(false);
const handleSearchChange = e => {
if (e.target.value === "") {
return toggleSearch(false);
}
toggleSearch(true);
};
return (
<Wrapper>
<InstantSearch
searchClient={searchClient}
indexName={`elliot_product_index_${ENVIRONMENT || "production"}`}
>
<Configure
hitsPerPage={20}
filters={`'domain_id':${ELLIOT_DOMAIN_ID} AND 'filter_param':'PUBLISHED' AND 'productCheckouts.slug':${ELLIOT_STORE_FRONT_NAME}`}
/>
<SearchBox
autoFocus={false}
onClick={e => handleSearchChange(e)}
onChange={e => handleSearchChange(e)}
onReset={() => toggleSearch(false)}
/>
{search && <Results />}
</InstantSearch>
</Wrapper>
);
}
Example #4
Source File: PlayerSearch.js From fifa with GNU General Public License v3.0 | 6 votes |
render() {
const { theme } = this.context;
return (
<div
className="items-collection d-none d-sm-block"
style={{
background: theme.useFluentDesign ? theme.acrylicTexture80.background : 'none'
}}
>
<InstantSearch
indexName="dev_PLAYERS"
searchClient={customSearchClient}
stalledSearchDelay={500}
>
<SearchBox
showLoadingIndicator
translations={{
submitTitle: 'Submit your search query.',
resetTitle: 'Clear your search query.',
placeholder: 'Search players here...'
}}
onChange={e => this.setState({ searchParameter: e.target.value })}
/>
<this.PlayerHits />
</InstantSearch>
</div>
);
}
Example #5
Source File: index.js From gatsby-plugin-typesense with Apache License 2.0 | 6 votes |
export default function Home() {
const Hit = ({ hit }) => (
<p>
{hit.title} - {hit.description}
</p>
)
return (
<div>
<Header pageName="Home" />
<div data-typesense-field={"description"}>
This is some home page content
</div>
<InstantSearch searchClient={searchClient} indexName="pages_v1">
<SearchBox />
<Stats />
<Hits hitComponent={Hit} />
</InstantSearch>
<Footer />
</div>
)
}
Example #6
Source File: MobileSearch.component.jsx From nextjs-woocommerce with GNU General Public License v3.0 | 6 votes |
MobileSearch = () => {
const [search, setSearch] = useState(null);
const [hasFocus, sethasFocus] = useState(false);
return (
<div className="inline mt-4 md:hidden">
<InstantSearch
indexName={process.env.NEXT_PUBLIC_ALGOLIA_INDEX_NAME}
searchClient={searchClient}
>
<SearchBox
translations={{
submitTitle: 'Søk',
resetTitle: 'Slett søketekst',
placeholder: 'Søk etter produkter',
}}
className={`px-4 py-2 text-base bg-white border outline-none rounded ${
hasFocus ? 'border-black' : 'border-gray-400'
}`}
onFocus={() => {
sethasFocus(true);
}}
onBlur={() => {
sethasFocus(false);
}}
onReset={() => {
setSearch(null);
}}
onChange={(text) => {
setSearch(text.target.value);
}}
/>
{search && <Hits className="absolute" hitComponent={SearchResults} />}
</InstantSearch>
</div>
);
}
Example #7
Source File: Search.js From adarshaacharya.com.np with MIT License | 5 votes |
Search = ({ props }) => {
const { location } = props;
const [searchState, setSearchState] = React.useState(
urlToSearchState(location)
);
const onSearchStateChange = updatedSearchState => {
setSearchState(updatedSearchState);
};
const searchClient = algoliasearch(
process.env.GATSBY_ALGOLIA_APP_ID,
process.env.GATSBY_ALGOLIA_SEARCH_KEY
);
return (
<StyledSearch>
<InstantSearch
indexName={process.env.GATSBY_ALGOLIA_INDEX_NAME}
searchClient={searchClient}
searchState={searchState}
onSearchStateChange={onSearchStateChange}
>
<SearchBox
translations={{
placeholder: 'Search by title, tags or description..',
}}
/>
{searchState && searchState.query ? (
<>
<Stats
translations={{
stats(nbHits) {
return `${nbHits} Results found`;
},
}}
/>
<Hits hitComponent={Hit} />
</>
) : (
<Posts />
)}
</InstantSearch>
</StyledSearch>
);
}
Example #8
Source File: index.js From website with MIT License | 5 votes |
export default function Search({ indices, collapse, hitsAsGrid }) {
const [query, setQuery] = useState(``)
const [setFocus] = useState(false)
const searchClient = algoliasearch(
"V0X7Z4KE9D",
"544bec33383dc791bcbca3e1ceaec11b"
)
return (
<InstantSearch
searchClient={searchClient}
indexName={indices[0].name}
onSearchStateChange={({ query }) => {
if (typeof query !== "undefined") {
setQuery(query)
}
}}
>
<div tw="relative shadow appearance-none border rounded w-full py-3 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-inner rounded-r-none">
<SearchBox
tw="w-full px-8"
translations={{
placeholder: "Find analysis tools, formatters, and linters...",
}}
startValue=""
submit={
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 18 18"
>
<g
fill="none"
fillRule="evenodd"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="1.67"
transform="translate(1 1)"
>
<circle cx="7.11" cy="7.11" r="7.11" />
<path d="M16 16l-3.87-3.87" />
</g>
</svg>
}
/>
</div>
{query && (
<HitsWrapper
show={query.length > 0}
asGrid="false"
tw="max-h-screen overflow-scroll border shadow bg-white absolute w-full"
>
{indices.map(({ name, title, hitComp }) => (
<Index key={name} indexName={name}>
<Results>
<Hits hitComponent={hitComps[hitComp](() => setFocus(false))} />
</Results>
</Index>
))}
<PoweredBy />
</HitsWrapper>
)}
</InstantSearch>
)
}
Example #9
Source File: AlgoliaSearchBox.component.jsx From nextjs-woocommerce with GNU General Public License v3.0 | 5 votes |
AlgoliaSearchBox = () => {
const [search, setSearch] = useState(null);
const [hasFocus, sethasFocus] = useState(false);
return (
<div className="hidden mt-2 md:inline xl:inline">
<div className="">
<InstantSearch
indexName={process.env.NEXT_PUBLIC_ALGOLIA_INDEX_NAME}
searchClient={searchClient}
>
{/*We need to conditionally add a border because the element has position:fixed*/}
<SearchBox
aria-label="Søk her"
translations={{
submitTitle: 'Søk',
resetTitle: 'Slett søketekst',
placeholder: 'Søk etter produkter',
}}
className={`px-4 py-2 text-base bg-white border outline-none rounded ${
hasFocus ? 'border-black' : 'border-gray-400'
}`}
onFocus={() => {
sethasFocus(true);
}}
onBlur={() => {
sethasFocus(false);
}}
onReset={() => {
setSearch(null);
}}
onChange={(text) => {
setSearch(text.target.value);
}}
/>
{search && <Hits className="absolute" hitComponent={SearchResults} />}
</InstantSearch>
</div>
</div>
);
}
Example #10
Source File: AlgoliaProductList.jsx From emprezzo with MIT License | 4 votes |
AlgoliaProductList = ({ defaultFilter, defaultSearchTerm, itemsPerPage, hideLeftPanel, hideCTAButton, showClearFilter, facetsToShow, showSearchBox, showSearchSuggestions, searchIndexName, enableShopProductSwitch, enableCart, noResultMessage }) => {
const [currentIndexName, setCurrentIndexName] = React.useState(searchIndexName || `empProducts`)
const changeCurrentIndexName = (e) => { setCurrentIndexName(e.target.value); setCurrentSuggestionIndexName(getSuggestionIndex(e.target.value)); setSuggestionQuery(''); }
const getSuggestionIndex = (mainIndexName) => {
if (mainIndexName == 'empProducts') return ('empProducts_query_suggestions');
if (mainIndexName == 'uncommonry') return ('uncommonry_query_suggestions')
}
const [currentSuggestionIndexName, setCurrentSuggestionIndexName] = React.useState(getSuggestionIndex(currentIndexName))
const [suggestionQuery, setSuggestionQuery] = React.useState();
const algoliaClient = algoliasearch(
process.env.GATSBY_ALGOLIA_APP_ID,
process.env.GATSBY_ALGOLIA_SEARCH_KEY
);
const searchClient = {
search(requests) {
if (requests.length > 0 && defaultSearchTerm) requests[0].params.query = defaultSearchTerm
return algoliaClient.search(requests);
},
};
noResultMessage = noResultMessage || `No result found`;
enableCart = enableCart || false;
itemsPerPage = itemsPerPage || 12;
aa('init', {
appId: process.env.GATSBY_ALGOLIA_APP_ID,
apiKey: process.env.GATSBY_ALGOLIA_SEARCH_KEY
});
const [currentHitComponent, setCurrentHitComponent] = React.useState();
React.useEffect(() => {
if (currentIndexName == 'empProducts') setCurrentHitComponent(() => connectHitInsights(aa)(AlgoliaProductItem));
if (currentIndexName == 'uncommonry') setCurrentHitComponent(() => connectHitInsights(aa)(AlgoliaUncommonryItem));
if (currentIndexName == 'emails') setCurrentHitComponent(() => connectHitInsights(aa)(AlgoliaEmailsItem));
}, [currentIndexName]);
const AlgoliaSuggestions = ({ hit }) => {
return (
<a href="javascript:" onClick={() => setSuggestionQuery(hit.query)}>{hit.query}</a>
);
}
return (
<SearchWrapper>
{!enableCart &&
<Global
styles={css`
.cart-section {
display: none;
}
`}
/>
}
<InstantSearch indexName={currentIndexName} searchClient={searchClient}>
<VirtualSearchBox defaultRefinement={suggestionQuery} />
{!hideLeftPanel &&
<LeftPanel>
{showClearFilter &&
<ClearRefinements />
}
{facetsToShow && facetsToShow.indexOf("category") >= 0 &&
<>
<FilterHeading>Category</FilterHeading>
<RefinementList attribute="shopCategory" showMore='true' limit='5' />
</>
}
{facetsToShow && facetsToShow.indexOf("brands") >= 0 && currentIndexName != 'uncommonry' &&
<>
<FilterHeading>Brands</FilterHeading>
<RefinementList attribute="shopName" showMore='true' limit='5' />
</>
}
{facetsToShow && facetsToShow.indexOf("payments") >= 0 && currentIndexName == 'uncommonry' &&
<>
<FilterHeading>Payments</FilterHeading>
<RefinementList
attribute="shopifyPay"
transformItems={items =>
items.filter(item => (item.label == '1')).map(item => ({
...item,
label: "Shop Pay",
}))
}
/>
<RefinementList
attribute="paypal"
transformItems={items =>
items.filter(item => (item.label == '1')).map(item => ({
...item,
label: "Paypal",
}))
}
/>
<RefinementList
attribute="applePay"
transformItems={items =>
items.filter(item => (item.label == '1')).map(item => ({
...item,
label: "Apple Pay",
}))
}
/>
<RefinementList
attribute="amazonPay"
transformItems={items =>
items.filter(item => (item.label == '1')).map(item => ({
...item,
label: "Amazon Pay",
}))
}
/>
</>
}
{facetsToShow && facetsToShow.indexOf("pricerangeslider") >= 0 && currentIndexName == 'uncommonry' &&
<>
<FilterHeading>Average Price</FilterHeading>
<AlgoliaRangeSlider attribute="price" />
</>
}
{facetsToShow && facetsToShow.indexOf("prices") >= 0 && currentIndexName == 'empProducts' &&
<>
<FilterHeading>Prices</FilterHeading>
<NumericMenu
attribute="price"
items={[
{ label: 'All' },
{ label: 'Under $50', end: 50 },
{ label: '$50 - $100', start: 50, end: 100 },
{ label: '$100 - $200', start: 100, end: 200 },
{ label: '$200+', start: 200 },
]}
/>
</>
}
{/*
{facetsToShow && facetsToShow.indexOf("giftcard") >= 0 && currentIndexName == 'empProducts' &&
<>
<FilterHeading>Gift Card</FilterHeading>
<RefinementList
attribute="name"
transformItems={items =>
items.filter(item => (item.label.toLowerCase().indexOf('gift') >= 0))
}
/>
</>
}
{facetsToShow && facetsToShow.indexOf("gifimage") >= 0 && currentIndexName == 'empProducts' &&
<>
<FilterHeading>GIF</FilterHeading>
<RefinementList
attribute="imageURL"
transformItems={items =>
items.filter(item => (item.label.indexOf('.gif') >= 0)).map(item => ({
...item,
label: "GIF",
}))
}
/>
</>
}
*/}
{facetsToShow && facetsToShow.indexOf("storeoffers") >= 0 &&
<>
<FilterHeading>Store Offers</FilterHeading>
<RefinementList
attribute="freeShipMin"
transformItems={items =>
items.filter(item => (item.label == 0)).map(item => ({
...item,
label: "Free Shipping",
}))
}
/>
<RefinementList
attribute="returnShipFree"
transformItems={items =>
items.filter(item => (item.label == 'Yes')).map(item => ({
...item,
label: "Free Returns",
}))
}
/>
</>
}
</LeftPanel>
}
<RightPanel>
<Configure clickAnalytics={true} hitsPerPage={itemsPerPage} filters={defaultFilter} />
<div class="searchline">
<div class="indexSelect">
{enableShopProductSwitch &&
<div style={{ paddingBottom: '0.75rem' }}>
<select value={currentIndexName} onChange={changeCurrentIndexName}>
<option value="uncommonry">Shops</option>
<option value="empProducts">Products</option>
</select>
</div>
}
</div>
{facetsToShow && facetsToShow.indexOf("onsale") >= 0 &&
<div class="saleFacet">
<RefinementList
attribute="onSale"
transformItems={items =>
items.filter(item => (item.label == '1')).map(item => ({
...item,
label: "On Sale",
}))
}
/>
</div>
}
<div class="searchContainer">
{showSearchBox &&
<>
<SearchBox defaultRefinement={suggestionQuery} />
</>
}<br style={{ clear: 'both' }} />
{showSearchSuggestions && currentSuggestionIndexName &&
<span style={{ 'font-weight': 'bold', 'padding': '0 1em 1em 0' }}>Trending </span>
}
{showSearchSuggestions && currentSuggestionIndexName &&
<div className="suggestions">
<InstantSearch
searchClient={searchClient}
indexName={currentSuggestionIndexName}
>
<Configure hitsPerPage={5} />
<InfiniteHits hitComponent={AlgoliaSuggestions} />
</InstantSearch>
</div>
}
</div>
{!hideCTAButton &&
<div class="giftCard">
<BuyGiftCard />
</div>
}
</div>
<AlgoliaStateResults noResultMessage={noResultMessage} />
<Hits hitComponent={currentHitComponent} />
<Pagination />
</RightPanel>
</InstantSearch>
</SearchWrapper>
);
}
Example #11
Source File: index.js From showcase-nextjs-typesense-ecommerce-store with Apache License 2.0 | 4 votes |
export default function Home({
searchClient = typesenseInstantsearchAdapter.searchClient,
searchState,
resultsState,
onSearchParameters,
widgetsCollector,
...props
}) {
return (
<div>
<Head>
<title>Ecommerce Store with Typesense + Next.js + Vercel</title>
<link rel="icon" href="/favicon.png"/>
</Head>
<main>
<InstantSearch indexName="products"
{...props}
searchClient={searchClient}
searchState={searchState}
resultsState={resultsState}
onSearchParameters={onSearchParameters}
widgetsCollector={widgetsCollector}>
<div className="container-fluid px-md-5 pt-4">
<div className="row d-flex align-items-center">
<div className="col-md">
<h1 className="display-6">
Ecommerce Store with Typesense + Next.js + Vercel
</h1>
</div>
<div className="col-md-2 d-none d-md-block">
<SearchBox/>
</div>
</div>
<div className="lead mt-2">
Besides search experiences,
Typesense can also be used to build <strong className="marker-highlight">blazing fast</strong>, <strong
className="marker-highlight">browsing
experiences</strong> like
product listing pages in an ecommerce
store.
</div>
<ul className="lead mt-1">
<li>Product data to render the grid is fetched by the front-end from a <strong>Geo-Distributed Typesense
Cloud cluster</strong> with nodes in Oregon, Frankfurt and Mumbai.
</li>
{/* eslint-disable-next-line react/no-unescaped-entities */}
<li>Product API Requests are routed to the node that is closest to the user's location, like a CDN. Since
data is geographically distributed, this reduces latency even more for your users, as they browse
products.
</li>
<li>The front-end uses Next.js, is statically generated and is hosted on Vercel.</li>
<li>See <a href="https://github.com/typesense/showcase-nextjs-typesense-ecommerce-store" target="_blank"
rel="noreferrer">Source
Code</a>.
</li>
</ul>
<div className="row mt-4">
<div className="col-md-3 pr-md-5">
<h5>Browse by Categories</h5>
<HierarchicalMenu
className="mt-3"
attributes={[
'categories.lvl0',
'categories.lvl1',
'categories.lvl2',
'categories.lvl3',
]}
showParentLevel={true}
rootPath={"Cell Phones"}
limit={50}
/>
<h5 className="mt-5">Filter by Brands</h5>
<RefinementList
className="mt-3"
attribute="brand"
limit={10}
showMore={true}
showMoreLimit={50}
searchable={true}
transformItems={items =>
items.sort((a, b) => a.label > b.label ? 1 : -1)
}
/>
<div className="mt-2"> </div>
<ToggleRefinement
className="mt-5"
attribute="free_shipping"
label="Free Shipping"
value={true}
/>
<div className="mt-1"> </div>
<h5 className="mt-5">Filter by Price</h5>
<RangeSlider attribute="price"/>
<div className="mt-1"> </div>
<h5 className="mt-5">Filter by Rating</h5>
<RatingMenu
className="mt-3"
attribute="rating"
/>
<div className="mt-1"> </div>
<ClearRefinements className="mt-5"/>
</div>
<div className="col-md">
<div className="row mt-5 mt-md-0">
<div className="col-md">
<div className="row">
<div className="col-md-4">
</div>
<div className="col-md-8 d-flex justify-content-end align-items-center">
<Stats translations={{
stats(nbHits, processingTimeMS) {
let hitCountPhrase
if (nbHits === 0) {
hitCountPhrase = 'No products'
} else if (nbHits === 1) {
hitCountPhrase = '1 product'
} else {
hitCountPhrase = `${nbHits.toLocaleString()} products`
}
return `${hitCountPhrase} found in ${processingTimeMS.toLocaleString()}ms`;
},
}}/>
<HitsPerPage
className="ms-4"
items={[
{label: '9 per page', value: 9},
{label: '18 per page', value: 18}
]}
defaultRefinement={9}
/>
<SortBy
items={[
{label: 'Relevancy', value: 'products'},
{label: 'Price (asc)', value: 'products/sort/price:asc'},
{label: 'Price (desc)', value: 'products/sort/price:desc'},
]}
defaultRefinement="products"
/>
</div>
</div>
</div>
</div>
<div className="row mt-1">
<div className="col-sm">
<Hits hitComponent={Hit}/>
</div>
</div>
<div className="row">
<div className="col-sm">
<Pagination/>
</div>
</div>
</div>
</div>
</div>
</InstantSearch>
</main>
</div>
)
}