Skip to content

Commit

Permalink
[material-ui][Autocomplete] Fix the options list being added to the D…
Browse files Browse the repository at this point in the history
…OM in `freeSolo` mode even when there are no options, causing style problems (#41300)

Co-authored-by: ZeeshanTamboli <zeeshan.tamboli@gmail.com>
  • Loading branch information
2 people authored and cipherlogs committed Mar 8, 2024
1 parent 3a431c9 commit 3a9e6c9
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 64 deletions.
135 changes: 71 additions & 64 deletions packages/mui-material/src/Autocomplete/Autocomplete.js
Expand Up @@ -582,6 +582,76 @@ const Autocomplete = React.forwardRef(function Autocomplete(inProps, ref) {
const popperSlotProps = slotProps.popper ?? componentsProps.popper;
const popupIndicatorSlotProps = slotProps.popupIndicator ?? componentsProps.popupIndicator;

const renderAutocompletePopperChildren = (children) => (
<AutocompletePopper
as={PopperComponent}
disablePortal={disablePortal}
style={{ width: anchorEl ? anchorEl.clientWidth : null }}
ownerState={ownerState}
role="presentation"
anchorEl={anchorEl}
open={popupOpen}
{...popperSlotProps}
className={clsx(classes.popper, popperSlotProps?.className)}
>
<AutocompletePaper
ownerState={ownerState}
as={PaperComponent}
{...paperSlotProps}
className={clsx(classes.paper, paperSlotProps?.className)}
>
{children}
</AutocompletePaper>
</AutocompletePopper>
);

let autocompletePopper = null;
if (!loading && groupedOptions.length > 0) {
autocompletePopper = renderAutocompletePopperChildren(
<AutocompleteListbox
as={ListboxComponent}
className={classes.listbox}
ownerState={ownerState}
{...otherListboxProps}
{...ListboxProps}
ref={combinedListboxRef}
>
{groupedOptions.map((option, index) => {
if (groupBy) {
return renderGroup({
key: option.key,
group: option.group,
children: option.options.map((option2, index2) =>
renderListOption(option2, option.index + index2),
),
});
}
return renderListOption(option, index);
})}
</AutocompleteListbox>,
);
} else if (loading && groupedOptions.length === 0) {
autocompletePopper = renderAutocompletePopperChildren(
<AutocompleteLoading className={classes.loading} ownerState={ownerState}>
{loadingText}
</AutocompleteLoading>,
);
} else if (groupedOptions.length === 0 && !freeSolo && !loading) {
autocompletePopper = renderAutocompletePopperChildren(
<AutocompleteNoOptions
className={classes.noOptions}
ownerState={ownerState}
role="presentation"
onMouseDown={(event) => {
// Prevent input blur when interacting with the "no options" content
event.preventDefault();
}}
>
{noOptionsText}
</AutocompleteNoOptions>,
);
}

return (
<React.Fragment>
<AutocompleteRoot
Expand Down Expand Up @@ -646,70 +716,7 @@ const Autocomplete = React.forwardRef(function Autocomplete(inProps, ref) {
},
})}
</AutocompleteRoot>
{anchorEl ? (
<AutocompletePopper
as={PopperComponent}
disablePortal={disablePortal}
style={{
width: anchorEl ? anchorEl.clientWidth : null,
}}
ownerState={ownerState}
role="presentation"
anchorEl={anchorEl}
open={popupOpen}
{...popperSlotProps}
className={clsx(classes.popper, popperSlotProps?.className)}
>
<AutocompletePaper
ownerState={ownerState}
as={PaperComponent}
{...paperSlotProps}
className={clsx(classes.paper, paperSlotProps?.className)}
>
{loading && groupedOptions.length === 0 ? (
<AutocompleteLoading className={classes.loading} ownerState={ownerState}>
{loadingText}
</AutocompleteLoading>
) : null}
{groupedOptions.length === 0 && !freeSolo && !loading ? (
<AutocompleteNoOptions
className={classes.noOptions}
ownerState={ownerState}
role="presentation"
onMouseDown={(event) => {
// Prevent input blur when interacting with the "no options" content
event.preventDefault();
}}
>
{noOptionsText}
</AutocompleteNoOptions>
) : null}
{groupedOptions.length > 0 ? (
<AutocompleteListbox
as={ListboxComponent}
className={classes.listbox}
ownerState={ownerState}
{...otherListboxProps}
{...ListboxProps}
ref={combinedListboxRef}
>
{groupedOptions.map((option, index) => {
if (groupBy) {
return renderGroup({
key: option.key,
group: option.group,
children: option.options.map((option2, index2) =>
renderListOption(option2, option.index + index2),
),
});
}
return renderListOption(option, index);
})}
</AutocompleteListbox>
) : null}
</AutocompletePaper>
</AutocompletePopper>
) : null}
{anchorEl ? autocompletePopper : null}
</React.Fragment>
);
});
Expand Down
16 changes: 16 additions & 0 deletions packages/mui-material/src/Autocomplete/Autocomplete.test.js
Expand Up @@ -2336,6 +2336,22 @@ describe('<Autocomplete />', () => {

expect(container.querySelector(`.${classes.endAdornment}`)).to.equal(null);
});

it('should not render popper when there are no options', () => {
render(
<Autocomplete
open
freeSolo
options={[]}
renderInput={(params) => <TextField {...params} />}
slotProps={{
popper: { 'data-testid': 'popperRoot' },
}}
/>,
);
const popper = screen.queryByTestId('popperRoot');
expect(popper).to.equal(null);
});
});

describe('prop: onChange', () => {
Expand Down

0 comments on commit 3a9e6c9

Please sign in to comment.