@@ -4,7 +4,6 @@ import { MagnifyingGlassIcon } from '@heroicons/react/24/solid';
44import { SearchRoot , ChatRoot , Modal } from '@orama/ui/components' ;
55import { useTranslations } from 'next-intl' ;
66import type { FC , PropsWithChildren } from 'react' ;
7- import { useEffect , useState , useRef } from 'react' ;
87
98import '@orama/ui/styles.css' ;
109
@@ -14,122 +13,46 @@ import {
1413 useSearchbox ,
1514} from '#site/providers/searchboxProvider' ;
1615
17- import { ChatInput } from './ChatInput' ;
18- import { ChatInteractionsContainer } from './ChatInteractions' ;
19- import { Footer } from './Footer' ;
2016import styles from './index.module.css' ;
21- import { MobileTopBar } from './MobileTopBar' ;
22- import { Search } from './Search' ;
23- import { SlidingChatPanel } from './SlidingChatPanel' ;
24-
25- const InnerSearchboxModal : FC < PropsWithChildren < { onClose : ( ) => void } > > = ( {
26- onClose,
27- } ) => {
28- const searchbox = useSearchbox ( ) ;
29- const [ isMobileScreen , setIsMobileScreen ] = useState ( false ) ;
30- const searchInputRef = useRef < HTMLInputElement > ( null ) ;
31-
32- const displaySearch =
33- ! isMobileScreen || ( isMobileScreen && searchbox . mode === 'search' ) ;
34-
35- useEffect ( ( ) => {
36- const checkScreenSize = ( ) => {
37- setIsMobileScreen ( window . innerWidth < 1024 ) ;
38- } ;
39- checkScreenSize ( ) ;
40- window . addEventListener ( 'resize' , checkScreenSize ) ;
41- return ( ) => {
42- window . removeEventListener ( 'resize' , checkScreenSize ) ;
43- } ;
44- } , [ ] ) ;
45-
46- return (
47- < >
48- { isMobileScreen && (
49- < MobileTopBar
50- isChatOpen = { searchbox . mode === 'chat' }
51- onClose = { onClose }
52- onSelect = { searchbox . switchTo }
53- />
54- ) }
55- { displaySearch && < Search ref = { searchInputRef } /> }
56- { isMobileScreen && searchbox . mode === 'chat' && (
57- < >
58- < div className = { styles . mobileChatContainer } >
59- < div className = { styles . mobileChatTop } >
60- < ChatInteractionsContainer />
61- </ div >
62- < div className = { styles . mobileChatBottom } >
63- < ChatInput />
64- </ div >
65- </ div >
66- < Footer />
67- </ >
68- ) }
69- { ! isMobileScreen && searchbox . mode === 'chat' && (
70- < SlidingChatPanel
71- open = { searchbox . isChatOpen }
72- onClose = { ( ) => {
73- searchbox . closeChatAndReset ( ( ) => {
74- searchInputRef . current ?. focus ( ) ;
75- } ) ;
76- } }
77- />
78- ) }
79- </ >
80- ) ;
81- } ;
17+ import { InnerSearchboxModal } from './InnerSearchboxModal' ;
8218
8319const Searchbox : FC = ( ) => {
8420 const searchbox = useSearchbox ( ) ;
8521 const orama = useOrama ( ) ;
8622 const t = useTranslations ( ) ;
8723
88- useEffect ( ( ) => {
89- const handleKeyDown = ( e : KeyboardEvent ) : void => {
90- if ( ( e . metaKey || e . ctrlKey ) && e . key === 'k' ) {
91- e . preventDefault ( ) ;
92- searchbox . toggleModal ( ) ;
93- }
94- if ( e . key === 'Escape' ) {
95- searchbox . closeModal ( ) ;
96- }
97- } ;
98- document . addEventListener ( 'keydown' , handleKeyDown ) ;
99- return ( ) => {
100- document . removeEventListener ( 'keydown' , handleKeyDown ) ;
101- } ;
102- } , [ searchbox ] ) ;
103-
10424 return (
10525 < div className = { styles . searchboxContainer } >
106- < button
107- type = "button"
108- data-testid = "orama-button"
109- onClick = { searchbox . toggleModal }
110- disabled = { ! orama }
111- className = { styles . searchButton }
112- >
113- < div className = { styles . searchButtonContent } >
114- < MagnifyingGlassIcon />
115- { t ( 'components.search.searchPlaceholder' ) }
116- </ div >
117- < span className = { styles . searchButtonShortcut } > ⌘ K</ span >
118- </ button >
119-
120- < Modal . Wrapper
121- open = { searchbox . isOpen }
122- onModalClosed = { searchbox . closeModal }
123- closeOnOutsideClick
124- closeOnEscape
125- className = { styles . modalWrapper }
126- >
127- < Modal . Inner className = { styles . modalInner } >
128- < Modal . Content className = { styles . modalContent } >
129- < InnerSearchboxModal onClose = { searchbox . closeModal } />
130- </ Modal . Content >
131- </ Modal . Inner >
132- </ Modal . Wrapper >
26+ < Modal . Root >
27+ < Modal . Trigger
28+ type = "button"
29+ data-testid = "orama-button"
30+ onClick = { searchbox . toggleModal }
31+ disabled = { ! orama }
32+ enableCmdK
33+ className = { styles . searchButton }
34+ >
35+ < div className = { styles . searchButtonContent } >
36+ < MagnifyingGlassIcon />
37+ { t ( 'components.search.searchPlaceholder' ) }
38+ </ div >
39+ < span className = { styles . searchButtonShortcut } > ⌘ K</ span >
40+ </ Modal . Trigger >
41+
42+ < Modal . Wrapper
43+ open = { searchbox . isOpen }
44+ onModalClosed = { searchbox . closeModal }
45+ closeOnOutsideClick
46+ closeOnEscape
47+ className = { styles . modalWrapper }
48+ >
49+ < Modal . Inner className = { styles . modalInner } >
50+ < Modal . Content className = { styles . modalContent } >
51+ < InnerSearchboxModal onClose = { searchbox . closeModal } />
52+ </ Modal . Content >
53+ </ Modal . Inner >
54+ </ Modal . Wrapper >
55+ </ Modal . Root >
13356 </ div >
13457 ) ;
13558} ;
@@ -138,8 +61,8 @@ const OramaSearch: FC<PropsWithChildren> = () => {
13861 const orama = useOrama ( ) ;
13962
14063 return (
141- < SearchRoot client = { orama } >
142- < ChatRoot client = { orama } askOptions = { { throttle_delay : 50 } } >
64+ < SearchRoot client = { orama ?? null } >
65+ < ChatRoot client = { orama ?? null } askOptions = { { throttle_delay : 50 } } >
14366 < SearchboxProvider >
14467 < Searchbox />
14568 </ SearchboxProvider >
0 commit comments