Material-UI context menu that doesn't block new context menu events? - material-ui

The Material-UI docs give an example of how to build a context menu. But when this menu is open, it seems like all the elements of the page stop receiving onContextMenu events. So if you right-click outside the menu while it's open, the application won't be able to identify what was clicked on and won't be able to reposition the menu. The only option is to close the menu first (for instance by left-clicking outside the menu), then right click on the desired element.
How can I create a menu such that, when it's open, I can still identify what elements of the page have been right-clicked on and reposition the menu to the location of the new click?
(see this Codesandox that is a slight modification from the example in the docs, where a second div has been added that you can right-click on)

Found the solution! The trick is to close the context menu on the mouse down event of the parent div, and also setting an exit transitionDuration of 0 on the menu. For example, see this demo.tsx (also on Codesandox):
import React from "react";
import Menu from "#material-ui/core/Menu";
import MenuItem from "#material-ui/core/MenuItem";
import Typography from "#material-ui/core/Typography";
const initialState = {
mouseX: null,
mouseY: null
};
export default function ContextMenu() {
const [state, setState] = React.useState<{
mouseX: null | number;
mouseY: null | number;
}>(initialState);
const handleClick = (
divName: string,
event: React.MouseEvent<HTMLDivElement>
) => {
console.log(divName);
event.preventDefault();
setState({
mouseX: event.clientX - 2,
mouseY: event.clientY - 4
});
};
const handleClose = () => {
setState(initialState);
};
return (
<div
onContextMenu={e => e.preventDefault()}
onMouseDownCapture={e => {
if (e.button === 2) handleClose();
}}
>
<Menu
keepMounted
open={state.mouseY !== null}
onClose={handleClose}
anchorReference="anchorPosition"
anchorPosition={
state.mouseY !== null && state.mouseX !== null
? { top: state.mouseY, left: state.mouseX }
: undefined
}
transitionDuration={0}
>
<MenuItem onClick={handleClose}>Copy</MenuItem>
<MenuItem onClick={handleClose}>Print</MenuItem>
<MenuItem onClick={handleClose}>Highlight</MenuItem>
<MenuItem onClick={handleClose}>Email</MenuItem>
</Menu>
<div
onContextMenu={e => handleClick("div1", e)}
style={{ cursor: "context-menu" }}
>
<Typography>
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>
-----
<div
onContextMenu={e => handleClick("div2", e)}
style={{ cursor: "context-menu" }}
>
<Typography>
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>
</div>
);
}

Related

Inconsistent font size in mobile browsers for material-ui components

