Skip to content

Commit 817a11f

Browse files
committed
[WIP] Move some Orama components to ui-components
1 parent 4c1a417 commit 817a11f

10 files changed

Lines changed: 157 additions & 123 deletions

File tree

apps/site/components/Common/Searchbox/InnerSearchboxModal/index.module.css renamed to apps/site/components/Common/Searchbox/InnerModal/index.module.css

File renamed without changes.

apps/site/components/Common/Searchbox/InnerSearchboxModal/index.tsx renamed to apps/site/components/Common/Searchbox/InnerModal/index.tsx

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,44 @@
11
'use client';
2-
import type { FC, PropsWithChildren } from 'react';
3-
import { useEffect, useState, useRef } from 'react';
2+
import MobileTopBar from '@node-core/ui-components/Common/Search/MobileTopBar';
3+
import type { FC } from 'react';
4+
import { useEffect, useRef, useState } from 'react';
45

56
import { useSearchbox } from '#site/providers/searchboxProvider';
67

78
import { ChatInput } from '../ChatInput';
89
import { ChatInteractionsContainer } from '../ChatInteractions';
910
import { Footer } from '../Footer';
10-
import { MobileTopBar } from '../MobileTopBar';
1111
import { Search } from '../Search';
1212
import { SlidingChatPanel } from '../SlidingChatPanel';
1313
import styles from './index.module.css';
1414

