Skip to content

Commit

Permalink
Merge pull request moroshko#760 from DoloMike/bug/highlightFirstSugge…
Browse files Browse the repository at this point in the history
…stion
  • Loading branch information
pimterry authored Nov 27, 2020
2 parents f42a549 + 362230c commit ebf4c35
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 18 deletions.
13 changes: 13 additions & 0 deletions src/Autosuggest.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,13 @@ export default class Autosuggest extends Component {

// eslint-disable-next-line camelcase, react/sort-comp
UNSAFE_componentWillReceiveProps(nextProps) {
// When highlightFirstSuggestion becomes deactivated, if the first suggestion was
// set, we should reset the suggestion back to the unselected default state.
const shouldResetHighlighting =
this.state.highlightedSuggestionIndex === 0 &&
this.props.highlightFirstSuggestion &&
!nextProps.highlightFirstSuggestion;

if (shallowEqualArrays(nextProps.suggestions, this.props.suggestions)) {
if (
nextProps.highlightFirstSuggestion &&
Expand All @@ -143,12 +150,18 @@ export default class Autosuggest extends Component {
this.justMouseEntered === false
) {
this.highlightFirstSuggestion();
} else if (shouldResetHighlighting) {
this.resetHighlightedSuggestion();
}
} else {
if (this.willRenderSuggestions(nextProps, REASON_SUGGESTIONS_UPDATED)) {
if (this.state.isCollapsed && !this.justSelectedSuggestion) {
this.revealSuggestions();
}

if (shouldResetHighlighting) {
this.resetHighlightedSuggestion();
}
} else {
this.resetHighlightedSuggestion();
}
Expand Down
31 changes: 19 additions & 12 deletions test/focus-first-suggestion/AutosuggestApp.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,46 +4,52 @@ import Autosuggest from '../../src/Autosuggest';
import languages from '../plain-list/languages';
import { escapeRegexCharacters } from '../../demo/src/components/utils/utils.js';

const getMatchingLanguages = value => {
const getMatchingLanguages = (value) => {
const escapedValue = escapeRegexCharacters(value.trim());
const regex = new RegExp('^' + escapedValue, 'i');

return languages.filter(language => regex.test(language.name));
return languages.filter((language) => regex.test(language.name));
};

let app = null;

export const getSuggestionValue = sinon.spy(suggestion => {
export const setHighlightFirstSuggestion = (value) => {
app.setState({
highlightFirstSuggestion: value
});
};

export const getSuggestionValue = sinon.spy((suggestion) => {
return suggestion.name;
});

export const renderSuggestion = sinon.spy(suggestion => {
export const renderSuggestion = sinon.spy((suggestion) => {
return <span>{suggestion.name}</span>;
});

export const onChange = sinon.spy((event, { newValue }) => {
app.setState({
value: newValue
value: newValue,
});
});

export const onSuggestionsFetchRequested = sinon.spy(({ value }) => {
app.setState({
suggestions: getMatchingLanguages(value)
suggestions: getMatchingLanguages(value),
});
});

export const onSuggestionsClearRequested = sinon.spy(() => {
app.setState({
suggestions: []
suggestions: [],
});
});

export const onSuggestionSelected = sinon.spy();

export const onSuggestionHighlighted = sinon.spy(({ suggestion }) => {
app.setState({
highlightedSuggestion: suggestion
highlightedSuggestion: suggestion,
});
});

Expand All @@ -56,15 +62,16 @@ export default class AutosuggestApp extends Component {
this.state = {
value: '',
suggestions: [],
highlightedSuggestion: null
highlightedSuggestion: null,
highlightFirstSuggestion: false
};
}

render() {
const { value, suggestions } = this.state;
const { value, suggestions, highlightFirstSuggestion } = this.state;
const inputProps = {
value,
onChange
onChange,
};

return (
Expand All @@ -77,7 +84,7 @@ export default class AutosuggestApp extends Component {
getSuggestionValue={getSuggestionValue}
renderSuggestion={renderSuggestion}
inputProps={inputProps}
highlightFirstSuggestion={true}
highlightFirstSuggestion={highlightFirstSuggestion}
/>
);
}
Expand Down
45 changes: 39 additions & 6 deletions test/focus-first-suggestion/AutosuggestApp.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,50 @@ import {
clickEnter,
clickDown,
setInputValue,
focusAndSetInputValue
focusAndSetInputValue,
} from '../helpers';
import AutosuggestApp, {
onChange,
onSuggestionSelected,
onSuggestionHighlighted
onSuggestionHighlighted,
setHighlightFirstSuggestion,
} from './AutosuggestApp';

describe('Autosuggest with highlightFirstSuggestion={true}', () => {
beforeEach(() => {
init(TestUtils.renderIntoDocument(<AutosuggestApp />));
setHighlightFirstSuggestion(true);
});

describe('when highlightFirstSuggestion changes from true to false', () => {
it("should unhighlight the suggestion", () => {
focusAndSetInputValue('j');
expectHighlightedSuggestion('Java');

setHighlightFirstSuggestion(false);
expectHighlightedSuggestion(null);
});

it("should retain the selected suggestion if it was set manually", () => {
focusAndSetInputValue('j');
expectHighlightedSuggestion('Java');
clickDown();
expectHighlightedSuggestion('JavaScript');

setHighlightFirstSuggestion(false);
expectHighlightedSuggestion('JavaScript');
});

it("should re-highlight the suggestion if it becomes true again", () => {
focusAndSetInputValue('j');
expectHighlightedSuggestion('Java');

setHighlightFirstSuggestion(false);
expectHighlightedSuggestion(null);

setHighlightFirstSuggestion(true);
expectHighlightedSuggestion('Java');
});
});

describe('when typing and matches exist', () => {
Expand Down Expand Up @@ -117,7 +150,7 @@ describe('Autosuggest with highlightFirstSuggestion={true}', () => {
expect(onChange).to.have.been.calledOnce;
expect(onChange).to.be.calledWith(syntheticEventMatcher, {
newValue: 'Perl',
method: 'enter'
method: 'enter',
});
});
});
Expand All @@ -135,7 +168,7 @@ describe('Autosuggest with highlightFirstSuggestion={true}', () => {
suggestionValue: 'Perl',
suggestionIndex: 0,
sectionIndex: null,
method: 'enter'
method: 'enter',
}
);
});
Expand All @@ -147,7 +180,7 @@ describe('Autosuggest with highlightFirstSuggestion={true}', () => {
focusAndSetInputValue('p');
expect(onSuggestionHighlighted).to.have.been.calledOnce;
expect(onSuggestionHighlighted).to.have.been.calledWithExactly({
suggestion: { name: 'Perl', year: 1987 }
suggestion: { name: 'Perl', year: 1987 },
});
});

Expand All @@ -157,7 +190,7 @@ describe('Autosuggest with highlightFirstSuggestion={true}', () => {
focusAndSetInputValue('c+');
expect(onSuggestionHighlighted).to.have.been.calledOnce;
expect(onSuggestionHighlighted).to.have.been.calledWithExactly({
suggestion: { name: 'C++', year: 1983 }
suggestion: { name: 'C++', year: 1983 },
});
});
});
Expand Down

0 comments on commit ebf4c35

Please sign in to comment.