Skip to content

Commit

Permalink
Fix/highlight matched substrings (#509)
Browse files Browse the repository at this point in the history
* fix(highlight-matched-substrings): highlight all matches coming from the Google API

* fix(highlight-matched-substrings): find matched substrings in fixtures case insensitive

* test(highlight-matched-substrings): add test for multiple matched substrings
  • Loading branch information
plumdumpling committed Oct 2, 2023
1 parent bfd0517 commit f3cb836
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 33 deletions.
12 changes: 7 additions & 5 deletions src/Geosuggest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -372,10 +372,12 @@ export default class GeoSuggest extends React.Component<Props, State> {
suggests.push({
...fixture,
isFixture: true,
matchedSubstrings: {
length: userInput.length,
offset: fixture.label.indexOf(userInput)
},
matchedSubstrings: [
{
length: userInput.length,
offset: fixture.label.search(regex)
}
],
placeId: fixture.placeId || fixture.label
});
}
Expand All @@ -390,7 +392,7 @@ export default class GeoSuggest extends React.Component<Props, State> {
label: this.props.getSuggestLabel
? this.props.getSuggestLabel(suggest)
: '',
matchedSubstrings: suggest.matched_substrings[0],
matchedSubstrings: suggest.matched_substrings,
placeId: suggest.place_id
});
}
Expand Down
47 changes: 21 additions & 26 deletions src/suggest-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,8 @@ export default class SuggestItem extends React.PureComponent<Props, unknown> {
/**
* Makes a text bold
*/
makeBold(element: string, key: string): JSX.Element {
return (
<b className="geosuggest__item__matched-text" key={key}>
{element}
</b>
);
makeBold(element: string) {
return <b className="geosuggest__item__matched-text">{element}</b>;
}

/**
Expand All @@ -59,31 +55,30 @@ export default class SuggestItem extends React.PureComponent<Props, unknown> {
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 (
<span>
{pre}
{boldPart}
{post}
</span>
);
return <span>{parts}</span>;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/types/suggest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ export interface Suggest {
readonly matchedSubstrings?: {
offset: number;
length: number;
};
}[];
readonly className?: string;
}
17 changes: 16 additions & 1 deletion test/Geosuggest_spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions test/fixtures/predictions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down

0 comments on commit f3cb836

Please sign in to comment.