15-
export const InnerSearchboxModal: FC<PropsWithChildren> = () => {
15+
const InnerModal: FC = () => {
1616
const searchbox = useSearchbox();
1717
const [isMobileScreen, setIsMobileScreen] = useState(false);
1818
const searchInputRef = useRef<HTMLInputElement>(null);
1919

20-
const displaySearch =
21-
!isMobileScreen || (isMobileScreen && searchbox?.mode === 'search');
20+
const isChatMode = searchbox?.mode === 'chat';
21+
const shouldShowSearch = !isMobileScreen || isChatMode === false;
2222

2323
useEffect(() => {
24-
const checkScreenSize = () => {
24+
const handleResize = () => {
2525
setIsMobileScreen(window.innerWidth < 1024);
2626
};
27-
checkScreenSize();
28-
window.addEventListener('resize', checkScreenSize);
29-
return () => {
30-
window.removeEventListener('resize', checkScreenSize);
31-
};
27+
28+
handleResize();
29+
window.addEventListener('resize', handleResize);
30+
return () => window.removeEventListener('resize', handleResize);
3231
}, []);
3332

3433
return (
3534
<>
3635
{isMobileScreen && (
37-
<MobileTopBar
38-
isChatOpen={searchbox?.mode === 'chat'}
39-
onSelect={searchbox?.switchTo}
40-
/>
36+
<MobileTopBar mode={searchbox?.mode} onSelect={searchbox?.switchTo} />
4137
)}
42-
{displaySearch && <Search ref={searchInputRef} />}
43-
{isMobileScreen && searchbox?.mode === 'chat' && (
38+
39+
{shouldShowSearch && <Search ref={searchInputRef} />}
40+
41+
{isMobileScreen && isChatMode && (
4442
<>
4543
<div className={styles.mobileChatContainer}>
4644
<div className={styles.mobileChatTop}>
@@ -53,7 +51,8 @@ export const InnerSearchboxModal: FC<PropsWithChildren> = () => {
5351
<Footer />
5452
</>
5553
)}
56-
{!isMobileScreen && searchbox?.mode === 'chat' && (
54+
55+
{!isMobileScreen && isChatMode && (
5756
<SlidingChatPanel
5857
open={searchbox?.isChatOpen}
5958
onClose={() => {
@@ -66,3 +65,5 @@ export const InnerSearchboxModal: FC<PropsWithChildren> = () => {
6665
</>
6766
);
6867
};
68+
69+
export default InnerModal;

apps/site/components/Common/Searchbox/MobileTopBar/index.tsx

Lines changed: 0 additions & 63 deletions
This file was deleted.

apps/site/components/Common/Searchbox/index.tsx

Lines changed: 8 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,25 @@
11
'use client';
22

3-
import { MagnifyingGlassIcon } from '@heroicons/react/24/solid';
4-
import { SearchRoot, ChatRoot, Modal } from '@orama/ui/components';
3+
import SearchModal from '@node-core/ui-components/Common/Search/Modal';
54
import { useTranslations } from 'next-intl';
65
import type { FC } from 'react';
76

8-
import '@orama/ui/styles.css';
97
import { SearchboxProvider } from '#site/providers/searchboxProvider';
108

11-
import styles from './index.module.css';
12-
import { InnerSearchboxModal } from './InnerSearchboxModal';
9+
import InnerModal from './InnerModal';
1310
import { oramaClient } from './orama-client';
1411

1512
const Searchbox: FC = () => {
1613
const t = useTranslations();
1714

1815
return (
1916
<SearchboxProvider>
20-
<div className={styles.searchboxContainer}>
21-
<Modal.Root>
22-
<Modal.Trigger
23-
type="button"
24-
disabled={!oramaClient}
25-
enableCmdK
26-
className={styles.searchButton}
27-
>
28-
<div className={styles.searchButtonContent}>
29-
<MagnifyingGlassIcon />
30-
{t('components.search.searchPlaceholder')}
31-
</div>
32-
<span className={styles.searchButtonShortcut}>⌘ K</span>
33-
</Modal.Trigger>
34-
35-
<Modal.Wrapper
36-
closeOnOutsideClick
37-
closeOnEscape
38-
className={styles.modalWrapper}
39-
>
40-
<SearchRoot client={oramaClient}>
41-
<ChatRoot
42-
client={oramaClient}
43-
askOptions={{ throttle_delay: 50 }}
44-
>
45-
<Modal.Inner className={styles.modalInner}>
46-
<Modal.Content className={styles.modalContent}>
47-
<InnerSearchboxModal />
48-
</Modal.Content>
49-
</Modal.Inner>
50-
</ChatRoot>
51-
</SearchRoot>
52-
</Modal.Wrapper>
53-
</Modal.Root>
54-
</div>
17+
<SearchModal
18+
client={oramaClient}
19+
placeholder={t('components.search.searchPlaceholder')}
20+
>
21+
<InnerModal />
22+
</SearchModal>
5523
</SearchboxProvider>
5624
);
5725
};

packages/ui-components/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
},
3737
"dependencies": {
3838
"@heroicons/react": "^2.2.0",
39+
"@orama/ui": "^1.3.2",
3940
"@radix-ui/react-avatar": "^1.1.10",
4041
"@radix-ui/react-dialog": "^1.1.15",
4142
"@radix-ui/react-dropdown-menu": "~2.1.16",
@@ -52,6 +53,7 @@
5253
"tailwindcss": "catalog:"
5354
},
5455
"devDependencies": {
56+
"@orama/core": "^1.2.13",
5557
"@storybook/addon-styling-webpack": "^2.0.0",
5658
"@storybook/addon-themes": "^10.0.2",
5759
"@storybook/addon-webpack5-compiler-swc": "^4.0.1",

apps/site/components/Common/Searchbox/MobileTopBar/index.module.css renamed to packages/ui-components/src/Common/Search/MobileTopBar/index.module.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@reference "../../../../styles/index.css";
1+
@reference "../../../styles/index.css";
22

33
.topBar {
44
@apply relative
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
'use client';
2+
3+
import {
4+
MagnifyingGlassIcon,
5+
ArrowLeftIcon,
6+
SparklesIcon,
7+
} from '@heroicons/react/24/solid';
8+
import { Modal } from '@orama/ui/components/Modal';
9+
import classNames from 'classnames';
10+
import type { FC } from 'react';
11+
import { useState } from 'react';
12+
13+
import '@orama/ui/styles.css';
14+
import styles from './index.module.css';
15+
16+
type Mode = 'search' | 'chat';
17+
18+
type MobileTopBarProps = {
19+
mode?: Mode;
20+
onSelect?: (mode: Mode) => void;
21+
};
22+
23+
const MobileTopBar: FC<MobileTopBarProps> = ({
24+
mode: currentMode,
25+
onSelect,
26+
}) => {
27+
const [animated, setAnimated] = useState(false);
28+
29+
const selectMode = (mode: Mode) => {
30+
onSelect?.(mode);
31+
setAnimated(true);
32+
};
33+
34+
const tabConfig = [
35+
{
36+
mode: 'search',
37+
icon: <MagnifyingGlassIcon />,
38+
label: 'Search',
39+
},
40+
{
41+
mode: 'chat',
42+
icon: <SparklesIcon />,
43+
label: 'Ask AI',
44+
},
45+
];
46+
47+
return (
48+
<div className={styles.topBar}>
49+
<Modal.Close
50+
className={styles.topBarArrow}
51+
aria-label="Close search modal"
52+
>
53+
<ArrowLeftIcon />
54+
</Modal.Close>
55+
<div className={styles.topBarTabs}>
56+
{tabConfig.map(({ mode, icon, label }) => (
57+
<button
58+
className={classNames(styles.topBarTab, {
59+
[styles.topBarTabActive]: mode === currentMode,
60+
[styles.topBarTabAnimated]: animated,
61+
})}
62+
onClick={() => selectMode(mode as Mode)}
63+
>
64+
<span>{label}</span>
65+
{icon}
66+
</button>
67+
))}
68+
</div>
69+
</div>
70+
);
71+
};
72+
73+
export default MobileTopBar;

apps/site/components/Common/Searchbox/index.module.css renamed to packages/ui-components/src/Common/Search/Modal/index.module.css

File renamed without changes.
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
'use client';
2+
3+
import { MagnifyingGlassIcon } from '@heroicons/react/24/solid';
4+
import type { OramaCloud } from '@orama/core';
5+
import { SearchRoot, ChatRoot, Modal } from '@orama/ui/components';
6+
import type { FC, PropsWithChildren } from 'react';
7+
8+
import styles from './index.module.css';
9+
10+
const SearchModal: FC<
11+
PropsWithChildren<{ client: OramaCloud | null; placeholder: string }>
12+
> = ({ children, client, placeholder }) => (
13+
<div className={styles.searchboxContainer}>
14+
<Modal.Root>
15+
<Modal.Trigger
16+
type="button"
17+
disabled={!client}
18+
enableCmdK
19+
className={styles.searchButton}
20+
>
21+
<div className={styles.searchButtonContent}>
22+
<MagnifyingGlassIcon />
23+
{placeholder}
24+
</div>
25+
<span className={styles.searchButtonShortcut}>⌘ K</span>
26+
</Modal.Trigger>
27+
28+
<Modal.Wrapper
29+
closeOnOutsideClick
30+
closeOnEscape
31+
className={styles.modalWrapper}
32+
>
33+
<SearchRoot client={client}>
34+
<ChatRoot client={client} askOptions={{ throttle_delay: 50 }}>
35+
<Modal.Inner className={styles.modalInner}>
36+
<Modal.Content className={styles.modalContent}>
37+
{children}
38+
</Modal.Content>
39+
</Modal.Inner>
40+
</ChatRoot>
41+
</SearchRoot>
42+
</Modal.Wrapper>
43+
</Modal.Root>
44+
</div>
45+
);
46+
47+
export default SearchModal;

pnpm-lock.yaml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)