Skip to content

Commit 3d1b79f

Browse files
committed
2 parents 090bbdd + 4f613c4 commit 3d1b79f

File tree

1 file changed

+94
-65
lines changed

1 file changed

+94
-65
lines changed

src/components/SearchModal.tsx

Lines changed: 94 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,7 @@ function decodeHtmlEntities(str: string): string {
2525
}
2626

2727
// Custom Highlight component that decodes HTML entities
28-
function DecodedHighlight({
29-
attribute,
30-
hit,
31-
}: {
32-
attribute: string
33-
hit: any
34-
}) {
28+
function DecodedHighlight({ attribute, hit }: { attribute: string; hit: any }) {
3529
// Navigate nested paths for both raw value and highlight result
3630
const getNestedValue = (obj: any, path: string) =>
3731
path.split('.').reduce((o, key) => o?.[key], obj)
@@ -45,7 +39,9 @@ function DecodedHighlight({
4539

4640
// Parse the highlighted string and decode entities while preserving <mark> tags
4741
const decoded = decodeHtmlEntities(
48-
highlighted.replace(/<mark>/g, '###MARK###').replace(/<\/mark>/g, '###/MARK###'),
42+
highlighted
43+
.replace(/<mark>/g, '###MARK###')
44+
.replace(/<\/mark>/g, '###/MARK###'),
4945
)
5046
.replace(/###MARK###/g, '<mark>')
5147
.replace(/###\/MARK###/g, '</mark>')
@@ -66,14 +62,26 @@ const SearchFiltersContext = React.createContext<{
6662
setSelectedFramework: (value: string) => void
6763
refineLibrary: (value: string) => void
6864
refineFramework: (value: string) => void
69-
libraryItems: Array<{ value: string; label: string; count: number; isRefined: boolean }>
70-
frameworkItems: Array<{ value: string; label: string; count: number; isRefined: boolean }>
65+
libraryItems: Array<{
66+
value: string
67+
label: string
68+
count: number
69+
isRefined: boolean
70+
}>
71+
frameworkItems: Array<{
72+
value: string
73+
label: string
74+
count: number
75+
isRefined: boolean
76+
}>
7177
} | null>(null)
7278

7379
function useSearchFilters() {
7480
const context = React.useContext(SearchFiltersContext)
7581
if (!context) {
76-
throw new Error('useSearchFilters must be used within SearchFiltersProvider')
82+
throw new Error(
83+
'useSearchFilters must be used within SearchFiltersProvider',
84+
)
7785
}
7886
return context
7987
}
@@ -252,9 +260,14 @@ const Hit = ({
252260
)
253261
}
254262

255-
const hierarchyLevels = ['lvl1', 'lvl2', 'lvl3', 'lvl4', 'lvl5', 'lvl6'].filter(
256-
(lvl) => hit.hierarchy[lvl],
257-
)
263+
const hierarchyLevels = [
264+
'lvl1',
265+
'lvl2',
266+
'lvl3',
267+
'lvl4',
268+
'lvl5',
269+
'lvl6',
270+
].filter((lvl) => hit.hierarchy[lvl])
258271

259272
return (
260273
<SafeLink
@@ -481,7 +494,9 @@ function FrameworkRefinement() {
481494
/>
482495
)}
483496
<span>
484-
{currentFramework ? capitalize(currentFramework.label) : 'All Frameworks'}
497+
{currentFramework
498+
? capitalize(currentFramework.label)
499+
: 'All Frameworks'}
485500
</span>
486501
<ChevronDown className="w-3.5 h-3.5 opacity-50" />
487502
</Listbox.Button>
@@ -692,51 +707,51 @@ export function SearchModal() {
692707
<InstantSearch searchClient={searchClient} indexName="tanstack-test">
693708
<SearchFiltersProvider>
694709
<Configure
695-
attributesToRetrieve={[
696-
'hierarchy.lvl1',
697-
'hierarchy.lvl2',
698-
'hierarchy.lvl3',
699-
'hierarchy.lvl4',
700-
'hierarchy.lvl5',
701-
'hierarchy.lvl6',
702-
'url',
703-
'content',
704-
'library',
705-
]}
706-
attributesToHighlight={[
707-
'hierarchy.lvl1',
708-
'hierarchy.lvl2',
709-
'hierarchy.lvl3',
710-
'hierarchy.lvl4',
711-
'hierarchy.lvl5',
712-
'hierarchy.lvl6',
713-
'content',
714-
]}
715-
attributesToSnippet={['content:50']}
716-
filters="version:latest"
717-
/>
718-
<div className="flex items-center gap-2 px-4 py-3 overflow-visible">
719-
<Search className="w-5 h-5 opacity-50 flex-none" />
720-
<LibraryRefinement />
721-
<span className="text-gray-400 dark:text-gray-600">/</span>
722-
<FrameworkRefinement />
723-
<span className="text-gray-400 dark:text-gray-600">/</span>
724-
<SearchBox
725-
placeholder="Search..."
726-
classNames={{
727-
root: 'flex-1',
728-
form: 'flex items-center',
729-
input:
730-
'w-full outline-none font-bold [&::-webkit-search-cancel-button]:hidden bg-transparent',
731-
submit: 'hidden',
732-
reset: 'p-1 opacity-50 hover:opacity-100',
733-
}}
734-
resetIconComponent={resetIconComponent}
735-
// eslint-disable-next-line jsx-a11y/no-autofocus
736-
autoFocus
710+
attributesToRetrieve={[
711+
'hierarchy.lvl1',
712+
'hierarchy.lvl2',
713+
'hierarchy.lvl3',
714+
'hierarchy.lvl4',
715+
'hierarchy.lvl5',
716+
'hierarchy.lvl6',
717+
'url',
718+
'content',
719+
'library',
720+
]}
721+
attributesToHighlight={[
722+
'hierarchy.lvl1',
723+
'hierarchy.lvl2',
724+
'hierarchy.lvl3',
725+
'hierarchy.lvl4',
726+
'hierarchy.lvl5',
727+
'hierarchy.lvl6',
728+
'content',
729+
]}
730+
attributesToSnippet={['content:50']}
731+
filters="version:latest"
737732
/>
738-
</div>
739-
<SearchResults focusedIndex={focusedIndex} />
733+
<div className="flex items-center gap-2 px-4 py-3 overflow-visible">
734+
<Search className="w-5 h-5 opacity-50 flex-none" />
735+
<LibraryRefinement />
736+
<span className="text-gray-400 dark:text-gray-600">/</span>
737+
<FrameworkRefinement />
738+
<span className="text-gray-400 dark:text-gray-600">/</span>
739+
<SearchBox
740+
placeholder="Search..."
741+
classNames={{
742+
root: 'flex-1',
743+
form: 'flex items-center',
744+
input:
745+
'w-full outline-none font-bold [&::-webkit-search-cancel-button]:hidden bg-transparent',
746+
submit: 'hidden',
747+
reset: 'p-1 opacity-50 hover:opacity-100',
748+
}}
749+
resetIconComponent={resetIconComponent}
750+
// eslint-disable-next-line jsx-a11y/no-autofocus
751+
autoFocus
752+
/>
753+
</div>
754+
<SearchResults focusedIndex={focusedIndex} />
740755
</SearchFiltersProvider>
741756
</InstantSearch>
742757
</div>
@@ -768,8 +783,12 @@ function SearchResults({ focusedIndex }: { focusedIndex: number }) {
768783
frameworkItems.find((item) => item.isRefined)?.value || null
769784

770785
// Use Algolia values when available, fall back to shared state when empty
771-
const refinedLibrary = libraryItems.length > 0 ? algoliaRefinedLibrary : selectedLibrary || null
772-
const refinedFramework = frameworkItems.length > 0 ? algoliaRefinedFramework : selectedFramework || null
786+
const refinedLibrary =
787+
libraryItems.length > 0 ? algoliaRefinedLibrary : selectedLibrary || null
788+
const refinedFramework =
789+
frameworkItems.length > 0
790+
? algoliaRefinedFramework
791+
: selectedFramework || null
773792

774793
const clearFramework = () => {
775794
if (refinedFramework) {
@@ -819,7 +838,9 @@ function SearchResults({ focusedIndex }: { focusedIndex: number }) {
819838
<div className="mt-6 flex gap-8 justify-center">
820839
{!selectedLibrary && (
821840
<div className="flex flex-col gap-2">
822-
<p className="text-xs font-medium uppercase tracking-wide opacity-60">Libraries</p>
841+
<p className="text-xs font-medium uppercase tracking-wide opacity-60">
842+
Libraries
843+
</p>
823844
<div className="flex flex-wrap gap-1.5 max-w-xs">
824845
{libraries
825846
.filter((lib) => 'bgStyle' in lib)
@@ -843,10 +864,14 @@ function SearchResults({ focusedIndex }: { focusedIndex: number }) {
843864
)}
844865
{!selectedFramework && frameworkItems.length > 0 && (
845866
<div className="flex flex-col gap-2">
846-
<p className="text-xs font-medium uppercase tracking-wide opacity-60">Frameworks</p>
867+
<p className="text-xs font-medium uppercase tracking-wide opacity-60">
868+
Frameworks
869+
</p>
847870
<div className="flex flex-wrap gap-1.5 max-w-xs">
848871
{frameworkItems.map((item) => {
849-
const fw = frameworkOptions.find((f) => f.value === item.value)
872+
const fw = frameworkOptions.find(
873+
(f) => f.value === item.value,
874+
)
850875
if (!fw) return null
851876
return (
852877
<button
@@ -857,7 +882,11 @@ function SearchResults({ focusedIndex }: { focusedIndex: number }) {
857882
}}
858883
className="flex items-center gap-1.5 px-2 py-1 text-xs font-bold rounded bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors"
859884
>
860-
<img src={fw.logo} alt={fw.label} className="w-3.5 h-3.5" />
885+
<img
886+
src={fw.logo}
887+
alt={fw.label}
888+
className="w-3.5 h-3.5"
889+
/>
861890
{fw.label}
862891
</button>
863892
)

0 commit comments

Comments
 (0)