Skip to content

Commit

Permalink
Merge pull request #4785 from Rall3n/current-input-value-meta
Browse files Browse the repository at this point in the history
Add `prevInputValue` to action meta
  • Loading branch information
JedWatson committed Oct 28, 2021
2 parents e67ea16 + a694069 commit 20ea030
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 21 deletions.
5 changes: 5 additions & 0 deletions .changeset/gorgeous-berries-tan.md
@@ -0,0 +1,5 @@
---
'react-select': minor
---

Add `prevInputValue` to action meta
24 changes: 11 additions & 13 deletions docs/examples/OnSelectResetsInput.tsx
Expand Up @@ -3,43 +3,41 @@ import Select, { InputActionMeta } from 'react-select';
import { colourOptions } from '../data';

interface State {
readonly inputValue: string;
readonly menuIsOpen?: boolean;
}

export default class OnSelectResetsInput extends Component<{}, State> {
state: State = {
inputValue: '',
};
onInputChange = (inputValue: string, { action }: InputActionMeta) => {
state: State = {};
onInputChange = (
inputValue: string,
{ action, prevInputValue }: InputActionMeta
) => {
console.log(inputValue, action);
switch (action) {
case 'input-change':
this.setState({ inputValue });
return;
return inputValue;
case 'menu-close':
console.log(this.state.inputValue);
console.log(prevInputValue);
let menuIsOpen = undefined;
if (this.state.inputValue) {
if (prevInputValue) {
menuIsOpen = true;
}
this.setState({
menuIsOpen,
});
return;
return prevInputValue;
default:
return;
return prevInputValue;
}
};
render() {
const { inputValue, menuIsOpen } = this.state;
const { menuIsOpen } = this.state;
return (
<Select
isMulti
defaultValue={colourOptions[0]}
isClearable
isSearchable
inputValue={inputValue}
onInputChange={this.onInputChange}
name="color"
options={colourOptions}
Expand Down
20 changes: 14 additions & 6 deletions packages/react-select/src/Select.tsx
Expand Up @@ -758,7 +758,10 @@ export default class Select<
this.props.onMenuOpen();
}
onMenuClose() {
this.onInputChange('', { action: 'menu-close' });
this.onInputChange('', {
action: 'menu-close',
prevInputValue: this.props.inputValue,
});
this.props.onMenuClose();
}
onInputChange(newValue: string, actionMeta: InputActionMeta) {
Expand Down Expand Up @@ -896,8 +899,8 @@ export default class Select<
action: SetValueAction,
option?: Option
) => {
const { closeMenuOnSelect, isMulti } = this.props;
this.onInputChange('', { action: 'set-value' });
const { closeMenuOnSelect, isMulti, inputValue } = this.props;
this.onInputChange('', { action: 'set-value', prevInputValue: inputValue });
if (closeMenuOnSelect) {
this.setState({ inputIsHiddenAfterUpdate: !isMulti });
this.onMenuClose();
Expand Down Expand Up @@ -1345,9 +1348,10 @@ export default class Select<
// ==============================

handleInputChange: FormEventHandler<HTMLInputElement> = (event) => {
const { inputValue: prevInputValue } = this.props;
const inputValue = event.currentTarget.value;
this.setState({ inputIsHiddenAfterUpdate: false });
this.onInputChange(inputValue, { action: 'input-change' });
this.onInputChange(inputValue, { action: 'input-change', prevInputValue });
if (!this.props.menuIsOpen) {
this.onMenuOpen();
}
Expand All @@ -1366,14 +1370,15 @@ export default class Select<
this.openAfterFocus = false;
};
onInputBlur: FocusEventHandler<HTMLInputElement> = (event) => {
const { inputValue: prevInputValue } = this.props;
if (this.menuListRef && this.menuListRef.contains(document.activeElement)) {
this.inputRef!.focus();
return;
}
if (this.props.onBlur) {
this.props.onBlur(event);
}
this.onInputChange('', { action: 'input-blur' });
this.onInputChange('', { action: 'input-blur', prevInputValue });
this.onMenuClose();
this.setState({
focusedValue: null,
Expand Down Expand Up @@ -1475,7 +1480,10 @@ export default class Select<
case 'Escape':
if (menuIsOpen) {
this.setState({ inputIsHiddenAfterUpdate: false });
this.onInputChange('', { action: 'menu-close' });
this.onInputChange('', {
action: 'menu-close',
prevInputValue: inputValue,
});
this.onMenuClose();
} else if (isClearable && escapeClearsValue) {
this.clearValue();
Expand Down
11 changes: 9 additions & 2 deletions packages/react-select/src/__tests__/Select.test.tsx
Expand Up @@ -1290,7 +1290,10 @@ cases(
keyCode: 27,
key: 'Escape',
});
expect(spy).toHaveBeenCalledWith('', { action: 'menu-close' });
expect(spy).toHaveBeenCalledWith('', {
action: 'menu-close',
prevInputValue: 'test',
});
},
{
'single select > should call onInputChange prop with empty string as inputValue':
Expand Down Expand Up @@ -3013,9 +3016,13 @@ test('close menu on hitting escape and clear input value if menu is open even if
expect(onMenuCloseSpy).toHaveBeenCalled();
// once by onMenuClose and other is direct
expect(onInputChangeSpy).toHaveBeenCalledTimes(2);
expect(onInputChangeSpy).toHaveBeenCalledWith('', { action: 'menu-close' });
expect(onInputChangeSpy).toHaveBeenCalledWith('', {
action: 'menu-close',
prevInputValue: '',
});
expect(onInputChangeSpy).toHaveBeenLastCalledWith('', {
action: 'menu-close',
prevInputValue: '',
});
});

Expand Down
2 changes: 2 additions & 0 deletions packages/react-select/src/types.ts
Expand Up @@ -171,6 +171,8 @@ export type InputAction =

export interface InputActionMeta {
action: InputAction;
/** The previous value of the search input. */
prevInputValue: string;
}

export type MenuPlacement = 'auto' | 'bottom' | 'top';
Expand Down

0 comments on commit 20ea030

Please sign in to comment.