Skip to content

Commit

Permalink
[Autocomplete] Prevent shrink animation in uncontrolled Autocomplete …
Browse files Browse the repository at this point in the history
…when default value is set (#44873)
  • Loading branch information
ZeeshanTamboli authored Jan 21, 2025
1 parent 819e662 commit 8a4eaf6
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 10 deletions.
26 changes: 16 additions & 10 deletions packages/mui-material/src/useAutocomplete/useAutocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ const defaultIsActiveElementInListbox = (listboxRef) =>

const MULTIPLE_DEFAULT_VALUE = [];

function getInputValue(value, multiple, getOptionLabel) {
if (multiple || value == null) {
return '';
}
const optionLabel = getOptionLabel(value);
return typeof optionLabel === 'string' ? optionLabel : '';
}

function useAutocomplete(props) {
const {
// eslint-disable-next-line @typescript-eslint/naming-convention
Expand Down Expand Up @@ -137,14 +145,20 @@ function useAutocomplete(props) {
const defaultHighlighted = autoHighlight ? 0 : -1;
const highlightedIndexRef = React.useRef(defaultHighlighted);

// Calculate the initial inputValue on mount only.
// Using useRef since defaultValue doesn't need to update inputValue dynamically.
const initialInputValue = React.useRef(
getInputValue(defaultValue, multiple, getOptionLabel),
).current;

const [value, setValueState] = useControlled({
controlled: valueProp,
default: defaultValue,
name: componentName,
});
const [inputValue, setInputValueState] = useControlled({
controlled: inputValueProp,
default: '',
default: initialInputValue,
name: componentName,
state: 'inputValue',
});
Expand All @@ -159,15 +173,7 @@ function useAutocomplete(props) {
if (!isOptionSelected && !clearOnBlur) {
return;
}
let newInputValue;
if (multiple) {
newInputValue = '';
} else if (newValue == null) {
newInputValue = '';
} else {
const optionLabel = getOptionLabel(newValue);
newInputValue = typeof optionLabel === 'string' ? optionLabel : '';
}
const newInputValue = getInputValue(newValue, multiple, getOptionLabel);

if (inputValue === newInputValue) {
return;
Expand Down
20 changes: 20 additions & 0 deletions packages/mui-material/src/useAutocomplete/useAutocomplete.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -395,4 +395,24 @@ describe('useAutocomplete', () => {
fireEvent.click(button);
}).not.to.throw();
});

describe('prop: defaultValue', () => {
it('should not trigger onInputChange when defaultValue is provided', () => {
const onInputChange = spy();
const defaultValue = 'foo';

function Test() {
const { getInputProps } = useAutocomplete({
defaultValue,
onInputChange,
options: ['foo', 'bar'],
});

return <input {...getInputProps()} />;
}

render(<Test />);
expect(onInputChange.callCount).to.equal(0);
});
});
});

0 comments on commit 8a4eaf6

Please sign in to comment.