@@ -32,10 +32,7 @@ export default function Examples(props: {
3232 const [ productFilter , setProductFilter ] = useState < string [ ] > ( [ ] ) ;
3333 const [ platformFilter , setPlatformFilter ] = useState < string [ ] > ( [ ] ) ;
3434 const [ blockchainFilter , setBlockchainFilter ] = useState < string [ ] > ( [ ] ) ;
35- const [ tagFilteredExampleMap , setTagFilteredExampleMap ] =
36- useState < ExamplesInterface [ ] > ( sortedExamples ) ;
37- const [ searchFilteredExampleMap , setSearchFilteredExampleMap ] =
38- useState < ExamplesInterface [ ] > ( tagFilteredExampleMap ) ;
35+ const [ filteredExamples , setFilteredExamples ] = useState < ExamplesInterface [ ] > ( sortedExamples ) ;
3936
4037 const chevron = (
4138 < svg width = "14" height = "14" viewBox = "0 0 16 16" fill = "none" xmlns = "http://www.w3.org/2000/svg" >
@@ -49,24 +46,27 @@ export default function Examples(props: {
4946 </ svg >
5047 ) ;
5148
49+ // Apply tag filters first
5250 useEffect ( ( ) => {
53- function filterByTags ( ) {
54- let examples ;
55- examples = sortedExamples ;
56- examples = examples . filter ( ( item ) => {
51+ let filtered = sortedExamples ;
52+
53+ if ( productFilter . length > 0 || platformFilter . length > 0 || blockchainFilter . length > 0 ) {
54+ filtered = sortedExamples . filter ( ( item ) => {
5755 const prodFil =
5856 productFilter . length === 0 || productFilter . some ( ( tag ) => item . tags . includes ( tag ) ) ;
5957 const platFil =
6058 platformFilter . length === 0 || platformFilter . some ( ( tag ) => item . tags . includes ( tag ) ) ;
6159 const blockFil =
6260 blockchainFilter . length === 0 || blockchainFilter . some ( ( tag ) => item . tags . includes ( tag ) ) ;
6361
64- return [ prodFil , platFil , blockFil ] . some ( ( result ) => result === true ) ;
62+ return prodFil && platFil && blockFil ;
6563 } ) ;
66- setTagFilteredExampleMap ( examples ) ;
6764 }
68- filterByTags ( ) ;
69- } , [ productFilter , platformFilter , blockchainFilter , searchFilteredExampleMap ] ) ;
65+
66+ // Reset search when filters change
67+ setSearchInput ( "" ) ;
68+ setFilteredExamples ( filtered ) ;
69+ } , [ productFilter , platformFilter , blockchainFilter ] ) ;
7070
7171 const onChangeProduct = ( e ) => {
7272 const filterValue = e . map ( ( item ) => item . value ) ;
@@ -83,55 +83,42 @@ export default function Examples(props: {
8383 const onChangeBlockchain = ( e ) => {
8484 const filterValue = e . map ( ( item ) => item . value ) ;
8585 setBlockchainFilter ( filterValue ) ;
86- setTags ( [ ...productFilter , ...filterValue , ...platformFilter ] ) ;
86+ setTags ( [ ...productFilter , ...platformFilter , ...filterValue ] ) ;
8787 } ;
8888
8989 function highlightSearchText ( text ) {
90- if ( searchInput === "" ) {
90+ if ( ! searchInput . trim ( ) ) {
9191 return text ;
9292 }
93- let inputKeywords = searchInput . split ( " " ) ;
94- inputKeywords = inputKeywords . filter ( ( keyword ) => keyword !== "" ) ;
95- const keywords = inputKeywords
96- . map ( ( keyword ) => {
97- return `(${ keyword } )` ;
98- } )
99- . join ( "|" ) ;
100- const regex = new RegExp ( keywords , "gi" ) ;
101- const matches = text . match ( regex ) ;
93+ const searchTerms = searchInput . trim ( ) . split ( / \s + / ) ;
94+ const regex = new RegExp ( `(${ searchTerms . join ( "|" ) } )` , "gi" ) ;
10295 const parts = text . split ( regex ) ;
103- if ( matches ) {
104- return (
105- < span >
106- { parts . filter ( String ) . map ( ( part , i ) => {
107- return regex . test ( part ) ? < mark key = { i } > { part } </ mark > : < span key = { i } > { part } </ span > ;
108- } ) }
109- </ span >
110- ) ;
111- }
112- return text ;
96+
97+ return (
98+ < span >
99+ { parts . map ( ( part , i ) => {
100+ return regex . test ( part ) ? < mark key = { i } > { part } </ mark > : < span key = { i } > { part } </ span > ;
101+ } ) }
102+ </ span >
103+ ) ;
113104 }
114105
115106 function onChangeSearch ( input ) {
116107 setSearchInput ( input ) ;
108+ }
117109
118- const inputKeywords = input . trim ( ) . split ( " " ) . filter ( Boolean ) ;
110+ // Filter the already filtered examples based on search
111+ const displayedExamples = filteredExamples . filter ( ( item ) => {
112+ if ( ! searchInput . trim ( ) ) return true ;
119113
120- function searchFilter ( item ) {
121- return (
122- inputKeywords . some ( ( key ) => item . title . toLowerCase ( ) . includes ( key . toLowerCase ( ) ) ) ||
123- inputKeywords . some ( ( key ) => item . description . toLowerCase ( ) . includes ( key . toLowerCase ( ) ) ) ||
124- inputKeywords . some ( ( key ) =>
125- item . tags . map ( ( tag ) => tag . toLowerCase ( ) . includes ( key . toLowerCase ( ) ) ) ,
126- )
127- ) ;
128- }
129- let examples = tagFilteredExampleMap ;
130- if ( input !== "" ) {
131- examples = tagFilteredExampleMap . filter ( ( item ) => searchFilter ( item ) ) ;
132- }
133- setSearchFilteredExampleMap ( examples ) ;
134- }
114+ const searchTerms = searchInput . toLowerCase ( ) . trim ( ) . split ( / \s + / ) ;
115+ return searchTerms . every (
116+ ( term ) =>
117+ item . title . toLowerCase ( ) . includes ( term ) ||
118+ item . description . toLowerCase ( ) . includes ( term ) ||
119+ item . tags . some ( ( tag ) => tag . toLowerCase ( ) . includes ( term ) ) ,
120+ ) ;
121+ } ) ;
135122
136123 function renderArticle ( article ) {
137124 return (
@@ -165,7 +152,7 @@ export default function Examples(props: {
165152 < div className = { styles . tagContainer } >
166153 { article . tags &&
167154 article . tags . map ( ( tag ) => {
168- if ( tags . includes ( tag ) || searchInput . split ( " " ) . includes ( tag ) ) {
155+ if ( tags . includes ( tag ) || searchInput . split ( / \s + / ) . includes ( tag ) ) {
169156 return (
170157 < div key = { tag } className = { styles . tagActive } >
171158 { tag }
@@ -177,7 +164,7 @@ export default function Examples(props: {
177164
178165 { article . tags &&
179166 article . tags . map ( ( tag ) => {
180- if ( ! ( tags . includes ( tag ) || searchInput . split ( " " ) . includes ( tag ) ) ) {
167+ if ( ! ( tags . includes ( tag ) || searchInput . split ( / \s + / ) . includes ( tag ) ) ) {
181168 return (
182169 < div key = { tag } className = { styles . tag } >
183170 { tag }
@@ -212,7 +199,7 @@ export default function Examples(props: {
212199 </ svg >
213200 </ div >
214201 < input
215- placeholder = "Quick search for anything "
202+ placeholder = "Search within filtered results "
216203 value = { searchInput }
217204 onChange = { ( event ) => onChangeSearch ( event . target . value ) }
218205 type = "text"
@@ -271,8 +258,8 @@ export default function Examples(props: {
271258 ) }
272259 </ div >
273260 < div className = { styles . container } >
274- { tagFilteredExampleMap . map ( ( item ) => renderArticle ( item ) ) }
275- { tagFilteredExampleMap . length === 0 && (
261+ { displayedExamples . map ( ( item ) => renderArticle ( item ) ) }
262+ { displayedExamples . length === 0 && (
276263 < div className = { styles . noResults } >
277264 < p > No Results Found</ p >
278265 </ div >
0 commit comments