diff --git a/.gitignore b/.gitignore
index 91d9cdd2..74623dac 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,4 @@ npm-debug.log
yarn.lock
*.log
.DS
+.idea
diff --git a/README.md b/README.md
index 80adda87..aa6b5e0e 100644
--- a/README.md
+++ b/README.md
@@ -163,6 +163,7 @@ class Example extends React.Component {
| [`getSuggestionValue`](#get-suggestion-value-prop) | Function | ✓ | Implement it to teach Autosuggest what should be the input value when suggestion is clicked. |
| [`renderSuggestion`](#render-suggestion-prop) | Function | ✓ | Use your imagination to define how suggestions are rendered. |
| [`inputProps`](#input-props-prop) | Object | ✓ | Pass through arbitrary props to the input. It must contain at least `value` and `onChange`. |
+| [`containerProps`](#container-props-prop) | Object | | Pass through arbitrary props to the container. Useful if you need to override the default props set by Autowhatever, for example, for accessibility. |
| [`onSuggestionSelected`](#on-suggestion-selected-prop) | Function | | Will be called every time suggestion is selected via mouse or keyboard. |
| [`onSuggestionHighlighted`](#on-suggestion-highlighted-prop) | Function | | Will be called every time the highlighted suggestion changes. |
| [`shouldRenderSuggestions`](#should-render-suggestions-prop) | Function | | When the input is focused, Autosuggest will consult this function when to render suggestions. Use it, for example, if you want to display suggestions when input value is at least 2 characters long. |
@@ -367,6 +368,19 @@ where:
- `highlightedSuggestion` - the suggestion that was highlighted just before the input lost focus, or `null` if there was no highlighted suggestion.
+
+
+#### containerProps
+
+Provides arbitrary properties to the outer `div` container of Autosuggest. Allows the override of accessibility properties.
+
+```js
+const containerProps = {
+ dataId: 'my-data-id'
+ // ... any other properties
+};
+```
+
#### onSuggestionSelected (optional)
diff --git a/package-lock.json b/package-lock.json
index 588b96cc..05914446 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "react-autosuggest",
- "version": "10.0.4",
+ "version": "10.1.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 2a30bee1..92e5e85c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "react-autosuggest",
- "version": "10.0.4",
+ "version": "10.1.0",
"description": "WAI-ARIA compliant React autosuggest component",
"main": "dist/index.js",
"repository": {
diff --git a/src/Autosuggest.js b/src/Autosuggest.js
index 433e43c9..c4a3757a 100644
--- a/src/Autosuggest.js
+++ b/src/Autosuggest.js
@@ -95,6 +95,7 @@ export default class Autosuggest extends Component {
highlightFirstSuggestion: PropTypes.bool,
theme: PropTypes.object,
id: PropTypes.string,
+ containerProps: PropTypes.object, // Arbitrary container props
};
static defaultProps = {
@@ -107,8 +108,35 @@ export default class Autosuggest extends Component {
highlightFirstSuggestion: false,
theme: defaultTheme,
id: '1',
+ containerProps: {},
};
+ static getDerivedStateFromProps(props, state) {
+ const {
+ suggestions,
+ inputProps: { value },
+ shouldRenderSuggestions,
+ } = props;
+ let nextState = {};
+
+ if (
+ suggestions.length > 0 &&
+ shouldRenderSuggestions(value, REASON_SUGGESTIONS_UPDATED)
+ ) {
+ if (state.isCollapsed && !this.justSelectedSuggestion) {
+ nextState = { isCollapsed: false };
+ }
+ } else {
+ nextState = {
+ highlightedSectionIndex: null,
+ highlightedSuggestionIndex: null,
+ highlightedSuggestion: null,
+ valueBeforeUpDown: null,
+ };
+ }
+ return nextState;
+ }
+
constructor({ alwaysRenderSuggestions }) {
super();
@@ -135,62 +163,39 @@ export default class Autosuggest extends Component {
this.suggestionsContainer = this.autowhatever.itemsContainer;
}
- // 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 &&
- nextProps.suggestions.length > 0 &&
- this.justPressedUpDown === false &&
- 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();
- }
- }
- }
-
+ /**
+ When highlightFirstSuggestion becomes deactivated, if the first suggestion was
+ set, we should reset the suggestion back to the unselected default state.
+ */
componentDidUpdate(prevProps, prevState) {
const {
- suggestions,
onSuggestionHighlighted,
highlightFirstSuggestion,
+ suggestions,
+ multiSection,
} = this.props;
+ const { highlightedSuggestionIndex } = this.state;
+ const hasSuggestions = suggestions.length > 0;
+ const suggestionsDidChange = !shallowEqualArrays(
+ suggestions,
+ prevProps.suggestions
+ );
+ if (hasSuggestions && suggestionsDidChange && highlightFirstSuggestion) {
+ this.updateHighlightedSuggestion(multiSection ? 0 : null, 0);
+ }
if (
- !shallowEqualArrays(suggestions, prevProps.suggestions) &&
- suggestions.length > 0 &&
- highlightFirstSuggestion
+ prevProps.highlightFirstSuggestion &&
+ !highlightFirstSuggestion &&
+ highlightedSuggestionIndex === 0
) {
- this.highlightFirstSuggestion();
- return;
+ this.resetHighlightedSuggestion();
}
-
if (onSuggestionHighlighted) {
const highlightedSuggestion = this.getHighlightedSuggestion();
const prevHighlightedSuggestion = prevState.highlightedSuggestion;
- if (highlightedSuggestion != prevHighlightedSuggestion) {
+ if (highlightedSuggestion !== prevHighlightedSuggestion) {
onSuggestionHighlighted({
suggestion: highlightedSuggestion,
});
@@ -382,9 +387,9 @@ export default class Autosuggest extends Component {
});
};
- highlightFirstSuggestion = () => {
- this.updateHighlightedSuggestion(this.props.multiSection ? 0 : null, 0);
- };
+ // highlightFirstSuggestion = () => {
+ // this.updateHighlightedSuggestion(this.props.multiSection ? 0 : null, 0);
+ // };
onDocumentMouseUp = () => {
if (this.pressedSuggestion && !this.justSelectedSuggestion) {
@@ -558,6 +563,7 @@ export default class Autosuggest extends Component {
getSuggestionValue,
alwaysRenderSuggestions,
highlightFirstSuggestion,
+ containerProps,
} = this.props;
const {
isFocused,
@@ -806,6 +812,7 @@ export default class Autosuggest extends Component {
getSectionItems={getSectionSuggestions}
highlightedSectionIndex={highlightedSectionIndex}
highlightedItemIndex={highlightedSuggestionIndex}
+ containerProps={containerProps}
inputProps={autowhateverInputProps}
itemProps={this.itemProps}
theme={mapToAutowhateverTheme(theme)}
diff --git a/src/Autowhatever.js b/src/Autowhatever.js
index fe2ee8e7..fd2c247a 100644
--- a/src/Autowhatever.js
+++ b/src/Autowhatever.js
@@ -95,25 +95,18 @@ export default class Autowhatever extends Component {
this.ensureHighlightedItemIsVisible();
}
- // eslint-disable-next-line camelcase, react/sort-comp
- UNSAFE_componentWillReceiveProps(nextProps) {
- if (nextProps.items !== this.props.items) {
- this.setSectionsItems(nextProps);
- }
+ componentDidUpdate(prevProps) {
+ const itemsDidChange = prevProps.items !== this.props.items;
- if (
- nextProps.items !== this.props.items ||
- nextProps.multiSection !== this.props.multiSection
- ) {
- this.setSectionIterator(nextProps);
+ if (itemsDidChange) {
+ this.setSectionsItems(this.props);
}
-
- if (nextProps.theme !== this.props.theme) {
- this.setTheme(nextProps);
+ if (itemsDidChange || prevProps.multiSection !== this.props.multiSection) {
+ this.setSectionIterator(this.props);
+ }
+ if (prevProps.theme !== this.props.theme) {
+ this.setTheme(this.props);
}
- }
-
- componentDidUpdate() {
this.ensureHighlightedItemIsVisible();
}