1
1
import clsx from 'clsx' ;
2
2
import React , { useEffect , useState } from 'react' ;
3
+ import type { CommandItemProps } from './CommandItem' ;
3
4
import { CommandItem } from './CommandItem' ;
5
+ import type { EmoticonItemProps } from './EmoticonItem' ;
4
6
import { EmoticonItem } from './EmoticonItem' ;
7
+ import type { SuggestionListItemComponentProps } from './SuggestionListItem' ;
5
8
import { SuggestionListItem as DefaultSuggestionListItem } from './SuggestionListItem' ;
6
9
import { UserItem } from './UserItem' ;
7
10
import { useComponentContext } from '../../../context/ComponentContext' ;
@@ -13,10 +16,15 @@ import type {
13
16
TextComposerState ,
14
17
TextComposerSuggestion ,
15
18
} from 'stream-chat' ;
16
- import type { SuggestionItemProps } from './SuggestionListItem' ;
19
+ import type { UserItemProps } from './UserItem' ;
20
+
21
+ type SuggestionTrigger = '/' | ':' | '@' | string ;
17
22
18
23
export type SuggestionListProps = Partial < {
19
- SuggestionItem : React . ComponentType < SuggestionItemProps > ;
24
+ suggestionItemComponents : Record <
25
+ SuggestionTrigger ,
26
+ React . ComponentType < SuggestionListItemComponentProps >
27
+ > ;
20
28
className ?: string ;
21
29
closeOnClickOutside ?: boolean ;
22
30
containerClassName ?: string ;
@@ -34,18 +42,28 @@ const searchSourceStateSelector = (
34
42
items : nextValue . items ?? [ ] ,
35
43
} ) ;
36
44
37
- export const defaultComponents = {
38
- '/' : CommandItem ,
39
- ':' : EmoticonItem ,
40
- '@' : UserItem ,
41
- } ;
45
+ export const defaultComponents : Record <
46
+ SuggestionTrigger ,
47
+ React . ComponentType < SuggestionListItemComponentProps >
48
+ > = {
49
+ '/' : ( props : SuggestionListItemComponentProps ) => (
50
+ < CommandItem entity = { props . entity as CommandItemProps [ 'entity' ] } />
51
+ ) ,
52
+ ':' : ( props : SuggestionListItemComponentProps ) => (
53
+ < EmoticonItem entity = { props . entity as EmoticonItemProps [ 'entity' ] } />
54
+ ) ,
55
+ '@' : ( props : SuggestionListItemComponentProps ) => (
56
+ < UserItem entity = { props . entity as UserItemProps [ 'entity' ] } />
57
+ ) ,
58
+ } as const ;
42
59
43
60
export const SuggestionList = ( {
44
61
className,
45
62
closeOnClickOutside = true ,
46
63
containerClassName,
47
64
focusedItemIndex,
48
65
setFocusedItemIndex,
66
+ suggestionItemComponents = defaultComponents ,
49
67
} : SuggestionListProps ) => {
50
68
const { AutocompleteSuggestionItem = DefaultSuggestionListItem } =
51
69
useComponentContext ( ) ;
@@ -56,8 +74,9 @@ export const SuggestionList = ({
56
74
useStateStore ( suggestions ?. searchSource . state , searchSourceStateSelector ) ?? { } ;
57
75
const [ container , setContainer ] = useState < HTMLDivElement | null > ( null ) ;
58
76
59
- // @ts -expect-error component type mismatch
60
- const component = suggestions ?. trigger && defaultComponents [ suggestions ?. trigger ] ;
77
+ const component = suggestions ?. trigger
78
+ ? suggestionItemComponents [ suggestions ?. trigger ]
79
+ : undefined ;
61
80
62
81
useEffect ( ( ) => {
63
82
if ( ! closeOnClickOutside || ! suggestions || ! container ) return ;
0 commit comments