diff --git a/docs/translations/api-docs-joy/autocomplete/autocomplete.json b/docs/translations/api-docs-joy/autocomplete/autocomplete.json
index ae572296547d1a..0f57da64cf78f5 100644
--- a/docs/translations/api-docs-joy/autocomplete/autocomplete.json
+++ b/docs/translations/api-docs-joy/autocomplete/autocomplete.json
@@ -33,7 +33,7 @@
"onChange": "Callback fired when the value changes.
Signature: function(event: React.SyntheticEvent, value: T | Array<T>, reason: string, details?: string) => void event: The event source of the callback. value: The new value of the component. reason: One of "createOption", "selectOption", "removeOption", "blur" or "clear".",
"onClose": "Callback fired when the popup requests to be closed. Use in controlled mode (see open).
Signature: function(event: React.SyntheticEvent, reason: string) => void event: The event source of the callback. reason: Can be: "toggleInput", "escape", "selectOption", "removeOption", "blur".",
"onHighlightChange": "Callback fired when the highlight option changes.
Signature: function(event: React.SyntheticEvent, option: T, reason: string) => void event: The event source of the callback. option: The highlighted option. reason: Can be: "keyboard", "auto", "mouse", "touch".",
- "onInputChange": "Callback fired when the input value changes.
Signature: function(event: React.SyntheticEvent, value: string, reason: string) => void event: The event source of the callback. value: The new value of the text input. reason: Can be: "input" (user input), "reset" (programmatic change), "clear".",
+ "onInputChange": "Callback fired when the input value changes.
Signature: function(event: React.SyntheticEvent, value: string, reason: string) => void event: The event source of the callback. value: The new value of the text input. reason: Can be: "input" (user input), "reset" (programmatic change), "clear", "blur", "selectOption", "removeOption"",
"onOpen": "Callback fired when the popup requests to be opened. Use in controlled mode (see open).
Signature: function(event: React.SyntheticEvent) => void event: The event source of the callback.",
"open": "If true, the component is shown.",
"openText": "Override the default text for the open popup icon button. For localization purposes, you can use the provided translations.",
diff --git a/docs/translations/api-docs/autocomplete/autocomplete.json b/docs/translations/api-docs/autocomplete/autocomplete.json
index 54ebd6ebd1aba9..c3d5fd1d988a97 100644
--- a/docs/translations/api-docs/autocomplete/autocomplete.json
+++ b/docs/translations/api-docs/autocomplete/autocomplete.json
@@ -44,7 +44,7 @@
"onChange": "Callback fired when the value changes.
Signature: function(event: React.SyntheticEvent, value: T | Array<T>, reason: string, details?: string) => void event: The event source of the callback. value: The new value of the component. reason: One of "createOption", "selectOption", "removeOption", "blur" or "clear".",
"onClose": "Callback fired when the popup requests to be closed. Use in controlled mode (see open).
Signature: function(event: React.SyntheticEvent, reason: string) => void event: The event source of the callback. reason: Can be: "toggleInput", "escape", "selectOption", "removeOption", "blur".",
"onHighlightChange": "Callback fired when the highlight option changes.
Signature: function(event: React.SyntheticEvent, option: T, reason: string) => void event: The event source of the callback. option: The highlighted option. reason: Can be: "keyboard", "auto", "mouse", "touch".",
- "onInputChange": "Callback fired when the input value changes.
Signature: function(event: React.SyntheticEvent, value: string, reason: string) => void event: The event source of the callback. value: The new value of the text input. reason: Can be: "input" (user input), "reset" (programmatic change), "clear".",
+ "onInputChange": "Callback fired when the input value changes.
Signature: function(event: React.SyntheticEvent, value: string, reason: string) => void event: The event source of the callback. value: The new value of the text input. reason: Can be: "input" (user input), "reset" (programmatic change), "clear", "blur", "selectOption", "removeOption"",
"onOpen": "Callback fired when the popup requests to be opened. Use in controlled mode (see open).
Signature: function(event: React.SyntheticEvent) => void event: The event source of the callback.",
"open": "If true, the component is shown.",
"openOnFocus": "If true, the popup will open on input focus.",
diff --git a/packages/mui-base/src/useAutocomplete/useAutocomplete.d.ts b/packages/mui-base/src/useAutocomplete/useAutocomplete.d.ts
index de334a48690467..7ef2a796f81645 100644
--- a/packages/mui-base/src/useAutocomplete/useAutocomplete.d.ts
+++ b/packages/mui-base/src/useAutocomplete/useAutocomplete.d.ts
@@ -248,7 +248,7 @@ export interface UseAutocompleteProps<
*
* @param {React.SyntheticEvent} event The event source of the callback.
* @param {string} value The new value of the text input.
- * @param {string} reason Can be: `"input"` (user input), `"reset"` (programmatic change), `"clear"`.
+ * @param {string} reason Can be: `"input"` (user input), `"reset"` (programmatic change), `"clear"`, `"blur"`, `"selectOption"`, `"removeOption"`
*/
onInputChange?: (
event: React.SyntheticEvent,
@@ -320,7 +320,13 @@ export type AutocompleteCloseReason =
| 'selectOption'
| 'removeOption'
| 'blur';
-export type AutocompleteInputChangeReason = 'input' | 'reset' | 'clear';
+export type AutocompleteInputChangeReason =
+ | 'input'
+ | 'reset'
+ | 'clear'
+ | 'blur'
+ | 'selectOption'
+ | 'removeOption';
export type AutocompleteGetTagProps = ({ index }: { index: number }) => {
key: number;
diff --git a/packages/mui-base/src/useAutocomplete/useAutocomplete.js b/packages/mui-base/src/useAutocomplete/useAutocomplete.js
index 8af5d5cbec66bc..8cc02e5f719f6b 100644
--- a/packages/mui-base/src/useAutocomplete/useAutocomplete.js
+++ b/packages/mui-base/src/useAutocomplete/useAutocomplete.js
@@ -164,7 +164,7 @@ export default function useAutocomplete(props) {
const [focused, setFocused] = React.useState(false);
const resetInputValue = React.useCallback(
- (event, newValue) => {
+ (event, newValue, reason) => {
// retain current `inputValue` if new option isn't selected and `clearOnBlur` is false
// When `multiple` is enabled, `newValue` is an array of all selected items including the newly selected item
const isOptionSelected = multiple ? value.length < newValue.length : newValue !== null;
@@ -188,7 +188,7 @@ export default function useAutocomplete(props) {
setInputValueState(newInputValue);
if (onInputChange) {
- onInputChange(event, newInputValue, 'reset');
+ onInputChange(event, newInputValue, reason);
}
},
[getOptionLabel, inputValue, multiple, onInputChange, setInputValueState, clearOnBlur, value],
@@ -247,7 +247,7 @@ export default function useAutocomplete(props) {
return;
}
- resetInputValue(null, value);
+ resetInputValue(null, value, 'reset');
}, [value, resetInputValue, focused, previousProps.value, freeSolo]);
const listboxAvailable = open && filteredOptions.length > 0 && !readOnly;
@@ -682,7 +682,7 @@ export default function useAutocomplete(props) {
}
}
- resetInputValue(event, newValue);
+ resetInputValue(event, newValue, reason);
handleValue(event, newValue, reason, { option });
if (!disableCloseOnSelect && (!event || (!event.ctrlKey && !event.metaKey))) {
@@ -938,7 +938,7 @@ export default function useAutocomplete(props) {
} else if (autoSelect && freeSolo && inputValue !== '') {
selectNewValue(event, inputValue, 'blur', 'freeSolo');
} else if (clearOnBlur) {
- resetInputValue(event, value);
+ resetInputValue(event, value, 'blur');
}
handleClose(event, 'blur');
diff --git a/packages/mui-joy/src/Autocomplete/Autocomplete.test.tsx b/packages/mui-joy/src/Autocomplete/Autocomplete.test.tsx
index a0d977163bb241..5dda4d9eb75c81 100644
--- a/packages/mui-joy/src/Autocomplete/Autocomplete.test.tsx
+++ b/packages/mui-joy/src/Autocomplete/Autocomplete.test.tsx
@@ -1843,24 +1843,31 @@ describe('Joy ', () => {
it('provides a reason on select reset', () => {
const handleInputChange = spy();
- const options = [{ name: 'foo' }];
- render(
- option.name}
- autoFocus
- />,
- );
- const textbox = screen.getByRole('combobox');
+ const options = [{ name: 'foo' }, { name: 'bar' }];
- fireEvent.keyDown(textbox, { key: 'ArrowDown' });
- fireEvent.keyDown(textbox, { key: 'Enter' });
+ function MyComponent() {
+ const [value, setValue] = React.useState(options[0]);
+ return (
+
+ option.name}
+ value={value}
+ />
+
+
+ );
+ }
+ render();
+ const resetBtn = screen.getByText('Reset');
- expect(handleInputChange.callCount).to.equal(1);
- expect(handleInputChange.args[0][1]).to.equal(options[0].name);
- expect(handleInputChange.args[0][2]).to.equal('reset');
+ fireEvent.click(resetBtn);
+
+ expect(handleInputChange.callCount).to.equal(4);
+ expect(handleInputChange.args[3][1]).to.equal(options[1].name);
+ expect(handleInputChange.args[3][2]).to.equal('reset');
});
});
diff --git a/packages/mui-joy/src/Autocomplete/Autocomplete.tsx b/packages/mui-joy/src/Autocomplete/Autocomplete.tsx
index 077782a0e69de9..043f10ee01b76f 100644
--- a/packages/mui-joy/src/Autocomplete/Autocomplete.tsx
+++ b/packages/mui-joy/src/Autocomplete/Autocomplete.tsx
@@ -975,7 +975,7 @@ Autocomplete.propTypes /* remove-proptypes */ = {
*
* @param {React.SyntheticEvent} event The event source of the callback.
* @param {string} value The new value of the text input.
- * @param {string} reason Can be: `"input"` (user input), `"reset"` (programmatic change), `"clear"`.
+ * @param {string} reason Can be: `"input"` (user input), `"reset"` (programmatic change), `"clear"`, `"blur"`, `"selectOption"`, `"removeOption"`
*/
onInputChange: PropTypes.func,
/**
diff --git a/packages/mui-material/src/Autocomplete/Autocomplete.js b/packages/mui-material/src/Autocomplete/Autocomplete.js
index bc1723d38cea36..eaa2049a16c4ed 100644
--- a/packages/mui-material/src/Autocomplete/Autocomplete.js
+++ b/packages/mui-material/src/Autocomplete/Autocomplete.js
@@ -988,7 +988,7 @@ Autocomplete.propTypes /* remove-proptypes */ = {
*
* @param {React.SyntheticEvent} event The event source of the callback.
* @param {string} value The new value of the text input.
- * @param {string} reason Can be: `"input"` (user input), `"reset"` (programmatic change), `"clear"`.
+ * @param {string} reason Can be: `"input"` (user input), `"reset"` (programmatic change), `"clear"`, `"blur"`, `"selectOption"`, `"removeOption"`
*/
onInputChange: PropTypes.func,
/**
diff --git a/packages/mui-material/src/Autocomplete/Autocomplete.test.js b/packages/mui-material/src/Autocomplete/Autocomplete.test.js
index 0315f2c653166a..b0337a910554f1 100644
--- a/packages/mui-material/src/Autocomplete/Autocomplete.test.js
+++ b/packages/mui-material/src/Autocomplete/Autocomplete.test.js
@@ -2266,24 +2266,32 @@ describe('', () => {
it('provides a reason on select reset', () => {
const handleInputChange = spy();
- const options = [{ name: 'foo' }];
- render(
- option.name}
- renderInput={(params) => }
- />,
- );
- const textbox = screen.getByRole('combobox');
+ const options = [{ name: 'foo' }, { name: 'bar' }];
- fireEvent.keyDown(textbox, { key: 'ArrowDown' });
- fireEvent.keyDown(textbox, { key: 'Enter' });
+ function MyComponent() {
+ const [value, setValue] = React.useState(options[0]);
+ return (
+
+ option.name}
+ renderInput={(params) => }
+ value={value}
+ />
+
+
+ );
+ }
+ render();
+ const resetBtn = screen.getByText('Reset');
- expect(handleInputChange.callCount).to.equal(1);
- expect(handleInputChange.args[0][1]).to.equal(options[0].name);
- expect(handleInputChange.args[0][2]).to.equal('reset');
+ fireEvent.click(resetBtn);
+
+ expect(handleInputChange.callCount).to.equal(3);
+ expect(handleInputChange.args[2][1]).to.equal(options[1].name);
+ expect(handleInputChange.args[2][2]).to.equal('reset');
});
});