反应 Table 与 Material UI 上下文菜单
React Table with Material UI context menu
我无法让 Material UI Menu
与 React Table@v6
一起工作。
我希望能够右键单击 table(行,td)中的任意位置并显示上下文菜单。这部分正在运行。
但我也希望能够连续右键单击 table 中的其他位置,并始终在上下文菜单中显示光标位置。这是行不通的。目前,您必须单击离开才能关闭菜单,然后再次右键单击才能重新打开菜单。
在 Material UI 演示中,这工作正常:
https://material-ui.com/components/menus/#context-menu
我采用了上面的示例来使用 React Table,但它并没有像预期的那样工作。
我的示例采用:
https://codesandbox.io/s/aged-leaf-0nf6b?file=/src/index.js
任何想法如何使它像示例中那样工作?
这是因为您向 Td 添加了 onContextMenu 属性,而不是 table 容器。
将 onContext 菜单移动到容器 div,像这样:
<div onContextMenu={(e) => {
e.preventDefault();
console.log("context menu");
this.setState({
mouseX: e.clientX - 2,
mouseY: e.clientY - 4
});
}}>
它应该可以工作。
尽情享受吧!
我最终创建了一个 popper 上下文菜单来复制菜单的所有 material-ui 行为。
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";
import { ClickAwayListener, Fade } from "@material-ui/core";
/* 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 handleContextMenu = (e) => {
e.preventDefault();
const { clientX, clientY } = e;
setOpen(true);
const virtualElement = {
getBoundingClientRect: () => ({
width: 0,
height: 0,
top: clientY,
right: clientX,
bottom: clientY,
left: clientX
})
};
setAnchorEl(virtualElement);
};
const id = open ? "faked-reference-popper" : undefined;
const menuClasses = useMenuStyles();
return (
<div>
<div onContextMenu={handleContextMenu}>
<Typography aria-describedby={id}>
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. 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. 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. 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. 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. 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>
</div>
<Popper
id={id}
open={open}
anchorEl={anchorEl}
transition
placement="bottom-start"
>
{({ TransitionProps }) => (
<ClickAwayListener onClickAway={handleClose}>
<Fade {...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>
</Fade>
</ClickAwayListener>
)}
</Popper>
</div>
);
}
这里是codesandbox
我无法让 Material UI Menu
与 React Table@v6
一起工作。
我希望能够右键单击 table(行,td)中的任意位置并显示上下文菜单。这部分正在运行。
但我也希望能够连续右键单击 table 中的其他位置,并始终在上下文菜单中显示光标位置。这是行不通的。目前,您必须单击离开才能关闭菜单,然后再次右键单击才能重新打开菜单。
在 Material UI 演示中,这工作正常:
https://material-ui.com/components/menus/#context-menu
我采用了上面的示例来使用 React Table,但它并没有像预期的那样工作。
我的示例采用:
https://codesandbox.io/s/aged-leaf-0nf6b?file=/src/index.js
任何想法如何使它像示例中那样工作?
这是因为您向 Td 添加了 onContextMenu 属性,而不是 table 容器。
将 onContext 菜单移动到容器 div,像这样:
<div onContextMenu={(e) => {
e.preventDefault();
console.log("context menu");
this.setState({
mouseX: e.clientX - 2,
mouseY: e.clientY - 4
});
}}>
它应该可以工作。
尽情享受吧!
我最终创建了一个 popper 上下文菜单来复制菜单的所有 material-ui 行为。
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";
import { ClickAwayListener, Fade } from "@material-ui/core";
/* 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 handleContextMenu = (e) => {
e.preventDefault();
const { clientX, clientY } = e;
setOpen(true);
const virtualElement = {
getBoundingClientRect: () => ({
width: 0,
height: 0,
top: clientY,
right: clientX,
bottom: clientY,
left: clientX
})
};
setAnchorEl(virtualElement);
};
const id = open ? "faked-reference-popper" : undefined;
const menuClasses = useMenuStyles();
return (
<div>
<div onContextMenu={handleContextMenu}>
<Typography aria-describedby={id}>
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. 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. 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. 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. 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. 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>
</div>
<Popper
id={id}
open={open}
anchorEl={anchorEl}
transition
placement="bottom-start"
>
{({ TransitionProps }) => (
<ClickAwayListener onClickAway={handleClose}>
<Fade {...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>
</Fade>
</ClickAwayListener>
)}
</Popper>
</div>
);
}
这里是codesandbox