11import clsx from 'clsx' ;
22import React , { useEffect , useState } from 'react' ;
3+ import type { CommandItemProps } from './CommandItem' ;
34import { CommandItem } from './CommandItem' ;
5+ import type { EmoticonItemProps } from './EmoticonItem' ;
46import { EmoticonItem } from './EmoticonItem' ;
7+ import type { SuggestionListItemComponentProps } from './SuggestionListItem' ;
58import { SuggestionListItem as DefaultSuggestionListItem } from './SuggestionListItem' ;
69import { UserItem } from './UserItem' ;
710import { useComponentContext } from '../../../context/ComponentContext' ;
@@ -13,10 +16,15 @@ import type {
1316 TextComposerState ,
1417 TextComposerSuggestion ,
1518} from 'stream-chat' ;
16- import type { SuggestionItemProps } from './SuggestionListItem' ;
19+ import type { UserItemProps } from './UserItem' ;
20+
21+ type SuggestionTrigger = '/' | ':' | '@' | string ;
1722
1823export type SuggestionListProps = Partial < {
19- SuggestionItem : React . ComponentType < SuggestionItemProps > ;
24+ suggestionItemComponents : Record <
25+ SuggestionTrigger ,
26+ React . ComponentType < SuggestionListItemComponentProps >
27+ > ;
2028 className ?: string ;
2129 closeOnClickOutside ?: boolean ;
2230 containerClassName ?: string ;
@@ -34,18 +42,28 @@ const searchSourceStateSelector = (
3442 items : nextValue . items ?? [ ] ,
3543} ) ;
3644
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 ;
4259
4360export const SuggestionList = ( {
4461 className,
4562 closeOnClickOutside = true ,
4663 containerClassName,
4764 focusedItemIndex,
4865 setFocusedItemIndex,
66+ suggestionItemComponents = defaultComponents ,
4967} : SuggestionListProps ) => {
5068 const { AutocompleteSuggestionItem = DefaultSuggestionListItem } =
5169 useComponentContext ( ) ;
@@ -56,8 +74,9 @@ export const SuggestionList = ({
5674 useStateStore ( suggestions ?. searchSource . state , searchSourceStateSelector ) ?? { } ;
5775 const [ container , setContainer ] = useState < HTMLDivElement | null > ( null ) ;
5876
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 ;
6180
6281 useEffect ( ( ) => {
6382 if ( ! closeOnClickOutside || ! suggestions || ! container ) return ;
0 commit comments