Skip to content

Commit

Permalink
CDC #27 - Renaming PlaceResultsList to SearchResultsList; Updating to…
Browse files Browse the repository at this point in the history
… use more generic rendering function; Removing "react-instantsearch" dependency
  • Loading branch information
dleadbetter committed Apr 23, 2024
1 parent cd00f15 commit a309fc2
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 206 deletions.
1 change: 0 additions & 1 deletion packages/core-data/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
"instantsearch.js": "^4.66.0",
"lucide-react": "^0.321.0",
"postcss-import": "^16.1.0",
"react-instantsearch": "^7.5.4",
"react-virtualized-auto-sizer": "^1.0.22",
"react-window": "^1.8.10",
"typesense-instantsearch-adapter": "^2.8.0",
Expand Down
137 changes: 0 additions & 137 deletions packages/core-data/src/components/PlaceResultsList.js

This file was deleted.

134 changes: 134 additions & 0 deletions packages/core-data/src/components/SearchResultsList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// @flow

import React, { useMemo } from 'react';
import AutoSizer from 'react-virtualized-auto-sizer';
import { FixedSizeList } from 'react-window';
import type { Feature } from '../types/Feature';
import type { Place } from '../types/typesense/Place';
import TypesenseUtils from '../utils/Typesense';

type Props = {
/**
* An array of search results representing `/typesense/Place` objects.
*/
hits: Array<Place>,

/**
* The object that is currently occupying the hover state.
*/
hover?: Feature<{ id: string }>,

/**
* The height (in pixels) of each row in the list.
*/
itemSize?: number,

/**
* Callback fired when the hover item is changed.
*/
onHoverChange: (hover?: Feature<{ id: string }>) => void,

/**
* Callback fired when a search result is clicked.
*/
onClick: (result: Place) => void,

/**
* TODO: Comment me
* @param result
*/
renderItem: (result: Place) => JSX.Element
};

type RowProps = {
index: number,
style: any
};

/**
* This component renders a list of search results returned from a Core Data Typesense index.
*/
const SearchResultsList = (props: Props) => {
const {
hits,
hover,
onClick,
onHoverChange,
renderItem
} = props;

const Row = ({ index, style }: RowProps) => {
const hit = hits[index];
const id = parseInt(hit.record_id, 10);

/**
* Sets the isHovered variable to `true` for the current row.
*
* @type {boolean}
*/
const isHovered = useMemo(() => hover?.id === id, [hover, id]);

/**
* Sets the class name variable for the current row.
*
* @type {string}
*/
const className = useMemo(() => {
const classNames = [
'h-full',
'border-b',
'flex',
'flex-col',
'justify-start'
];

if (isHovered) {
classNames.push('bg-teal-700/30');
}

return classNames.join(' ');
}, [isHovered]);

return (
<div
style={style}
onPointerEnter={() => onHoverChange(isHovered ? hover : TypesenseUtils.toFeature(hit))}
onPointerLeave={() => onHoverChange(undefined)}
>
<div
className={className}
>
<button
aria-label='Search result'
className='py-2 px-3 flex-grow text-left flex rounded-none flex-col hover:bg-transparent'
onClick={onClick}
type='button'
>
{ renderItem(hit) }
</button>
</div>
</div>
);
};

return (
<AutoSizer>
{({ height, width }) => (
<FixedSizeList
height={height}
itemCount={hits.length}
width={width}
itemSize={props.itemSize}
>
{ Row }
</FixedSizeList>
)}
</AutoSizer>
);
};

SearchResultsList.defaultProps = {
itemSize: 88
};

export default SearchResultsList;
2 changes: 1 addition & 1 deletion packages/core-data/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export { default as PersistentSearchStateContextProvider } from './components/Pe
export { default as PlaceDetails } from './components/PlaceDetails';
export { default as PlaceLayersSelector } from './components/PlaceLayersSelector';
export { default as PlaceMarkers } from './components/PlaceMarkers';
export { default as PlaceResultsList } from './components/SearchResultsList.js';
export { default as SearchResultsList } from './components/SearchResultsList';
export { default as RefinementListProxy } from './components/RefinementListProxy';
export { default as RelatedEvents } from './components/RelatedEvents';
export { default as RelatedItem } from './components/RelatedItem';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

import { action } from '@storybook/addon-actions';
import React from 'react';
import PlaceResultsList from '../../../core-data/src/components/PlaceResultsList';
import hits from '../data/typesense/Places.json';
import SearchResultsList from '../../../core-data/src/components/SearchResultsList';

export default {
title: 'Components/Core Data/PlaceResultsList',
component: PlaceResultsList
title: 'Components/Core Data/SearchResultsList',
component: SearchResultsList
};

export const Default = () => (
Expand All @@ -27,10 +27,22 @@ export const Default = () => (
height: '100%'
}}
>
<PlaceResultsList
<SearchResultsList
hits={hits}
onHoverChange={action('hover')}
onClick={action('click')}
renderItem={(item) => (
<>
<h2>
{ item.name }
</h2>
<p
className='text-muted text-xs line-clamp-1'
>
{ item.names }
</p>
</>
)}
/>
</div>
</div>
Expand Down
Loading

0 comments on commit a309fc2

Please sign in to comment.