I have a nextjs app (https://codesandbox.io/s/kind-ellis-bkobb?file=/pages/list2.js) using material-ui without any theme with a page:
import ListItem from "#material-ui/core/ListItem";
import ListItemText from "#material-ui/core/ListItemText";
import List from "#material-ui/core/List";
export default function List2Page() {
return (
<>
<p>Paragraph text</p>
<List>
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit</div>
<ListItem>
Donec pretium elit id augue vulputate dignissim non eget
</ListItem>
<ListItemText>
Vestibulum scelerisque facilisis libero quis congue nulla
</ListItemText>
<ListItem>
<ListItemText primary="Proin ornare sapien libero, eget commodo sem laoreet sit"></ListItemText>
</ListItem>
</List>
</>
);
}
Here is a screenshot of this page made on android Chrome browser in landscape mode (looks ok):
And in portrait mode (looks crazy):
Why are the two elements much smaller than other elements in portrait mode and how to make font size consistent?
The solution is to add "max-height: 999999px" to any parent element, as described here: https://stackoverflow.com/a/60044980/523972

html2canvas generates a blank image

after some googling around, I haven't been able to wrap my head around why this script isn't working. The goal is to have a button that, when clicked, will generate an image download of my div with the id save.
Currently, clicking the download button DOES generate an image download, but the image is always blank/empty. Why is it not grabbing my div successfully?
Here's my html:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="styles.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.js"></script>
</head>
<body>
<div class="save" id='save'>
<div class="center">
<h1 class="alignleft">This is a heading</h1>
<p class="alignright">#asdf</p>
<div style="clear: both;"></div>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras tempus placerat fringilla. Sed rutrum tortor et lobortis egestas. Morbi cursus, ex nec pharetra fringilla, nisl libero convallis leo, vitae volutpat arcu enim in mi. Suspendisse a enim molestie justo laoreet fermentum at ac neque. Donec vel cursus orci, vel blandit est. Suspendisse fringilla vel nulla quis mollis. Mauris orci urna, dignissim id erat a, posuere congue turpis. Integer blandit sed felis ut vehicula. Phasellus et dui quis orci dictum vulputate. Pellentesque pretium eget diam et euismod. Nunc rutrum vehicula nisl, at sagittis enim sollicitudin quis.<br>
Mauris et sagittis eros. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In hac habitasse platea dictumst. Nam ante ante, faucibus nec dapibus a, tristique ac turpis. Maecenas at ipsum a mauris luctus blandit. Nam convallis lacus dui, pulvinar interdum arcu malesuada id. Integer convallis semper purus in sodales. Mauris ac laoreet augue.</p>
<div class="nav">
next ->
</div>
<a id="btn-Convert-Html2Image" href="#">Download</a>
<br />
<div id="previewImage" style="display: none;">
</div>
</div>
</div>
<script>
$(document).ready(function () {
var element = $("#save"); // global variable
var getCanvas; // global variable
html2canvas(element, {
onrendered: function (canvas) {
$("#previewImage").append(canvas);
getCanvas = canvas;
}
});
$("#btn-Convert-Html2Image").on('click', function () {
var imgageData = getCanvas.toDataURL("image/png");
// Now browser starts downloading it instead of just showing it
var newData = imgageData.replace(/^data:image\/png/, "data:application/octet-stream");
$("#btn-Convert-Html2Image").attr("download", "poem.png").attr("href", newData);
});
});
</script>
</body>
</html>
Try adding a reference to JQuery UI as well:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
It works fine for me per this fiddle:
https://jsfiddle.net/n5gcbstu/
Only difference in the fiddle and your code seems to be that I have JQueryUI referenced as well.
Code worked without the Jquery UI reference, it was my CSS centering the div that was messing it up. Replaced with this CSS and life is good:
.center {
margin: auto;
height: 500px;
width: 500px;
}
body {
background-color: lightgrey;
height: 100%;
display: grid;
}

Change background image in responsive emails

I have ae email in which I have a cell with a background image. I need to change this image src for mobiles. Is it possible to do this ? I see a lot of examples using the <img> tag but in my case this is a background image.
I have decided to cut the background image in Outlook (bulletproof bg wasn't enough) so basically my code looks like this
<!--[if lt mso 9]> <!-->
<td
background="https://assets.myjobglasses.com/email/campaigns/aladdin/red-carpet.png" bgcolor="#ffffff"
valign="top" align="center"
style="background-repeat: no-repeat;"
height="<%= red_carpet_height %>"
class="red-carpet-bulletproof-background"
>
<!--<![endif]-->
<!--[if gte mso 9]>
<td
valign="top" align="center"
height="<%= red_carpet_height %>"
class="red-carpet-bulletproof-background"
>
Instead I'd like to use this image on mobile. How can I do this ? (I can choose to duplicate the code and add some visibility classes, but if my emails are too long Gmail will choose to cut the visible part so I'd like to avoid such drastic measures)
You will need to target that specific class that contains the image and change it on mobile.
#media only screen and (max-width:480px) {
.red-carpet-bulletproof-background{background-image:url();width:300px; height:225px; background-size:100% auto;}
}
Here is a working example:
#media only screen and (max-width:480px) {
.table{width:300px !important;}
.red-carpet-bulletproof-background{background-image:url('https://assets.myjobglasses.com/email/campaigns/aladdin/red-carpet-mobile.png') !important;width:300px; height:225px; background-size:100% auto;}
}
<table width="600" cellpadding="0" cellspacing="0" border="0" class="table">
<tr>
<td
background="https://assets.myjobglasses.com/email/campaigns/aladdin/red-carpet.png" bgcolor="#ffffff"
valign="top" align="center"
style="background-repeat: no-repeat;"
height="<%= red_carpet_height %>"
class="red-carpet-bulletproof-background"
>
Content goes here. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris pellentesque lectus at risus pellentesque pulvinar. Vestibulum vitae bibendum lorem, eu fermentum erat. Fusce viverra ante vel leo placerat euismod. Quisque aliquam lectus nec justo tincidunt iaculis. Pellentesque ultrices suscipit diam, a dapibus nulla. Aenean semper est at dapibus lacinia. Etiam semper lacinia dictum. Donec non fermentum eros. <br><br>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris pellentesque lectus at risus pellentesque pulvinar. Vestibulum vitae bibendum lorem, eu fermentum erat. Fusce viverra ante vel leo placerat euismod.
<br><br>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris pellentesque lectus at risus pellentesque pulvinar. Vestibulum vitae bibendum lorem, eu fermentum erat. Fusce viverra ante vel leo placerat euismod.
<br><br>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris pellentesque lectus at risus pellentesque pulvinar. Vestibulum vitae bibendum lorem, eu fermentum erat. Fusce viverra ante vel leo placerat euismod.
</td>
</tr>
</table>
Let me know if this works for you.

