reactjs - material-ui 4.3.2 上下文菜单鼠标右键点击位置
问题描述
使用带有 popper 的 material-ui 4.3.2 菜单。我需要显示动态定位的菜单。我只是从 material-ui 中修改了一个示例代码框。在此示例中,当您选择一些文本时会出现菜单。但没有定位。我猜菜单需要用一个实际的 DOM 元素来锚定。我怎样才能做到?
感谢和问候
import React from "react";
import Popper from "@material-ui/core/Popper";
import Typography from "@material-ui/core/Typography";
import Menu from "@material-ui/core/Menu";
import MenuItem from "@material-ui/core/MenuItem";
export default function FakedReferencePopper() {
const [open, setOpen] = React.useState(false);
const [anchorEl, setAnchorEl] = React.useState<null | any>(null);
const handleClose = () => {
setOpen(false);
};
const handleMouseUp = () => {
const selection = window.getSelection();
// Resets when the selection has a length of 0
if (!selection || selection.anchorOffset === selection.focusOffset) {
handleClose();
return;
}
const getBoundingClientRect = () =>
selection.getRangeAt(0).getBoundingClientRect();
setOpen(true);
setAnchorEl({
clientWidth: getBoundingClientRect().width,
clientHeight: getBoundingClientRect().height,
getBoundingClientRect
});
};
const id = open ? "faked-reference-popper" : undefined;
return (
<div onMouseLeave={handleClose}>
<Typography aria-describedby={id} onMouseUp={handleMouseUp}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ipsum
purus, bibendum sit amet vulputate eget, porta semper ligula. Donec
bibendum vulputate erat, ac fringilla mi finibus nec. Donec ac dolor sed
dolor porttitor blandit vel vel purus. Fusce vel malesuada ligula. Nam
quis vehicula ante, eu finibus est. Proin ullamcorper fermentum orci,
quis finibus massa. Nunc lobortis, massa ut rutrum ultrices, metus metus
finibus ex, sit amet facilisis neque enim sed neque. Quisque accumsan
metus vel maximus consequat. Suspendisse lacinia tellus a libero
volutpat maximus.
</Typography>
<Popper
id={id}
open={open}
anchorEl={anchorEl}
transition
placement="bottom-start"
>
{({ TransitionProps }) => (
<Menu
id="simple-menu"
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
<MenuItem onClick={handleClose}>Logout</MenuItem>
</Menu>
)}
</Popper>
</div>
);
}
解决方案
Menu
内部使用类似于但基于组件的Popover。定位机制类似于,但不一样。为了在里面做一个菜单,你应该看一下MenuList 组合演示。Popper
Modal
Popover's
Popper
Popper
Menu
您可以使用由组件MenuList
包装的而不是 using 。Paper
<Paper className={menuClasses.paper}>
<MenuList className={menuClasses.list} autoFocus>
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
<MenuItem onClick={handleClose}>Logout</MenuItem>
</MenuList>
</Paper>
两个 CSS 类 (paper
和list
) 是从Menu
.
这是完整的代码:
import React from "react";
import Popper from "@material-ui/core/Popper";
import Typography from "@material-ui/core/Typography";
import MenuList from "@material-ui/core/MenuList";
import MenuItem from "@material-ui/core/MenuItem";
import Paper from "@material-ui/core/Paper";
import { makeStyles } from "@material-ui/core/styles";
/* copied from https://github.com/mui-org/material-ui/blob/v4.3.2/packages/material-ui/src/Menu/Menu.js#L21 */
const useMenuStyles = makeStyles({
/* Styles applied to the `Paper` component. */
paper: {
// specZ: The maximum height of a simple menu should be one or more rows less than the view
// height. This ensures a tapable area outside of the simple menu with which to dismiss
// the menu.
maxHeight: "calc(100% - 96px)",
// Add iOS momentum scrolling.
WebkitOverflowScrolling: "touch"
},
/* Styles applied to the `List` component via `MenuList`. */
list: {
// We disable the focus ring for mouse, touch and keyboard users.
outline: 0
}
});
export default function FakedReferencePopper() {
const [open, setOpen] = React.useState(false);
const [anchorEl, setAnchorEl] = React.useState<null | any>(null);
const handleClose = () => {
setOpen(false);
};
const handleMouseUp = () => {
const selection = window.getSelection();
// Resets when the selection has a length of 0
if (!selection || selection.anchorOffset === selection.focusOffset) {
handleClose();
return;
}
const getBoundingClientRect = () =>
selection.getRangeAt(0).getBoundingClientRect();
setOpen(true);
setAnchorEl({
clientWidth: getBoundingClientRect().width,
clientHeight: getBoundingClientRect().height,
getBoundingClientRect
});
};
const id = open ? "faked-reference-popper" : undefined;
const menuClasses = useMenuStyles();
return (
<div onMouseLeave={handleClose}>
<Typography aria-describedby={id} onMouseUp={handleMouseUp}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ipsum
purus, bibendum sit amet vulputate eget, porta semper ligula. Donec
bibendum vulputate erat, ac fringilla mi finibus nec. Donec ac dolor sed
dolor porttitor blandit vel vel purus. Fusce vel malesuada ligula. Nam
quis vehicula ante, eu finibus est. Proin ullamcorper fermentum orci,
quis finibus massa. Nunc lobortis, massa ut rutrum ultrices, metus metus
finibus ex, sit amet facilisis neque enim sed neque. Quisque accumsan
metus vel maximus consequat. Suspendisse lacinia tellus a libero
volutpat maximus.
</Typography>
<Popper
id={id}
open={open}
anchorEl={anchorEl}
transition
placement="bottom-start"
>
{({ TransitionProps }) => (
<Paper className={menuClasses.paper}>
<MenuList className={menuClasses.list} autoFocus>
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
<MenuItem onClick={handleClose}>Logout</MenuItem>
</MenuList>
</Paper>
)}
</Popper>
</div>
);
}
推荐阅读
- python - 使用多个解释器编译 Python 应用程序
- c++ - list1.erase(hash1.find (p)); 没有匹配的函数来调用“擦除”C++
- r - 是否有 R 函数可以在 for 循环下绘制 ggplot
- kubernetes - 如何通过 Kubernetes pod 中的 sha256 哈希引用 docker 映像?
- visual-studio - VS-Code 无法捕获 firebase 身份验证异常 (Flutter)
- angular - 功能组件中实现的服务-httpclient返回可观察表时出错
- javascript - 如何在 d3 上标记力导向图?
- c# - C# - 如何在不改变 DateTime 格式的情况下改变文化
- html - CSS - 在不改变 HTML 的情况下将图像对齐到右上角和左上角
- javascript - 运行在此变量/对象上的 JQuery 包含