前端项目实战叁佰贰拾柒material ui-Autocomplete-自动补全

import React from 'react';
import PropTypes from 'prop-types';
import deburr from 'lodash/deburr';
import Downshift from 'downshift';
import { withStyles } from '@material-ui/core/styles';
import TextField from '@material-ui/core/TextField';
import Popper from '@material-ui/core/Popper';
import Paper from '@material-ui/core/Paper';
import MenuItem from '@material-ui/core/MenuItem';
import Chip from '@material-ui/core/Chip';
const suggestions = [
{ label: 'Afghanistan' },
{ label: 'Aland Islands' },
{ label: 'Albania' },
{ label: 'Algeria' },
{ label: 'American Samoa' },
{ label: 'Andorra' },
{ label: 'Angola' },
{ label: 'Anguilla' },
{ label: 'Antarctica' },
{ label: 'Antigua and Barbuda' },
{ label: 'Argentina' },
{ label: 'Armenia' },
{ label: 'Aruba' },
{ label: 'Australia' },
{ label: 'Austria' },
{ label: 'Azerbaijan' },
{ label: 'Bahamas' },
{ label: 'Bahrain' },
{ label: 'Bangladesh' },
{ label: 'Barbados' },
{ label: 'Belarus' },
{ label: 'Belgium' },
{ label: 'Belize' },
{ label: 'Benin' },
{ label: 'Bermuda' },
{ label: 'Bhutan' },
{ label: 'Bolivia, Plurinational State of' },
{ label: 'Bonaire, Sint Eustatius and Saba' },
{ label: 'Bosnia and Herzegovina' },
{ label: 'Botswana' },
{ label: 'Bouvet Island' },
{ label: 'Brazil' },
{ label: 'British Indian Ocean Territory' },
{ label: 'Brunei Darussalam' },
];
function renderInput(inputProps) {
const { InputProps, classes, ref, ...other } = inputProps;
return (
<TextField
InputProps={{
inputRef: ref,
classes: {
root: classes.inputRoot,
input: classes.inputInput,
},
...InputProps,
}}
{...other}
/>
);
}
function renderSuggestion({ suggestion, index, itemProps, highlightedIndex, selectedItem }) {
const isHighlighted = highlightedIndex === index;
const isSelected = (selectedItem || '').indexOf(suggestion.label) > -1;
return (
<MenuItem
{...itemProps}
key={suggestion.label}
selected={isHighlighted}
component="div"
style={{
fontWeight: isSelected ? 500 : 400,
}}
>
{suggestion.label}
</MenuItem>
);
}
renderSuggestion.propTypes = {
highlightedIndex: PropTypes.number,
index: PropTypes.number,
itemProps: PropTypes.object,
selectedItem: PropTypes.string,
suggestion: PropTypes.shape({ label: PropTypes.string }).isRequired,
};
function getSuggestions(value) {
const inputValue = deburr(value.trim()).toLowerCase();
const inputLength = inputValue.length;
let count = 0;
return inputLength === 0
? []
: suggestions.filter(suggestion => {
const keep =
count < 5 && suggestion.label.slice(0, inputLength).toLowerCase() === inputValue;
if (keep) {
count += 1;
}
return keep;
});
}
class DownshiftMultiple extends React.Component {
state = {
inputValue: '',
selectedItem: [],
};
handleKeyDown = event => {
const { inputValue, selectedItem } = this.state;
if (selectedItem.length && !inputValue.length && event.key === 'Backspace') {
this.setState({
selectedItem: selectedItem.slice(0, selectedItem.length - 1),
});
}
};
handleInputChange = event => {
this.setState({ inputValue: event.target.value });
};
handleChange = item => {
let { selectedItem } = this.state;
if (selectedItem.indexOf(item) === -1) {
selectedItem = [...selectedItem, item];
}
this.setState({
inputValue: '',
selectedItem,
});
};
handleDelete = item => () => {
this.setState(state => {
const selectedItem = [...state.selectedItem];
selectedItem.splice(selectedItem.indexOf(item), 1);
return { selectedItem };
});
};
render() {
const { classes } = this.props;
const { inputValue, selectedItem } = this.state;
return (
<Downshift
id="downshift-multiple"
inputValue={inputValue}
onChange={this.handleChange}
selectedItem={selectedItem}
>
{({
getInputProps,
getItemProps,
isOpen,
inputValue: inputValue2,
selectedItem: selectedItem2,
highlightedIndex,
}) => (
<div className={classes.container}>
{renderInput({
fullWidth: true,
classes,
InputProps: getInputProps({
startAdornment: selectedItem.map(item => (
<Chip
key={item}
tabIndex={-1}
label={item}
className={classes.chip}
onDelete={this.handleDelete(item)}
/>
)),
onChange: this.handleInputChange,
onKeyDown: this.handleKeyDown,
placeholder: 'Select multiple countries',
}),
label: 'Label',
})}
{isOpen ? (
<Paper className={classes.paper} square>
{getSuggestions(inputValue2).map((suggestion, index) =>
renderSuggestion({
suggestion,
index,
itemProps: getItemProps({ item: suggestion.label }),
highlightedIndex,
selectedItem: selectedItem2,
}),
)}
</Paper>
) : null}
</div>
)}
</Downshift>
);
}
}
DownshiftMultiple.propTypes = {
classes: PropTypes.object.isRequired,
};
const styles = theme => ({
root: {
flexGrow: 1,
height: 250,
},
container: {
flexGrow: 1,
position: 'relative',
},
paper: {
position: 'absolute',
zIndex: 1,
marginTop: theme.spacing.unit,
left: 0,
right: 0,
},
chip: {
margin: `${theme.spacing.unit / 2}px ${theme.spacing.unit / 4}px`,
},
inputRoot: {
flexWrap: 'wrap',
},
inputInput: {
width: 'auto',
flexGrow: 1,
},
divider: {
height: theme.spacing.unit * 2,
},
});
let popperNode;
function IntegrationDownshift(props) {
const { classes } = props;
return (
<div className={classes.root}>
<Downshift id="downshift-simple">
{({
getInputProps,
getItemProps,
getMenuProps,
highlightedIndex,
inputValue,
isOpen,
selectedItem,
}) => (
<div className={classes.container}>
{renderInput({
fullWidth: true,
classes,
InputProps: getInputProps({
placeholder: 'Search a country (start with a)',
}),
})}
<div {...getMenuProps()}>
{isOpen ? (
<Paper className={classes.paper} square>
{getSuggestions(inputValue).map((suggestion, index) =>
renderSuggestion({
suggestion,
index,
itemProps: getItemProps({ item: suggestion.label }),
highlightedIndex,
selectedItem,
}),
)}
</Paper>
) : null}
</div>
</div>
)}
</Downshift>
<div className={classes.divider} />
<DownshiftMultiple classes={classes} />
<div className={classes.divider} />
<Downshift id="downshift-popper">
{({
getInputProps,
getItemProps,
getMenuProps,
highlightedIndex,
inputValue,
isOpen,
selectedItem,
}) => (
<div className={classes.container}>
{renderInput({
fullWidth: true,
classes,
InputProps: getInputProps({
placeholder: 'With Popper',
}),
ref: node => {
popperNode = node;
},
})}
<Popper open={isOpen} anchorEl={popperNode}>
<div {...(isOpen ? getMenuProps({}, { suppressRefError: true }) : {})}>
<Paper
square
style={{ marginTop: 8, width: popperNode ? popperNode.clientWidth : null }}
>
{getSuggestions(inputValue).map((suggestion, index) =>
renderSuggestion({
suggestion,
index,
itemProps: getItemProps({ item: suggestion.label }),
highlightedIndex,
selectedItem,
}),
)}
</Paper>
</div>
</Popper>
</div>
)}
</Downshift>
</div>
);
}
IntegrationDownshift.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(IntegrationDownshift);

运行结果

posted @   前端导师歌谣  阅读(30)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示