Skip to content

Commit d53301c

Browse files
authored
feat(orama): add SearchHit UI component (#8398)
* feat(orama): add SearchHit UI component * fixup!
1 parent bf98887 commit d53301c

File tree

8 files changed

+97
-93
lines changed

8 files changed

+97
-93
lines changed
Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
'use client';
22

3+
import styles from '@node-core/ui-components/Common/Search/Results/Hit/index.module.css';
34
import Link from 'next/link';
45
import { useLocale } from 'next-intl';
56

67
import type { FC } from 'react';
78

8-
import styles from './index.module.css';
9+
import { getDocumentHref } from '../SearchItem/utils';
910

1011
export type Document = {
1112
path: string;
@@ -22,30 +23,21 @@ type DocumentLinkProps = {
2223

2324
export const DocumentLink: FC<DocumentLinkProps> = ({
2425
document,
25-
className = styles.documentLink,
26+
className = styles.link,
2627
children,
2728
'data-focus-on-arrow-nav': dataFocusOnArrowNav,
2829
...props
2930
}) => {
3031
const locale = useLocale();
3132

32-
const href =
33-
document.siteSection?.toLowerCase() === 'docs'
34-
? `/${document.path}`
35-
: `/${locale}/${document.path}`;
36-
3733
return (
3834
<Link
39-
href={href}
35+
href={getDocumentHref(document, locale)}
4036
className={className}
4137
data-focus-on-arrow-nav={dataFocusOnArrowNav}
4238
{...props}
4339
>
44-
{children || (
45-
<span className={styles.documentTitle}>
46-
{document.pageSectionTitle}
47-
</span>
48-
)}
40+
{children}
4941
</Link>
5042
);
5143
};

apps/site/components/Common/Searchbox/SearchItem/index.module.css

Lines changed: 0 additions & 34 deletions
This file was deleted.
Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,36 @@
1-
'use client';
2-
3-
import { DocumentTextIcon } from '@heroicons/react/24/outline';
4-
import { SearchResults } from '@orama/ui/components';
1+
import SearchHit from '@node-core/ui-components/Common/Search/Results/Hit';
2+
import Link from 'next/link';
3+
import { useLocale } from 'next-intl';
54

65
import type { Document } from '../DocumentLink';
7-
import type { FC } from 'react';
8-
9-
import { DocumentLink } from '../DocumentLink';
10-
import { getFormattedPath } from './utils';
6+
import type { LinkLike } from '@node-core/ui-components/types';
7+
import type { ComponentProps, FC } from 'react';
118

12-
import styles from './index.module.css';
9+
import { getDocumentHref, getFormattedPath } from './utils';
1310

14-
type SearchItemProps = {
11+
type SearchItemProps = Omit<
12+
ComponentProps<typeof SearchHit>,
13+
'document' | 'as'
14+
> & {
1515
document: Document;
16-
mode?: 'search' | 'chat';
1716
};
1817

19-
export const SearchItem: FC<SearchItemProps> = ({ document, mode }) => (
20-
<SearchResults.Item className={styles.searchResultsItem}>
21-
<DocumentLink
22-
document={document as Document}
23-
tabIndex={mode === 'search' ? 0 : -1}
24-
aria-hidden={mode === 'chat'}
25-
data-focus-on-arrow-nav
26-
>
27-
<DocumentTextIcon />
28-
<div>
29-
{typeof document?.pageSectionTitle === 'string' && (
30-
<h3>{document.pageSectionTitle}</h3>
31-
)}
32-
{typeof document?.pageSectionTitle === 'string' &&
33-
typeof document?.path === 'string' && (
34-
<p className={styles.searchResultsItemDescription}>
35-
{getFormattedPath(document.path, document.pageSectionTitle)}
36-
</p>
37-
)}
38-
</div>
39-
</DocumentLink>
40-
</SearchResults.Item>
41-
);
18+
const SearchItem: FC<SearchItemProps> = ({ document, ...props }) => {
19+
const locale = useLocale();
20+
21+
return (
22+
<SearchHit
23+
document={{
24+
title: document.pageSectionTitle,
25+
description:
26+
document.pageSectionTitle &&
27+
getFormattedPath(document.path, document.pageSectionTitle),
28+
href: getDocumentHref(document, locale),
29+
}}
30+
as={Link as LinkLike}
31+
{...props}
32+
/>
33+
);
34+
};
35+
36+
export default SearchItem;

apps/site/components/Common/Searchbox/SearchItem/utils.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import type { Document } from '../DocumentLink';
2+
13
export const uppercaseFirst = (word: string) =>
24
word.charAt(0).toUpperCase() + word.slice(1);
35

@@ -9,3 +11,8 @@ export const getFormattedPath = (path: string, title: string) =>
911
.map(element => uppercaseFirst(element))
1012
.filter(Boolean)
1113
.join(' > ')}${title}`;
14+
15+
export const getDocumentHref = (document: Document, locale: string) =>
16+
document.siteSection?.toLowerCase() === 'docs'
17+
? `/${document.path}`
18+
: `/${locale}/${document.path}`;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import type { FC } from 'react';
1414

1515
import { Footer } from './Footer';
1616
import { oramaClient } from './orama-client';
17-
import { SearchItem } from './SearchItem';
17+
import SearchItem from './SearchItem';
1818
import { SlidingChatPanel } from './SlidingChatPanel';
1919

2020
import styles from './index.module.css';

packages/ui-components/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@node-core/ui-components",
3-
"version": "1.4.0",
3+
"version": "1.4.1",
44
"type": "module",
55
"exports": {
66
"./*": [

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

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
11
@reference "../../../../styles/index.css";
22

3-
.documentLink {
4-
@apply rounded-xl
3+
.link {
4+
@apply flex
5+
items-center
6+
gap-4
7+
rounded-xl
8+
border
9+
border-transparent
510
bg-neutral-100
611
px-4
712
py-2
13+
text-sm
814
text-neutral-900
915
duration-300
16+
outline-none
1017
hover:bg-neutral-200
1118
focus:bg-neutral-200
19+
focus-visible:border-green-600
20+
focus-visible:bg-transparent
1221
motion-safe:transition-colors
1322
dark:bg-neutral-950
1423
dark:text-neutral-200
@@ -20,12 +29,8 @@
2029
}
2130
}
2231

23-
.documentTitle {
24-
@apply max-w-full
25-
truncate
26-
overflow-hidden
27-
text-sm
28-
font-semibold
29-
text-ellipsis
30-
whitespace-nowrap;
32+
.hitDescription {
33+
@apply text-sm
34+
text-neutral-600
35+
dark:text-neutral-700;
3136
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { DocumentTextIcon } from '@heroicons/react/24/outline';
2+
import { SearchResults } from '@orama/ui/components';
3+
4+
import type { LinkLike } from '#ui/types';
5+
import type { FC } from 'react';
6+
7+
import styles from './index.module.css';
8+
9+
type HitProps = {
10+
document: {
11+
title?: string;
12+
description?: string;
13+
href: string;
14+
};
15+
mode?: 'search' | 'chat';
16+
as?: LinkLike;
17+
};
18+
19+
const Hit: FC<HitProps> = ({ document, mode = 'search', as: Link = 'a' }) => (
20+
<SearchResults.Item>
21+
<Link
22+
href={document.href}
23+
tabIndex={mode === 'search' ? 0 : -1}
24+
aria-hidden={mode === 'chat'}
25+
data-focus-on-arrow-nav
26+
className={styles.link}
27+
>
28+
<DocumentTextIcon />
29+
<div>
30+
{typeof document?.title === 'string' && <h3>{document.title}</h3>}
31+
{typeof document?.description === 'string' && (
32+
<p className={styles.hitDescription}>{document.description}</p>
33+
)}
34+
</div>
35+
</Link>
36+
</SearchResults.Item>
37+
);
38+
39+
export default Hit;

0 commit comments

Comments
 (0)