Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Autocomplete] API addition to support Tooltip workaround. #19247

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/pages/api/autocomplete.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ You can learn more about the difference by [reading this guide](/guides/minimizi
| <span class="prop-name">inputValue</span> | <span class="prop-type">string</span> | | The input value. |
| <span class="prop-name">ListboxComponent</span> | <span class="prop-type">elementType</span> | <span class="prop-default">'ul'</span> | The component used to render the listbox. |
| <span class="prop-name">ListboxProps</span> | <span class="prop-type">object</span> | | Props applied to the Listbox element. |
| <span class="prop-name">ListOptionComponent</span> | <span class="prop-type">elementType</span> | <span class="prop-default">'li'</span> | The component used to render the list item option.<br>This will override `renderOption` as well as `getOptionLabel`. It allows greater control of the option rendering. |
| <span class="prop-name">loading</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, the component is in a loading state. |
| <span class="prop-name">loadingText</span> | <span class="prop-type">node</span> | <span class="prop-default">'Loading…'</span> | Text to display when in a loading state.<br>For localization purposes, you can use the provided [translations](/guides/localization/). |
| <span class="prop-name">multiple</span> | <span class="prop-type">bool</span> | <span class="prop-default">false</span> | If `true`, `value` must be an array and the menu will support multiple selections. |
Expand Down
33 changes: 33 additions & 0 deletions docs/src/pages/components/autocomplete/Playground.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
/* eslint-disable no-use-before-define */
import React from 'react';
import TextField from '@material-ui/core/TextField';
import Tooltip from '@material-ui/core/Tooltip';
import Autocomplete from '@material-ui/lab/Autocomplete';
import Info from '@material-ui/icons/Info';
import Button from '@material-ui/core/Button';

export default function Playground() {
const defaultProps = {
Expand Down Expand Up @@ -126,6 +129,36 @@ export default function Playground() {
<TextField {...params} label="disablePortal" margin="normal" fullWidth />
)}
/>
<Autocomplete
{...defaultProps}
id="list-option"
debug
getOptionDisabled={({ year }) => year > 2000}
ListOptionComponent={({ title, year, ...props }) => {
if (year > 2000) {
return (
<Tooltip title={`Too Old ${year}`} placement="right-end">
<div>
<Button endIcon={<Info />} component="li" {...props} fullWidth>
{title} - {year}
</Button>
</div>
</Tooltip>
);
}

return (
<Button component="li" {...props} fullWidth>
<span>
{title} - {year}
</span>
</Button>
);
}}
renderInput={params => (
<TextField {...params} label="DisableOld w/ tooltip" margin="normal" fullWidth />
)}
/>
</div>
);
}
Expand Down
37 changes: 37 additions & 0 deletions docs/src/pages/components/autocomplete/Playground.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
/* eslint-disable no-use-before-define */
import React from 'react';
import TextField from '@material-ui/core/TextField';
import Tooltip from '@material-ui/core/Tooltip';
import Autocomplete from '@material-ui/lab/Autocomplete';
import Info from '@material-ui/icons/Info';
import Button, { ButtonProps } from '@material-ui/core/Button';

export default function Playground() {
const defaultProps = {
Expand Down Expand Up @@ -124,6 +127,40 @@ export default function Playground() {
<TextField {...params} label="disablePortal" margin="normal" fullWidth />
)}
/>
<Autocomplete
{...defaultProps}
id="list-option"
debug
getOptionDisabled={({ year }) => year > 2000}
ListOptionComponent={<T extends FilmOptionType>({
title,
year,
...props
}: T & Partial<ButtonProps>) => {
if (year > 2000) {
return (
<Tooltip title={`Too Old ${year}`} placement="right-end">
<div>
<Button endIcon={<Info />} component="li" {...props} fullWidth>
{title} - {year}
</Button>
</div>
</Tooltip>
);
}

return (
<Button component="li" {...props} fullWidth>
<span>
{title} - {year}
</span>
</Button>
);
}}
renderInput={params => (
<TextField {...params} label="DisableOld w/ tooltip" margin="normal" fullWidth />
)}
/>
</div>
);
}
Expand Down
6 changes: 6 additions & 0 deletions packages/material-ui-lab/src/Autocomplete/Autocomplete.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ export interface AutocompleteProps<T>
* Props applied to the Listbox element.
*/
ListboxProps?: object;
/**
* The component used to render the list item option.
*
* This will override `renderOption` as well as `getOptionLabel`. It allows greater control of the option rendering.
*/
ListOptionComponent?: React.ComponentType<React.HTMLAttributes<HTMLElement> & T>;
/**
* If `true`, the component is in a loading state.
*/
Expand Down
11 changes: 11 additions & 0 deletions packages/material-ui-lab/src/Autocomplete/Autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ const Autocomplete = React.forwardRef(function Autocomplete(props, ref) {
inputValue: inputValueProp,
ListboxComponent = 'ul',
ListboxProps,
ListOptionComponent = 'li',
loading = false,
loadingText = 'Loading…',
multiple = false,
Expand Down Expand Up @@ -335,6 +336,10 @@ const Autocomplete = React.forwardRef(function Autocomplete(props, ref) {
const renderListOption = (option, index) => {
const optionProps = getOptionProps({ option, index });

if (ListOptionComponent !== 'li') {
return <ListOptionComponent {...option} {...optionProps} className={classes.option} />;
}

return (
<li {...optionProps} className={classes.option}>
{renderOption(option, {
Expand Down Expand Up @@ -613,6 +618,12 @@ Autocomplete.propTypes = {
* Props applied to the Listbox element.
*/
ListboxProps: PropTypes.object,
/**
* The component used to render the list item option.
*
* This will override `renderOption` as well as `getOptionLabel`. It allows greater control of the option rendering.
*/
ListOptionComponent: PropTypes.elementType,
/**
* If `true`, the component is in a loading state.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,7 @@ export default function useAutocomplete(props) {
return {
key: index,
tabIndex: -1,
disabled,
role: 'option',
id: `${id}-option-${index}`,
onMouseOver: handleOptionMouseOver,
Expand Down