I am having trouble getting the Material UI Menu to work with React Table#v6.
I want to be able to right-click anywhere in the table (row, td) and show a context menu. This part is working.
But I also want to be able to continuously right-click other locations in the table and always show the context menu the cursor location. This is not working. Currently, you have to click-away to close the menu and then right-click again to re-open the menu.
In the Material UI demo this is working fine:
https://material-ui.com/components/menus/#context-menu
I adopted the example above to work with React Table, but it's not quite working as expected.
My example adoption:
https://codesandbox.io/s/aged-leaf-0nf6b?file=/src/index.js
Any Ideas how to get this to work as in the example?
This is because you added onContextMenu props to Td, not the table container.
Move onContext Menu to container div, like this:
<div onContextMenu={(e) => {
e.preventDefault();
console.log("context menu");
this.setState({
mouseX: e.clientX - 2,
mouseY: e.clientY - 4
});
}}>
And it should work.
Enjoy!
I ended up creating a popper context menu to replicate all the material-ui behavior for menus.
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>
);
}
Here is codesandbox
https://codesandbox.io/s/popper-context-menu-t1u6r
Related
i am trying to build cv maker web application.and i need to convert componet to pdf file.
here my code
const handelDownload = () => {
html2canvas(componentRef.current).then(function (canvas) {
const divImage = canvas.toDataURL("image/png");
const pdf = new jsPDF();
pdf.addImage(divImage, "PNG", 0, 0);
pdf.save("download.pdf");
});
};
return (
<>
<h1>hello world</h1>
<div ref={componentRef}>
<h1 className="text-4xl bg-red-500">My Component</h1>
<p className="text-lg">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vel
ipsum et velit posuere tempus sed ac ex. Vestibulum ante ipsum primis
in faucibus orci luctus et ultrices posuere cubilia curae; Integer
eget augue faucibus, placerat leo vitae, dignissim mi. Fusce id nibh
id risus congue consequat ac ut libero. Duis ut tincidunt turpis. Nam
scelerisque tortor in risus interdum consequat. Ut vel lectus sem.
Nulla hendrerit erat vel massa finibus, eget laoreet tellus ultrices.
Integer rhoncus lectus quis libero imperdiet, et viverra turpis
fermentum. Donec ullamcorper nisl eget felis dictum, at suscipit dolor
viverra. Etiam ullamcorper sem sit amet ante bibendum iaculis.
</p>
</div>
</>
problem is qulity of pdf is wrost and elements are not in the same position in the PDF as they are in the original component.
i also try reactpdf.
I wish I was able to recreate this small menu from the material ui website in my app :
By now I have a component with a list and links :
import { Link, List, ListItem } from '#material-ui/core';
const burgerRecipe = [
{
id: 0,
name: "bread",
quantity: 2
},
{
id: 1,
name: "steak",
quantity: 1
},
{
id: 2,
name: "cheddar",
quantity: 1
},
{
id: 3,
name: "pickles",
quantity: 2
}
]
/**
* MenuInteractiveColumn :
* #description
*/
const MenuInteractiveColumn = props => {
return (
<>
<List>
{burgerRecipe.map(value => {
return (
<ListItem key={value.id}>
<Link href={`/reservations#${value.name}`}
underline="none"
onClick={() => {
console.info("bip bop");
}}
>
{value.name}
</Link>
</ListItem>
)
})}
</List>
<List>
{burgerRecipe.map(value => {
return (
<div id={value.name}>
{value.name} -------------
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam in lectus sit amet est mollis pharetra nec non augue. Phasellus eleifend ac erat non aliquam. Donec varius vel orci vel tempus. Suspendisse non dolor est. Duis at consequat diam. Etiam at bibendum orci, at tincidunt nulla. Integer vel quam non urna malesuada auctor. Quisque feugiat ligula dolor, vitae consequat magna mattis nec. Nulla massa nisl, fringilla et felis nec, lobortis placerat lectus. Praesent eget vehicula nulla. Cras lobortis metus sed pellentesque maximus. Proin nisi diam, euismod sit amet lacinia in, fringilla eget dolor. Nunc molestie magna id varius facilisis. Pellentesque sit amet posuere justo. Nullam faucibus lectus at mauris efficitur, sit amet hendrerit massa auctor.
Fusce a dapibus nibh, at dignissim nulla. Donec tempus ut justo eu volutpat. Pellentesque eget diam ipsum. Nullam vehicula lorem et rhoncus mattis. Duis arcu libero, consectetur a sodales eget, malesuada at purus. Integer a mattis eros. Etiam sagittis, lectus cursus commodo molestie, ante justo maximus diam, pellentesque hendrerit nibh est sed ex. Cras pharetra interdum sagittis. Nulla tincidunt scelerisque purus, eget varius ipsum venenatis porta. Etiam fermentum, diam vitae tempor tempus, quam diam iaculis eros, id fringilla sapien felis ut metus. Quisque et mi condimentum, semper justo ultrices, euismod metus. Interdum et malesuada fames ac ante ipsum primis in faucibus. Cras posuere et nisl ac ultrices. Donec eu dolor tincidunt, maximus augue quis, suscipit metus. Praesent convallis ut metus vel eleifend.
Sed eu dignissim urna. Quisque sit amet risus sollicitudin, lobortis purus nec, consequat justo. Vestibulum non mauris faucibus, maximus nulla eu, convallis augue. Aenean vel libero nec felis ullamcorper auctor. Mauris efficitur sed tellus eget semper. Etiam blandit et lectus ut lacinia. Suspendisse faucibus enim convallis, placerat eros vitae, ullamcorper mauris. Quisque quis quam vestibulum, mollis justo ac, pellentesque nisl. Nunc iaculis tortor sit amet ex tristique convallis sit amet sit amet augue. Nulla aliquam sit amet enim eget placerat. Ut quis ex tincidunt, dignissim ligula non, euismod mauris. Sed euismod faucibus massa, vel aliquam elit euismod in.
Aliquam id sapien nibh. Sed eu tellus eros. Cras interdum magna quis arcu dignissim, eget posuere felis dictum. Donec dictum euismod lectus, nec ornare erat suscipit at. Fusce mi nibh, ullamcorper porttitor orci sit amet, placerat ultrices eros. Nam rutrum mauris sit amet magna iaculis aliquet. Sed venenatis urna in metus volutpat, id sagittis nulla tempor. Curabitur odio metus, porttitor sit amet urna ac, posuere rhoncus neque. Morbi tortor libero, dapibus vitae finibus rutrum, placerat quis leo. Vivamus nunc leo, vehicula vulputate cursus ac, placerat vitae ex. Nullam eu nisl purus. Curabitur vitae egestas turpis, quis volutpat felis. Quisque sit amet purus facilisis, posuere ante in, laoreet nisl. Pellentesque ornare dolor nec lectus porttitor, et venenatis orci auctor. Vestibulum ultrices id enim vel interdum. Ut non tortor placerat, consectetur sem at, viverra elit.
Etiam non tellus in nisl facilisis pharetra. Vivamus porttitor justo at fringilla euismod. Nunc neque lacus, scelerisque sed pellentesque quis, ullamcorper nec leo. Nullam sed dolor metus. Vivamus aliquet at erat eu blandit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque mollis neque at eros feugiat, nec lacinia lorem finibus. In semper vel lacus eu porttitor. Curabitur mollis lectus ac purus pretium, non facilisis odio viverra. Aliquam erat volutpat. Pellentesque ultrices nulla et nisi placerat, non tempus nisl elementum. Sed dui dui, vestibulum posuere enim vitae, sollicitudin rhoncus metus.
</div>
)
})}
</List>
</>
)
};
export default MenuInteractiveColumn;
And I would like it to go to some div in my page like it does on the material ui website
EDIT : It kinda works now but it hides the top of the lorem Ipsum under my navbar
While i do not have the time to make an example based on your code here are some resources which might be interesting to you:
material-ui - AppTableOfContents
react-scrollspy - see example on how this can be used with tabs
react-scroll-agent
Antd anchor
see also material-ui: issue 16359 for more information
I have the following code to add to a variable every time the mouse has reached the end of the page :
const [number, setNum] = React.useState(5);
const addUp = () => {
setNum(number + 1);
}
const handleScroll = cb => {
if (window.innerHeight + window.scrollY >= document.body.offsetHeight) cb();
};
React.useEffect(() => {
window.addEventListener("scroll", handleScroll(addUp));
}, [number]);
return (
<div className="App">
{console.log(number)}
sadly the code does not add to its existing value or with a little change to useEffect dependencies I end up in an infinite loop.
How can I add to my state by scrolling to the end of the page ?
the full code can be found at https://codesandbox.io/s/laughing-tree-pw6co
You can try something like the following. Don't add any dependencies for the useEffect() that creates the window event-listener. Anytime your component re-renders that will create a brand-new event listener on top of the one that already exists. You only want that useEffect() to execute once.
To assist you, you can add a second useState() to keep track of the scroll position. true if they are at the bottom, false otherwise. We'll call this endReached.
Then use a second useEffect() to verify the value of endReached, if true then increase number.
See working sandbox: http://codesandbox.io/s/youthful-hofstadter-h362t
App.js
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
const myref = React.useRef(0);
const [number, setNum] = React.useState(5);
const [endReached, setEndReached] = React.useState(false);
const handleScroll = () => {
if (
window.scrollY + window.innerHeight >= document.body.offsetHeight &&
!endReached
) {
setEndReached(true);
} else {
setEndReached(false);
}
};
React.useEffect(() => {
if (endReached) {
setNum(number + 1);
}
}, [endReached]);
React.useEffect(() => {
window.addEventListener("scroll", () => handleScroll());
}, []);
return (
<div className="App">
<h1>number is {number}</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tristique
consequat imperdiet. Nulla vitae dolor in nisl fermentum egestas ut ac
nulla. Quisque aliquam libero sit amet neque ullamcorper molestie.
Phasellus massa ligula, rhoncus non consectetur sit amet, consequat eu
leo. Proin nec gravida sapien. Proin convallis malesuada est, nec
tincidunt massa. Quisque sit amet augue molestie, convallis purus quis,
porttitor quam. Duis iaculis ultrices ipsum a egestas. Duis pulvinar
urna sit amet egestas rutrum. Praesent sed consectetur felis. Nulla
massa libero, iaculis tempor porta ornare, hendrerit eu est. Praesent
tempor consequat nibh, in aliquam quam laoreet ut. Sed laoreet congue
urna id feugiat. Etiam egestas gravida dictum. Vestibulum nec sapien
turpis. In hac habitasse platea dictumst. Vestibulum odio turpis,
tincidunt sit amet ultricies at, interdum quis massa. Ut vestibulum quis
tortor viverra consequat. Phasellus ligula erat, efficitur non justo in,
pretium tempor nibh. Aliquam fringilla fermentum consectetur. Nunc
cursus convallis posuere. Pellentesque ac quam a mauris tempus dapibus
ut at quam. In vel tellus in eros elementum bibendum at mollis metus.
Fusce venenatis aliquet magna, non viverra odio dapibus vitae. Etiam
orci metus, consectetur ut enim at, tristique pellentesque augue. Sed eu
cursus metus. Maecenas imperdiet ultricies hendrerit. Maecenas porta
varius ipsum, a convallis magna pharetra ac. Sed sit amet dolor quis mi
luctus auctor. Mauris finibus, purus in dictum suscipit, nibh lacus
consequat orci, id ornare tellus lectus non urna. Nulla est neque,
sagittis at lacinia id, pulvinar quis sem. In hac habitasse platea
dictumst. Aenean vel porta ante, quis pulvinar velit. Etiam at mollis
sapien. Ut tristique pretium nisi, in tincidunt nisl pulvinar nec. Ut ac
ultricies erat, nec maximus neque. Vestibulum ante ipsum primis in
faucibus orci luctus et ultrices posuere cubilia Curae; Integer
vehicula, magna non aliquam sagittis, ex sapien interdum magna, vitae
gravida arcu nisi varius nunc. Nunc molestie ante a imperdiet finibus.
Aenean pellentesque rhoncus tincidunt. Suspendisse potenti. Nullam
dictum nibh vel sem ultrices, at lacinia sem cursus. Etiam dignissim
porta nulla a commodo. Nulla facilisi. Quisque non erat lectus.
Suspendisse a justo mi. Suspendisse ut sem et magna vulputate facilisis.
Morbi rutrum ornare tristique. Nam facilisis et urna ut fringilla. Etiam
pretium augue eu lorem mattis vestibulum. Nulla iaculis lorem ultricies
justo varius, id aliquet arcu fringilla. Nunc vehicula velit id nisi
imperdiet, ut lobortis arcu dignissim. Donec et orci iaculis, aliquet mi
quis, pellentesque elit. Aenean ipsum libero, molestie vitae libero eu,
mattis porta nulla. Duis vitae ornare turpis, eget lobortis enim. Cras
ut sagittis ipsum. Aenean luctus lacinia leo, a luctus augue pharetra
nec. Nulla blandit in est id cursus.
</p>
<button onClick={() => setNum(myref.current.value)}>Change</button>
<br />
<input ref={myref} />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
I'm need justify a text and my code isn't work correctly.
import React from "react"
import { ScrollView, StyleSheet, View, WebView } from "react-native"
export default class App extends React.Component {
render() {
return (
<ScrollView style={styles.container}>
<WebView
source={{
html:
"<style>p{text-align:justify}</style>" +
"<p>" +
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus commodo tortor ut ipsum pharetra sodales. Praesent sed diam non lacus convallis dapibus. Sed vulputate erat risus, ac hendrerit eros egestas id. Etiam pellentesque auctor ipsum, non cursus nisi gravida sed. Ut eget pretium risus. Curabitur a lectus odio. Etiam felis urna, pharetra ut odio in, tristique suscipit tortor. Cras vitae risus odio. Etiam a leo elit. Duis molestie fermentum mi vitae pretium. Morbi luctus semper quam, et suscipit nisi convallis dictum. Fusce sit amet est dapibus, interdum ante non, lacinia metus. Donec at nulla non ante consectetur vulputate. Cras tristique porttitor ligula quis posuere. Integer nec laoreet felis, at tempor leo. Ut et convallis quam." +
"</p>"
}}
/>
</ScrollView>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
margin: 20
}
})
The text isn't showed in the screen.
I'm try execute the code in a Android device.
Try removing the scrollView component, and putting the style in the Webview.
Here is an example:
https://snack.expo.io/SJQ5Mf9ym
I am trying to implement dynamic tabs using Kendo UI Tabstrip in Angular JS. How to indicate the active state? For example I want the second tab to be active by default.
Markup with directives
<div data-kendo-tab-strip="" data-k-animation="false" k-data-source="panes" k-data-text-field="'title'" k-data-content-field="'content'" ></div>
//Tabs controller
ngUI.controller('nguiTabsController', function($scope) {
$scope.panes = {
data : [ {title:"First", content:"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vitae dolor sed lacus interdum rutrum. Mauris mauris dui, rhoncus ut magna vitae, faucibus elementum lectus. "},
{title:"Second", content:"Sed auctor, turpis at scelerisque dapibus, dolor quam laoreet nibh, in pulvinar augue est a est. Nulla eu nulla nunc. Donec eu augue placerat, tincidunt diam vel, fringilla velit. Ut convallis faucibus neque. Nullam pellentesque, nisi quis facilisis tincidunt."},
{title:"Third", content:"Maecenas posuere tellus vel elit cursus porttitor. Proin auctor lorem risus, sit amet blandit ligula ultricies sit amet. Pellentesque eget velit ut libero faucibus lobortis."},
{title:"Fourth", content:"Suspendisse sodales consequat aliquet. Mauris ultricies nisl a metus convallis, at iaculis elit scelerisque. Nullam dignissim convallis lectus eu malesuada. Etiam libero mi, suscipit at auctor id, porta eu justo. Nullam a ipsum dictum, gravida erat vitae, sollicitudin justo."},
{title:"Fifth", content:"Phasellus suscipit ipsum molestie augue interdum sodales. Sed sit amet eros in odio viverra aliquam vitae nec odio. Nulla condimentum eleifend tortor, non malesuada purus placerat non. Mauris porttitor odio tortor."}]
};
});
Change the div to define the widget reference;
<div data-kendo-tab-strip="tabStrip"...
In the controller, create the tabStrip scope variable and place a watch on it. When it is set, select the desired tab by number.
ngUI.controller('nguiTabsController', function($scope) {
$scope.tabStrip = null;
$scope.$watch('tabStrip', function() {
$scope.tabStrip.select(0);
});
$scope.panes...
}