1ページあたりの表示件数
最終更新: 2022年02月11日
概要
HitsPerPageのカスタムウィジェットを作成します。
カスタムウィジェットの作成
事前に Tailwind CSS と Headless UIの導入が必要です。
components/custom-search-box.tsximport { Listbox, Transition } from '@headlessui/react'; import { CheckIcon, SelectorIcon } from '@heroicons/react/outline'; import React, { Fragment } from 'react'; import { connectHitsPerPage } from 'react-instantsearch-dom'; import { classNames } from '../lib/class-names'; const HitsPerPage = ({ items, refine, currentRefinement, }: { items: { value: string; label: string; }[]; refine: (value: number) => void; currentRefinement: number; }) => { return ( <Listbox value={currentRefinement} onChange={(value) => refine(value)}> {({ open }) => ( <div className="flex items-center space-x-2"> <Listbox.Label className="block text-sm font-medium text-gray-700"> 表示件数 </Listbox.Label> <div className="relative w-20"> <Listbox.Button className="bg-white relative w-full border border-gray-300 rounded-md shadow-sm pl-3 pr-10 py-2 text-left cursor-default focus:outline-none focus:ring-1 focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"> <span className="block truncate">{currentRefinement}</span> <span className="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none"> <SelectorIcon className="h-5 w-5 text-gray-400" aria-hidden="true" /> </span> </Listbox.Button> <Transition show={open} as={Fragment} leave="transition ease-in duration-100" leaveFrom="opacity-100" leaveTo="opacity-0" > <Listbox.Options className="absolute z-10 mt-1 w-full bg-white shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm"> {items.map((item) => ( <Listbox.Option key={item.value} className={({ active }) => classNames( active ? 'text-white bg-indigo-600' : 'text-gray-900', 'cursor-default select-none relative py-2 pl-3 pr-9' ) } value={item.value} > {({ selected, active }) => ( <> <span className={classNames( selected ? 'font-semibold' : 'font-normal', 'block truncate' )} > {item.label} </span> {selected ? ( <span className={classNames( active ? 'text-white' : 'text-indigo-600', 'absolute inset-y-0 right-0 flex items-center pr-4' )} > <CheckIcon className="h-5 w-5" aria-hidden="true" /> </span> ) : null} </> )} </Listbox.Option> ))} </Listbox.Options> </Transition> </div> </div> )} </Listbox> ); }; const CustomHitsPerPage = connectHitsPerPage(HitsPerPage); export default CustomHitsPerPage;
Tailwind CSSと Headless UI を使っているので複雑に見えますが仕組みはシンプルです。カスタムウィジェットウィジェットが受け取った以下のプロパティを使ってUIを実装しています。
- items: 表示件数の選択肢
- refine: 検索条件の変更
- currentRefinement: 現在の表示件数
カスタムウィジェットの使用
InstantSearchタグの中に設置してください。
<CustomHitsPerPage items={[ { value: 5, label: '5', }, { value: 20, label: '20', }, { value: 50, label: '50', }, ]} defaultRefinement={ Number(router.query.hitsPerPage as string) || 5 } />
URLのクエリーが存在する場合デフォルトの検索条件として反映されるようにしています。