Ionic header bar hides content

I am new to Ionic and of course searched for a solution on SO and Google but no success.
I try to build a first simple app using following code:
<body>
<ion-header-bar class="bar bar-header bar-dark">
<h1 class="title">Settings</h1>
</ion-header-bar>
<ion-content class="has-header">
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</ion-content>
</body>
What happens is that the header overlaps the content and hides the first lines of text.
What am I doing wrong?
You need to include the has-subheader class to your ion-content directive.
Here is a working codepen of their nightly build. It seems more like a problem with the ionic version you are running.
<ion-header-bar> and the classes you provide are correct, try updating ionic and see if that fixes it.
Use <ion-view> instead of <body> tags.
There you can also set the title, like:
<ion-view view-title="Settings">
<!-- Your content, etc goes here -->
</ion-view>

FancyBox not scaling to the height of inline content

I've got a link which triggers a hidden div which is supposed to show in a fancybox. The content in each hidden div is of different heights. Right now, when the fancybox opens, the div content extends beyond the borders of the fancybox. It's not resizing for some reason.
Here is a sample of the html:
<div class="faqWrapper">
<a class="faqLink" href="#faqContent1132116">How Do I Join?</a>
<div id="faqContent1132116" class="faqBox">
<div class="fancybox_wrapper_content"><p>How Do I Join?</p>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi commodo, ipsum
sed pharetra gravida, orci magna rhoncus neque, id pulvinar odio lorem non turpis.
Nullam sit amet enim. Suspendisse id velit vitae ligula volutpat condimentum. Aliquam
erat volutpat. Sed quis velit. Nulla facilisi. Nulla libero. Vivamus pharetra posuere
sapien. Nam consectetuer. Sed aliquam, nunc eget euismod ullamcorper, lectus nunc
ullamcorper orci, fermentum bibendum enim nibh eget ipsum. Donec porttitor ligula eu
dolor. Maecenas vitae nulla consequat libero cursus venenatis. Nam magna enim,
accumsan eu, blandit sed, blandit a, eros.<br></p>
</div>
</div>
Here is the trigger code for the fancybox:
$("a.faqLink").fancybox({
type : 'inline',
autoScale : false,
autoDimensions : true
Any idea how to get the box to resize. I've tried the resize function but it breaks the code. I must be implementing wrong. Here's what I've tried.
$("a.faqLink").fancybox.resize();
Is the content hidden when you open Fancybox? If so, FancyBox can't tell the size of a hidden element.
In your code above you are not closing the first div.
having a similar issue where fancybox width defaults to 300 NOT 600 on Vimeo inline.
// slideshow function
$('a.slide').fancybox({
'autoWidth' : false,
'autoResize' : false,
'width' : 600
});
<img src="/site/assets/files/1025/eyho.jpg" title="video">
<div style="display:none">
<div id="video-1">
<iframe width="500" frameborder="0" allowfullscreen="" mozallowfullscreen="" webkitallowfullscreen="" src="http://player.vimeo.com/video/61541969?color=ff0179"></iframe>
</div>
</div>