Skip to content

Commit

Permalink
[Autocomplete] Improvement popup open logic (mui#19901)
Browse files Browse the repository at this point in the history
  • Loading branch information
haseebdaone authored and EsoterikStare committed Mar 30, 2020
1 parent 405d235 commit f67ffec
Show file tree
Hide file tree
Showing 9 changed files with 34 additions and 40 deletions.
2 changes: 1 addition & 1 deletion docs/pages/api/autocomplete.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ You can learn more about the difference by [reading this guide](/guides/minimizi
| <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. |
| <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. |
| <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. |
| <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. |
| <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. |
| <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. |
| <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. |
Expand All @@ -64,6 +63,7 @@ You can learn more about the difference by [reading this guide](/guides/minimizi
| <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"`. |
| <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. |
| <span class="prop-name">open</span> | <span class="prop-type">bool</span> | | Control the popup` open state. |
| <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. |
| <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/). |
| <span class="prop-name required">options&nbsp;*</span> | <span class="prop-type">array</span> | | Array of options. |
| <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. |
Expand Down
1 change: 0 additions & 1 deletion docs/src/pages/components/autocomplete/GoogleMaps.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ export default function GoogleMaps() {
options={options}
autoComplete
includeInputInList
disableOpenOnFocus
renderInput={params => (
<TextField
{...params}
Expand Down
1 change: 0 additions & 1 deletion docs/src/pages/components/autocomplete/GoogleMaps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ export default function GoogleMaps() {
options={options}
autoComplete
includeInputInList
disableOpenOnFocus
renderInput={params => (
<TextField
{...params}
Expand Down
6 changes: 3 additions & 3 deletions docs/src/pages/components/autocomplete/Playground.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ export default function Playground() {
/>
<Autocomplete
{...defaultProps}
id="disable-open-on-focus"
disableOpenOnFocus
renderInput={params => <TextField {...params} label="disableOpenOnFocus" margin="normal" />}
id="open-on-focus"
openOnFocus
renderInput={params => <TextField {...params} label="openOnFocus" margin="normal" />}
/>
<Autocomplete
{...defaultProps}
Expand Down
6 changes: 3 additions & 3 deletions docs/src/pages/components/autocomplete/Playground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ export default function Playground() {
/>
<Autocomplete
{...defaultProps}
id="disable-open-on-focus"
disableOpenOnFocus
renderInput={params => <TextField {...params} label="disableOpenOnFocus" margin="normal" />}
id="open-on-focus"
openOnFocus
renderInput={params => <TextField {...params} label="openOnFocus" margin="normal" />}
/>
<Autocomplete
{...defaultProps}
Expand Down
10 changes: 5 additions & 5 deletions packages/material-ui-lab/src/Autocomplete/Autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,6 @@ const Autocomplete = React.forwardRef(function Autocomplete(props, ref) {
disableCloseOnSelect = false,
disabled = false,
disableListWrap = false,
disableOpenOnFocus = false,
disablePortal = false,
filterOptions,
filterSelectedOptions = false,
Expand All @@ -276,6 +275,7 @@ const Autocomplete = React.forwardRef(function Autocomplete(props, ref) {
onInputChange,
onOpen,
open,
openOnFocus = false,
openText = 'Open',
options,
PaperComponent = Paper,
Expand Down Expand Up @@ -567,10 +567,6 @@ Autocomplete.propTypes = {
* If `true`, the list box in the popup will not wrap focus.
*/
disableListWrap: PropTypes.bool,
/**
* If `true`, the popup won't open on input focus.
*/
disableOpenOnFocus: PropTypes.bool,
/**
* Disable the portal behavior.
* The children stay within it's parent DOM hierarchy.
Expand Down Expand Up @@ -692,6 +688,10 @@ Autocomplete.propTypes = {
* Control the popup` open state.
*/
open: PropTypes.bool,
/**
* If `true`, the popup will open on input focus.
*/
openOnFocus: PropTypes.bool,
/**
* Override the default text for the *open popup* icon button.
*
Expand Down
15 changes: 8 additions & 7 deletions packages/material-ui-lab/src/Autocomplete/Autocomplete.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ describe('<Autocomplete />', () => {
const render = createClientRender();
const defaultProps = {
options: [],
openOnFocus: true,
};

before(() => {
Expand Down Expand Up @@ -465,38 +466,38 @@ describe('<Autocomplete />', () => {
});
});

describe('prop: disableOpenOnFocus', () => {
it('disables open on input focus', () => {
describe('prop: openOnFocus', () => {
it('enables open on input focus', () => {
const { getByRole } = render(
<Autocomplete
{...defaultProps}
options={['one', 'two', 'three']}
disableOpenOnFocus
openOnFocus
renderInput={params => <TextField {...params} autoFocus />}
/>,
);
const textbox = getByRole('textbox');
const combobox = getByRole('combobox');

expect(combobox).to.have.attribute('aria-expanded', 'false');
expect(combobox).to.have.attribute('aria-expanded', 'true');
expect(textbox).to.have.focus;

fireEvent.mouseDown(textbox);
fireEvent.click(textbox);
expect(combobox).to.have.attribute('aria-expanded', 'true');
expect(combobox).to.have.attribute('aria-expanded', 'false');

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

fireEvent.mouseDown(textbox);
fireEvent.click(textbox);
expect(combobox).to.have.attribute('aria-expanded', 'false');
expect(combobox).to.have.attribute('aria-expanded', 'true');
expect(textbox).to.have.focus;

fireEvent.mouseDown(textbox);
fireEvent.click(textbox);
expect(combobox).to.have.attribute('aria-expanded', 'true');
expect(combobox).to.have.attribute('aria-expanded', 'false');
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,6 @@ export interface UseAutocompleteCommonProps<T> {
* If `true`, the list box in the popup will not wrap focus.
*/
disableListWrap?: boolean;
/**
* If `true`, the popup won't open on input focus.
*/
disableOpenOnFocus?: boolean;
/**
* A filter function that determines the options that are eligible.
*
Expand Down Expand Up @@ -154,6 +150,10 @@ export interface UseAutocompleteCommonProps<T> {
* Control the popup` open state.
*/
open?: boolean;
/**
* If `true`, the popup will open on input focus.
*/
openOnFocus?: boolean;
/**
* Array of options.
*/
Expand Down
25 changes: 10 additions & 15 deletions packages/material-ui-lab/src/useAutocomplete/useAutocomplete.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable no-constant-condition */
import * as React from 'react';
import PropTypes from 'prop-types';
import { setRef, useEventCallback, useControlled, ownerDocument } from '@material-ui/core/utils';
import { setRef, useEventCallback, useControlled } from '@material-ui/core/utils';

// https://stackoverflow.com/questions/990904/remove-accents-diacritics-in-a-string-in-javascript
// Give up on IE 11 support for this feature
Expand Down Expand Up @@ -86,12 +86,12 @@ export default function useAutocomplete(props) {
autoSelect = false,
blurOnSelect = false,
clearOnEscape = false,
componentName = 'useAutocomplete',
debug = false,
defaultValue = props.multiple ? [] : null,
disableClearable = false,
disableCloseOnSelect = false,
disableListWrap = false,
disableOpenOnFocus = false,
filterOptions = defaultFilterOptions,
filterSelectedOptions = false,
freeSolo = false,
Expand All @@ -105,13 +105,13 @@ export default function useAutocomplete(props) {
multiple = false,
onChange,
onClose,
onOpen,
onInputChange,
onOpen,
open: openProp,
openOnFocus = false,
options,
selectOnFocus = !props.freeSolo,
value: valueProp,
componentName = 'useAutocomplete',
} = props;

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

if (!disableOpenOnFocus && !ignoreFocus.current) {
if (openOnFocus && !ignoreFocus.current) {
handleOpen(event);
}
};
Expand Down Expand Up @@ -692,10 +692,6 @@ export default function useAutocomplete(props) {
}

if (newValue === '') {
if (disableOpenOnFocus) {
handleClose(event);
}

if (!disableClearable && !multiple) {
handleValue(event, null);
}
Expand Down Expand Up @@ -783,8 +779,7 @@ export default function useAutocomplete(props) {
};

const handleInputMouseDown = event => {
const doc = ownerDocument(inputRef.current);
if (inputValue === '' && (!disableOpenOnFocus || inputRef.current === doc.activeElement)) {
if (inputValue === '') {
handlePopupIndicator(event);
}
};
Expand Down Expand Up @@ -968,10 +963,6 @@ useAutocomplete.propTypes = {
* If `true`, the list box in the popup will not wrap focus.
*/
disableListWrap: PropTypes.bool,
/**
* If `true`, the popup won't open on input focus.
*/
disableOpenOnFocus: PropTypes.bool,
/**
* A filter function that determins the options that are eligible.
*
Expand Down Expand Up @@ -1051,6 +1042,10 @@ useAutocomplete.propTypes = {
* Control the popup` open state.
*/
open: PropTypes.bool,
/**
* If `true`, the popup will open on input focus.
*/
openOnFocus: PropTypes.bool,
/**
* Array of options.
*/
Expand Down

0 comments on commit f67ffec

Please sign in to comment.