forked from algolia/docsearch
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathResults.tsx
More file actions
128 lines (114 loc) · 4.13 KB
/
Results.tsx
File metadata and controls
128 lines (114 loc) · 4.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import type { AutocompleteApi, AutocompleteState, BaseItem } from '@algolia/autocomplete-core';
import React, { type JSX } from 'react';
import type { DocSearchProps } from './DocSearch';
import { Snippet } from './Snippet';
import type { InternalDocSearchHit, StoredDocSearchHit } from './types';
interface ResultsProps<TItem extends BaseItem>
extends AutocompleteApi<TItem, React.FormEvent, React.MouseEvent, React.KeyboardEvent> {
title: string;
collection: AutocompleteState<TItem>['collections'][0];
renderIcon: (props: { item: TItem; index: number }) => React.ReactNode;
renderAction: (props: {
item: TItem;
runDeleteTransition: (cb: () => void) => void;
runFavoriteTransition: (cb: () => void) => void;
}) => React.ReactNode;
onItemClick: (item: TItem, event: KeyboardEvent | MouseEvent) => void;
hitComponent: DocSearchProps['hitComponent'];
}
export function Results<TItem extends StoredDocSearchHit>(props: ResultsProps<TItem>): JSX.Element | null {
if (!props.collection || props.collection.items.length === 0) {
return null;
}
return (
<section className="DocSearch-Hits">
<div className="DocSearch-Hit-source">{props.title}</div>
<ul {...props.getListProps()}>
{props.collection.items.map((item, index) => {
return <Result key={[props.title, item.objectID].join(':')} item={item} index={index} {...props} />;
})}
</ul>
</section>
);
}
interface ResultProps<TItem extends BaseItem> extends ResultsProps<TItem> {
item: TItem;
index: number;
}
function Result<TItem extends StoredDocSearchHit>({
item,
index,
renderIcon,
renderAction,
getItemProps,
onItemClick,
collection,
hitComponent,
}: ResultProps<TItem>): JSX.Element {
const [isDeleting, setIsDeleting] = React.useState(false);
const [isFavoriting, setIsFavoriting] = React.useState(false);
const action = React.useRef<(() => void) | null>(null);
const Hit = hitComponent!;
function runDeleteTransition(cb: () => void): void {
setIsDeleting(true);
action.current = cb;
}
function runFavoriteTransition(cb: () => void): void {
setIsFavoriting(true);
action.current = cb;
}
return (
<li
className={[
'DocSearch-Hit',
(item as unknown as InternalDocSearchHit).__docsearch_parent && 'DocSearch-Hit--Child',
isDeleting && 'DocSearch-Hit--deleting',
isFavoriting && 'DocSearch-Hit--favoriting',
]
.filter(Boolean)
.join(' ')}
onTransitionEnd={() => {
if (action.current) {
action.current();
}
}}
{...getItemProps({
item,
source: collection.source,
onClick(event) {
onItemClick(item, event);
},
})}
>
<Hit hit={item}>
<div className="DocSearch-Hit-Container">
{renderIcon({ item, index })}
{item.hierarchy[item.type] && item.type === 'lvl1' && (
<div className="DocSearch-Hit-content-wrapper">
<Snippet className="DocSearch-Hit-title" hit={item} attribute="hierarchy.lvl1" />
{item.content && <Snippet className="DocSearch-Hit-path" hit={item} attribute="content" />}
</div>
)}
{item.hierarchy[item.type] &&
(item.type === 'lvl2' ||
item.type === 'lvl3' ||
item.type === 'lvl4' ||
item.type === 'lvl5' ||
item.type === 'lvl6') && (
<div className="DocSearch-Hit-content-wrapper">
<Snippet className="DocSearch-Hit-title" hit={item} attribute={`hierarchy.${item.type}`} />
<Snippet className="DocSearch-Hit-path" hit={item} attribute="hierarchy.lvl1" />
</div>
)}
{item.type === 'content' && (
<div className="DocSearch-Hit-content-wrapper">
<Snippet className="DocSearch-Hit-title" hit={item} attribute="content" />
<Snippet className="DocSearch-Hit-path" hit={item} attribute="hierarchy.lvl1" />
</div>
)}
{renderAction({ item, runDeleteTransition, runFavoriteTransition })}
</div>
</Hit>
</li>
);
}