Reactjs 在文本字段中键入时显示关联菜单
我正在尝试实现一个上下文菜单,当用户使用。其思想是根据文本字段中当前键入的单词在上下文菜单中显示建议。因此,上下文菜单显示在插入符号输入旁边,不应干扰用户继续键入 但问题是,当显示菜单时,焦点从文本字段中取出,用户无法继续键入,直到菜单关闭 是否有一种方法可以允许显示菜单,同时仍将焦点放在文本字段上,从而允许用户继续键入Reactjs 在文本字段中键入时显示关联菜单,reactjs,material-ui,Reactjs,Material Ui,我正在尝试实现一个上下文菜单,当用户使用。其思想是根据文本字段中当前键入的单词在上下文菜单中显示建议。因此,上下文菜单显示在插入符号输入旁边,不应干扰用户继续键入 但问题是,当显示菜单时,焦点从文本字段中取出,用户无法继续键入,直到菜单关闭 是否有一种方法可以允许显示菜单,同时仍将焦点放在文本字段上,从而允许用户继续键入 <Menu keepMounted open={contextMenuOpen} onClose={handleClose
<Menu
keepMounted
open={contextMenuOpen}
onClose={handleClose}
anchorReference="anchorPosition"
anchorPosition={
{ top: caretPositionY, left: caretPositionX}
}
>
<MenuItem onClick={handleClose}>Suggestion1</MenuItem>
<MenuItem onClick={handleClose}>Suggestion2</MenuItem>
<MenuItem onClick={handleClose}>Suggestion3</MenuItem>
<MenuItem onClick={handleClose}>Suggestion4</MenuItem>
</Menu>
建议1
建议2
建议3
建议4
如果您无法使用材质UI菜单
,以下是备选方案:-
(使用简单的Demo.js
元素和包ul
):-类名
import React,{useState,useffect}来自“React”;
从“类名”中导入类名;
从“@material ui/core/styles”导入{makeStyles}”;
从“@material ui/core”导入{Button,TextField}”;
导入“/style.css”;
常量演示=()=>{
const classes=useStyles();
const[search,setSearch]=useState(“”);
常量[openMenu,setOpenMenu]=使用状态(false);
常量[menuItems,setMenuItems]=useState([
{id:1,名称:“Profile”},
{id:2,名称:“我的帐户”},
{id:3,名称:“注销”}
]);
常量[menuItemsFiltered,setMenuItemsFiltered]=useState(menuItems);
常量handleClose=()=>{
设置菜单(假);
};
const handleSearch=值=>{
如果(值==“”){
设置菜单(假);
setMenuItemsFiltered(menuItems);
}否则{
设置菜单(真);
setMenuItemsFiltered(()=>
menuItems.filter(
item=>item.name.toLowerCase().indexOf(value.toLowerCase())>-1
)
);
}
};
useffect(()=>{
handleSearch(搜索);
},[搜索];
返回(
setSearch(e.target.value)}
/>
setOpenMenu(!openMenu)}
>
打开菜单
{menuItemsFiltered.map(项=>(
- handleClose()}
>
{item.name}
))}
);
};
导出默认演示;
const useStyles=makeStyles(主题=>({
根目录:{
显示:“flex”
},
菜单:{
listStyle:“无”,
填充:“0.5雷姆”,
背景色:主题。调色板。灰色[100],
“&li:不是(:最后一个孩子)”:{
marginBottom:“1rem”
}
},
梅努希德:{
显示:“无”
},
菜单项:{
“&:悬停”:{
光标:“指针”,
颜色:theme.palete.primary.main
}
}
}));
您可以在沙盒中看到正在运行的演示
import React, { useState, useEffect } from "react";
import classNames from "classnames";
import { makeStyles } from "@material-ui/core/styles";
import { Button, TextField } from "@material-ui/core";
import "./style.css";
const Demo = () => {
const classes = useStyles();
const [search, setSearch] = useState("");
const [openMenu, setOpenMenu] = useState(false);
const [menuItems, setMenuItems] = useState([
{ id: 1, name: "Profile" },
{ id: 2, name: "My Account" },
{ id: 3, name: "Logout" }
]);
const [menuItemsFiltered, setMenuItemsFiltered] = useState(menuItems);
const handleClose = () => {
setOpenMenu(false);
};
const handleSearch = value => {
if (value === "") {
setOpenMenu(false);
setMenuItemsFiltered(menuItems);
} else {
setOpenMenu(true);
setMenuItemsFiltered(() =>
menuItems.filter(
item => item.name.toLowerCase().indexOf(value.toLowerCase()) > -1
)
);
}
};
useEffect(() => {
handleSearch(search);
}, [search]);
return (
<div className={classes.root}>
<TextField
type="search"
value={search}
onChange={e => setSearch(e.target.value)}
/>
<div>
<Button
aria-controls="simple-menu"
aria-haspopup="true"
onClick={() => setOpenMenu(!openMenu)}
>
Open Menu
</Button>
<ul
className={
openMenu ? classes.menu : classNames(classes.menu, classes.menuHide)
}
>
{menuItemsFiltered.map(item => (
<li
key={item.id}
className={classes.menuItem}
onClick={() => handleClose()}
>
{item.name}
</li>
))}
</ul>
</div>
</div>
);
};
export default Demo;
const useStyles = makeStyles(theme => ({
root: {
display: "flex"
},
menu: {
listStyle: "none",
padding: "0.5rem",
backgroundColor: theme.palette.grey[100],
"& li:not(:last-child)": {
marginBottom: "1rem"
}
},
menuHide: {
display: "none"
},
menuItem: {
"&:hover": {
cursor: "pointer",
color: theme.palette.primary.main
}
}
}));