From 195d6c1473c08029842be2659795eaa5e7f05aba Mon Sep 17 00:00:00 2001 From: Leslie Zimmermann Date: Wed, 9 Aug 2023 13:51:48 +0200 Subject: [PATCH 1/3] fix(highlight-matched-substrings): highlight all matches coming from the Google API --- src/Geosuggest.tsx | 12 ++++++----- src/suggest-item.tsx | 47 ++++++++++++++++++++------------------------ src/types/suggest.ts | 2 +- 3 files changed, 29 insertions(+), 32 deletions(-) diff --git a/src/Geosuggest.tsx b/src/Geosuggest.tsx index 417643c..c59cdce 100644 --- a/src/Geosuggest.tsx +++ b/src/Geosuggest.tsx @@ -372,10 +372,12 @@ export default class GeoSuggest extends React.Component { suggests.push({ ...fixture, isFixture: true, - matchedSubstrings: { - length: userInput.length, - offset: fixture.label.indexOf(userInput) - }, + matchedSubstrings: [ + { + length: userInput.length, + offset: fixture.label.indexOf(userInput) + } + ], placeId: fixture.placeId || fixture.label }); } @@ -390,7 +392,7 @@ export default class GeoSuggest extends React.Component { label: this.props.getSuggestLabel ? this.props.getSuggestLabel(suggest) : '', - matchedSubstrings: suggest.matched_substrings[0], + matchedSubstrings: suggest.matched_substrings, placeId: suggest.place_id }); } diff --git a/src/suggest-item.tsx b/src/suggest-item.tsx index 5b89373..8d2386a 100644 --- a/src/suggest-item.tsx +++ b/src/suggest-item.tsx @@ -43,12 +43,8 @@ export default class SuggestItem extends React.PureComponent { /** * Makes a text bold */ - makeBold(element: string, key: string): JSX.Element { - return ( - - {element} - - ); + makeBold(element: string) { + return {element}; } /** @@ -59,31 +55,30 @@ export default class SuggestItem extends React.PureComponent { return suggest.label; } - const start: number = suggest.matchedSubstrings.offset; - const length: number = suggest.matchedSubstrings.length; - const end: number = start + length; - const boldPart = this.makeBold( - suggest.label.substring(start, end), - suggest.label - ); + const parts = []; - let pre = ''; - let post = ''; + let previousEnd = 0; + + for (const {offset: start, length} of suggest.matchedSubstrings) { + // Add non-matching substring before and between matches + if (start > previousEnd) { + parts.push(suggest.label.substring(previousEnd, start)); + } - if (start > 0) { - pre = suggest.label.slice(0, start); + // Add matching substring as bold text + const end = start + length; + const match = this.makeBold(suggest.label.substring(start, end)); + parts.push(match); + + previousEnd = end; } - if (end < suggest.label.length) { - post = suggest.label.slice(end); + + // Add non-matching substring after matches + if (previousEnd < suggest.label.length) { + parts.push(suggest.label.substring(previousEnd)); } - return ( - - {pre} - {boldPart} - {post} - - ); + return {parts}; } /** diff --git a/src/types/suggest.ts b/src/types/suggest.ts index 6f86d64..2dc02b7 100644 --- a/src/types/suggest.ts +++ b/src/types/suggest.ts @@ -13,6 +13,6 @@ export interface Suggest { readonly matchedSubstrings?: { offset: number; length: number; - }; + }[]; readonly className?: string; } From 0848408719d24b257f4bda25258f323571bf4284 Mon Sep 17 00:00:00 2001 From: Leslie Zimmermann Date: Wed, 9 Aug 2023 13:54:31 +0200 Subject: [PATCH 2/3] fix(highlight-matched-substrings): find matched substrings in fixtures case insensitive --- src/Geosuggest.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Geosuggest.tsx b/src/Geosuggest.tsx index c59cdce..59676f4 100644 --- a/src/Geosuggest.tsx +++ b/src/Geosuggest.tsx @@ -375,7 +375,7 @@ export default class GeoSuggest extends React.Component { matchedSubstrings: [ { length: userInput.length, - offset: fixture.label.indexOf(userInput) + offset: fixture.label.search(regex) } ], placeId: fixture.placeId || fixture.label From 505389c792f9e5ef88b063f446081614f83e74a8 Mon Sep 17 00:00:00 2001 From: Leslie Zimmermann Date: Wed, 9 Aug 2023 14:03:46 +0200 Subject: [PATCH 3/3] test(highlight-matched-substrings): add test for multiple matched substrings --- test/Geosuggest_spec.tsx | 17 ++++++++++++++++- test/fixtures/predictions.ts | 4 ++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/test/Geosuggest_spec.tsx b/test/Geosuggest_spec.tsx index 65fc1c4..c8d0dc4 100644 --- a/test/Geosuggest_spec.tsx +++ b/test/Geosuggest_spec.tsx @@ -870,13 +870,28 @@ describe('Component: Geosuggest', () => { expect(matchedText).to.have.lengthOf.at.least(1); }); - it('should render a match with minial nodes', () => { + it('should highlight multiple matched substrings', () => { const geoSuggestInput = component.container.querySelector( '.geosuggest__input' ) as HTMLInputElement; fireEvent.change(geoSuggestInput, {target: {value: 'Newa'}}); geoSuggestInput.focus(); + const geoSuggestItems = + component.container.getElementsByClassName('geosuggest__item'); + const matchedText = geoSuggestItems[0].getElementsByClassName( + 'geosuggest__item__matched-text' + ); + expect(matchedText).to.have.lengthOf(2); + }); + + it('should render a match with minimal nodes', () => { + const geoSuggestInput = component.container.querySelector( + '.geosuggest__input' + ) as HTMLInputElement; + fireEvent.change(geoSuggestInput, {target: {value: 'New Jersey'}}); + geoSuggestInput.focus(); + const geoSuggestItems = component.container.getElementsByClassName('geosuggest__item'); expect(geoSuggestItems).to.have.lengthOf(1); diff --git a/test/fixtures/predictions.ts b/test/fixtures/predictions.ts index 02a6ed1..060290c 100644 --- a/test/fixtures/predictions.ts +++ b/test/fixtures/predictions.ts @@ -149,6 +149,10 @@ export default function predictions(): google.maps.places.AutocompletePrediction { length: 2, offset: 0 + }, + { + length: 2, + offset: 8 } ], place_id: 'ChIJHQ6aMnBTwokRc-T-3CrcvOE',