Skip to content

Commit 41a08d2

Browse files
authored
[Autocomplete] Improvement popup open logic (#19901)
1 parent e6dae39 commit 41a08d2

File tree

9 files changed

+34
-40
lines changed

9 files changed

+34
-40
lines changed

docs/pages/api/autocomplete.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ You can learn more about the difference by [reading this guide](/guides/minimizi
4040
| <span class="prop-name">disableCloseOnSelect</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the popup won't close when a value is selected. |
4141
| <span class="prop-name">disabled</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the input will be disabled. |
4242
| <span class="prop-name">disableListWrap</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the list box in the popup will not wrap focus. |
43-
| <span class="prop-name">disableOpenOnFocus</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the popup won't open on input focus. |
4443
| <span class="prop-name">disablePortal</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | Disable the portal behavior. The children stay within it's parent DOM hierarchy. |
4544
| <span class="prop-name">filterOptions</span> | <span class="prop-type">func</span> | | A filter function that determines the options that are eligible.<br><br>**Signature:**<br>`function(options: T[], state: object) => undefined`<br>*options:* The options to render.<br>*state:* The state of the component. |
4645
| <span class="prop-name">filterSelectedOptions</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, hide the selected options from the list box. |
@@ -64,6 +63,7 @@ You can learn more about the difference by [reading this guide](/guides/minimizi
6463
| <span class="prop-name">onInputChange</span> | <span class="prop-type">func</span> | | Callback fired when the input value changes.<br><br>**Signature:**<br>`function(event: object, value: string, reason: string) => void`<br>*event:* The event source of the callback.<br>*value:* The new value of the text input.<br>*reason:* Can be: `"input"` (user input), `"reset"` (programmatic change), `"clear"`. |
6564
| <span class="prop-name">onOpen</span> | <span class="prop-type">func</span> | | Callback fired when the popup requests to be opened. Use in controlled mode (see open).<br><br>**Signature:**<br>`function(event: object) => void`<br>*event:* The event source of the callback. |
6665
| <span class="prop-name">open</span> | <span class="prop-type">bool</span> | | Control the popup` open state. |
66+
| <span class="prop-name">openOnFocus</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the popup will open on input focus. |
6767
| <span class="prop-name">openText</span> | <span class="prop-type">string</span> | <span class="prop-default">'Open'</span> | Override the default text for the *open popup* icon button.<br>For localization purposes, you can use the provided [translations](/guides/localization/). |
6868
| <span class="prop-name required">options&nbsp;*</span> | <span class="prop-type">array</span> | | Array of options. |
6969
| <span class="prop-name">PaperComponent</span> | <span class="prop-type">elementType</span> | <span class="prop-default">Paper</span> | The component used to render the body of the popup. |

docs/src/pages/components/autocomplete/GoogleMaps.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ export default function GoogleMaps() {
9494
options={options}
9595
autoComplete
9696
includeInputInList
97-
disableOpenOnFocus
9897
renderInput={params => (
9998
<TextField
10099
{...params}

docs/src/pages/components/autocomplete/GoogleMaps.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ export default function GoogleMaps() {
108108
options={options}
109109
autoComplete
110110
includeInputInList
111-
disableOpenOnFocus
112111
renderInput={params => (
113112
<TextField
114113
{...params}

docs/src/pages/components/autocomplete/Playground.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,9 @@ export default function Playground() {
7878
/>
7979
<Autocomplete
8080
{...defaultProps}
81-
id="disable-open-on-focus"
82-
disableOpenOnFocus
83-
renderInput={params => <TextField {...params} label="disableOpenOnFocus" margin="normal" />}
81+
id="open-on-focus"
82+
openOnFocus
83+
renderInput={params => <TextField {...params} label="openOnFocus" margin="normal" />}
8484
/>
8585
<Autocomplete
8686
{...defaultProps}

docs/src/pages/components/autocomplete/Playground.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@ export default function Playground() {
7676
/>
7777
<Autocomplete
7878
{...defaultProps}
79-
id="disable-open-on-focus"
80-
disableOpenOnFocus
81-
renderInput={params => <TextField {...params} label="disableOpenOnFocus" margin="normal" />}
79+
id="open-on-focus"
80+
openOnFocus
81+
renderInput={params => <TextField {...params} label="openOnFocus" margin="normal" />}
8282
/>
8383
<Autocomplete
8484
{...defaultProps}

packages/material-ui-lab/src/Autocomplete/Autocomplete.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,6 @@ const Autocomplete = React.forwardRef(function Autocomplete(props, ref) {
252252
disableCloseOnSelect = false,
253253
disabled = false,
254254
disableListWrap = false,
255-
disableOpenOnFocus = false,
256255
disablePortal = false,
257256
filterOptions,
258257
filterSelectedOptions = false,
@@ -276,6 +275,7 @@ const Autocomplete = React.forwardRef(function Autocomplete(props, ref) {
276275
onInputChange,
277276
onOpen,
278277
open,
278+
openOnFocus = false,
279279
openText = 'Open',
280280
options,
281281
PaperComponent = Paper,
@@ -567,10 +567,6 @@ Autocomplete.propTypes = {
567567
* If `true`, the list box in the popup will not wrap focus.
568568
*/
569569
disableListWrap: PropTypes.bool,
570-
/**
571-
* If `true`, the popup won't open on input focus.
572-
*/
573-
disableOpenOnFocus: PropTypes.bool,
574570
/**
575571
* Disable the portal behavior.
576572
* The children stay within it's parent DOM hierarchy.
@@ -692,6 +688,10 @@ Autocomplete.propTypes = {
692688
* Control the popup` open state.
693689
*/
694690
open: PropTypes.bool,
691+
/**
692+
* If `true`, the popup will open on input focus.
693+
*/
694+
openOnFocus: PropTypes.bool,
695695
/**
696696
* Override the default text for the *open popup* icon button.
697697
*

packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ describe('<Autocomplete />', () => {
1515
const render = createClientRender();
1616
const defaultProps = {
1717
options: [],
18+
openOnFocus: true,
1819
};
1920

2021
before(() => {
@@ -465,38 +466,38 @@ describe('<Autocomplete />', () => {
465466
});
466467
});
467468

468-
describe('prop: disableOpenOnFocus', () => {
469-
it('disables open on input focus', () => {
469+
describe('prop: openOnFocus', () => {
470+
it('enables open on input focus', () => {
470471
const { getByRole } = render(
471472
<Autocomplete
472473
{...defaultProps}
473474
options={['one', 'two', 'three']}
474-
disableOpenOnFocus
475+
openOnFocus
475476
renderInput={params => <TextField {...params} autoFocus />}
476477
/>,
477478
);
478479
const textbox = getByRole('textbox');
479480
const combobox = getByRole('combobox');
480481

481-
expect(combobox).to.have.attribute('aria-expanded', 'false');
482+
expect(combobox).to.have.attribute('aria-expanded', 'true');
482483
expect(textbox).to.have.focus;
483484

484485
fireEvent.mouseDown(textbox);
485486
fireEvent.click(textbox);
486-
expect(combobox).to.have.attribute('aria-expanded', 'true');
487+
expect(combobox).to.have.attribute('aria-expanded', 'false');
487488

488489
document.activeElement.blur();
489490
expect(combobox).to.have.attribute('aria-expanded', 'false');
490491
expect(textbox).to.not.have.focus;
491492

492493
fireEvent.mouseDown(textbox);
493494
fireEvent.click(textbox);
494-
expect(combobox).to.have.attribute('aria-expanded', 'false');
495+
expect(combobox).to.have.attribute('aria-expanded', 'true');
495496
expect(textbox).to.have.focus;
496497

497498
fireEvent.mouseDown(textbox);
498499
fireEvent.click(textbox);
499-
expect(combobox).to.have.attribute('aria-expanded', 'true');
500+
expect(combobox).to.have.attribute('aria-expanded', 'false');
500501
});
501502
});
502503

packages/material-ui-lab/src/useAutocomplete/useAutocomplete.d.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,6 @@ export interface UseAutocompleteCommonProps<T> {
6969
* If `true`, the list box in the popup will not wrap focus.
7070
*/
7171
disableListWrap?: boolean;
72-
/**
73-
* If `true`, the popup won't open on input focus.
74-
*/
75-
disableOpenOnFocus?: boolean;
7672
/**
7773
* A filter function that determines the options that are eligible.
7874
*
@@ -154,6 +150,10 @@ export interface UseAutocompleteCommonProps<T> {
154150
* Control the popup` open state.
155151
*/
156152
open?: boolean;
153+
/**
154+
* If `true`, the popup will open on input focus.
155+
*/
156+
openOnFocus?: boolean;
157157
/**
158158
* Array of options.
159159
*/

packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint-disable no-constant-condition */
22
import * as React from 'react';
33
import PropTypes from 'prop-types';
4-
import { setRef, useEventCallback, useControlled, ownerDocument } from '@material-ui/core/utils';
4+
import { setRef, useEventCallback, useControlled } from '@material-ui/core/utils';
55

66
// https://stackoverflow.com/questions/990904/remove-accents-diacritics-in-a-string-in-javascript
77
// Give up on IE 11 support for this feature
@@ -86,12 +86,12 @@ export default function useAutocomplete(props) {
8686
autoSelect = false,
8787
blurOnSelect = false,
8888
clearOnEscape = false,
89+
componentName = 'useAutocomplete',
8990
debug = false,
9091
defaultValue = props.multiple ? [] : null,
9192
disableClearable = false,
9293
disableCloseOnSelect = false,
9394
disableListWrap = false,
94-
disableOpenOnFocus = false,
9595
filterOptions = defaultFilterOptions,
9696
filterSelectedOptions = false,
9797
freeSolo = false,
@@ -105,13 +105,13 @@ export default function useAutocomplete(props) {
105105
multiple = false,
106106
onChange,
107107
onClose,
108-
onOpen,
109108
onInputChange,
109+
onOpen,
110110
open: openProp,
111+
openOnFocus = false,
111112
options,
112113
selectOnFocus = !props.freeSolo,
113114
value: valueProp,
114-
componentName = 'useAutocomplete',
115115
} = props;
116116

117117
const [defaultId, setDefaultId] = React.useState();
@@ -655,7 +655,7 @@ export default function useAutocomplete(props) {
655655
const handleFocus = event => {
656656
setFocused(true);
657657

658-
if (!disableOpenOnFocus && !ignoreFocus.current) {
658+
if (openOnFocus && !ignoreFocus.current) {
659659
handleOpen(event);
660660
}
661661
};
@@ -692,10 +692,6 @@ export default function useAutocomplete(props) {
692692
}
693693

694694
if (newValue === '') {
695-
if (disableOpenOnFocus) {
696-
handleClose(event);
697-
}
698-
699695
if (!disableClearable && !multiple) {
700696
handleValue(event, null);
701697
}
@@ -783,8 +779,7 @@ export default function useAutocomplete(props) {
783779
};
784780

785781
const handleInputMouseDown = event => {
786-
const doc = ownerDocument(inputRef.current);
787-
if (inputValue === '' && (!disableOpenOnFocus || inputRef.current === doc.activeElement)) {
782+
if (inputValue === '') {
788783
handlePopupIndicator(event);
789784
}
790785
};
@@ -968,10 +963,6 @@ useAutocomplete.propTypes = {
968963
* If `true`, the list box in the popup will not wrap focus.
969964
*/
970965
disableListWrap: PropTypes.bool,
971-
/**
972-
* If `true`, the popup won't open on input focus.
973-
*/
974-
disableOpenOnFocus: PropTypes.bool,
975966
/**
976967
* A filter function that determins the options that are eligible.
977968
*
@@ -1051,6 +1042,10 @@ useAutocomplete.propTypes = {
10511042
* Control the popup` open state.
10521043
*/
10531044
open: PropTypes.bool,
1045+
/**
1046+
* If `true`, the popup will open on input focus.
1047+
*/
1048+
openOnFocus: PropTypes.bool,
10541049
/**
10551050
* Array of options.
10561051
*/

0 commit comments

Comments
 (0)