React / CSS: If content is larger than its container - html

I have a menuList, in that list are items, those text items (label) are X in length. The container is overflow wrapping the item.
container: {
minHeight: 'auto',
overflow: 'hidden',
},
label: {
whiteSpace: 'nowrap',
overflow: 'wrap',
overflowWrap: 'break-word',
'#keyframes scrollText': {
'0%': { transform: 'translate(0%, 0)' },
'100%': { transform: 'translate(-100%, 0)' },
},
'&:hover': {
animation: 'scrollText 4s linear infinite',
},
},
When the text is larger than the container i want to translate through, but only where the text is overflowing... i.e. it would look silly to rotate text on hover where there is no need to.
So how in the react application / css file do i determine if the text is overflowing / needs to transform. I can pass a var to the style sheet to apply different rules, but how to determine if the text if overflowing?
const TextMenuItem: TextMenuItemType = (props) => {
const { text, selected, onSelect } = getTextMenuItemProps(props);
const styles = useTextMenuItemStyles();
return (
<MenuItem
data-testid="text-menu-item"
sx={styles.container}
selected={selected}
onClick={onSelect}
>
<Typography sx={styles.label}>{text}</Typography>
</MenuItem>
);
};

Related

How can I make a background gradient's height extend till the end of a specific foreground element and be responsive?

I am using react and typescript to make a website. I have a custom background gradient that I want to stretch till the end of an element that is in the foreground. The background should come just below the 'some text' section.
Page Design
function LandingPage() {
return (
<div>
<Background/>
<Navbar />
<SomeText />
<Footer />
</div>
);
}
What I tried doing was to calculate the height of the 'some-text' section, and then set the height of the background to this value.
function Background() {
useEffect(() => {
const canvasElement = document.getElementById("gradient-canvas");
const gradient: any = new Gradient();
if (canvasElement) {
gradient.initGradient("#gradient-canvas");
} else {
gradient.pause();
}
}, []);
const bgHeight = document
?.getElementById("some-text-section")
?.clientHeight?.toString();
const divStyle = {
height: bgHeight?.toString() + "px",
};
return (
<canvas
id="gradient-canvas"
className="bg-gradient-to-r from-red -z-10 absolute"
style={divStyle}
/>
);
}
This is not working and the background occupies the entire screen instead of the specified style height. The 'Gradient' is imported from a javascript file.
Thanks!

Make tidier table and styling problem on jspdf

I have some div in my html page i want to make it as pdf. It's the page with multiple table, and each header / table start in the new page.
The one i'm using is jspdf, and i already achieve my goal of starting the new page based of div class. The code i try is this one :
https://plnkr.co/edit/DmNuINbijP1tu4cW
$('#printbutton').on("click", function () {
var pdf = new jsPDF('landscape');
// var pdf = new jsPDF('p','pt','a4');
var pdfName = 'test.pdf';
var imagesToResize = document.getElementsByTagName("img");
for(i=0;i<imagesToResize.length;i++){
imagesToResize[i].style.width = "100px";
imagesToResize[i].style.height = "100px";
}
var options = { pagesplit: true};
var $divs = $('.myDivClass')
//jQuery object of all the myDivClass divs
var numRecursionsNeeded = $divs.length -1; //the number of times we need to call addHtml (once per div)
var currentRecursion=0;
//Found a trick for using addHtml more than once per pdf. Call addHtml in the callback function of addHtml recursively.
function recursiveAddHtmlAndSave(currentRecursion, totalRecursions){
//Once we have done all the divs save the pdf
if(currentRecursion==totalRecursions){
pdf.save(pdfName);
}else{
currentRecursion++;
pdf.addPage();
//$('.myDivClass')[currentRecursion] selects one of the divs out of the jquery collection as a html element
//addHtml requires an html element. Not a string like fromHtml.
pdf.fromHTML($('.myDivClass')[currentRecursion], 15, 20, options, function(){
console.log(currentRecursion);
recursiveAddHtmlAndSave(currentRecursion, totalRecursions)
});
}
}
pdf.fromHTML($('.myDivClass')[currentRecursion], 15, 20, options, function(){
recursiveAddHtmlAndSave(currentRecursion, numRecursionsNeeded);
});
});
The problem is, the table is kinda messy, with teh width not fully the same as the paper and somehow it's making two row showing on one page (and there's hollow row at the start of the page)
Is there anything wrong in the code? my goal is for make the table readable and at least > 10 row showed at the same page.
Thank u in advance
The tableWidth: 'auto' should work perfectly. Anyways,
I tried the following style and properties to my table and it works fine.
pdf.autoTable(res2.columns, res2.data, {
startY: false,
theme: 'grid',
tableWidth: 'auto',
columnWidth: 'wrap',
showHeader: 'everyPage',
tableLineColor: 200,
tableLineWidth: 0,
columnStyles: {
0: {
columnWidth: 50
},
1: {
columnWidth: 50
},
2: {
columnWidth: 50
},
3: {
columnWidth: 50
},
4: {
columnWidth: 50
},
5: {
columnWidth: 'auto'
},
6: {
columnWidth: 50
},
7: {
columnWidth: 50
},
8: {
columnWidth: 'auto'
}
},
headerStyles: {
theme: 'grid'
},
styles: {
overflow: 'linebreak',
columnWidth: 'wrap',
font: 'arial',
fontSize: 10,
cellPadding: 8,
overflowColumns: 'linebreak'
},
});

Change IText color in Fabric.JS canvas (using React + typescript)

I have input with type=color outside Canvas. I have canvas with one ore more IText objects (as well as other objects). What I wanted to achieve is "on input change, change color of select text objects".
This is my input within React
<input type="color" defaultValue={defaultTextColor} ref={myRef} onChange={handleColorChange} />
I am able to change "text", but not color...
This is my Color Change event
const handleColorChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const newColor = e.currentTarget.value;
canvas.getActiveObjects().forEach((element: any) => {
if(element.type == 'i-text') {
element.color = newColor; //this doesn't work
element.text = "new"; // this works
}
});
canvas.renderAll();
}
Firstly, the color of a text is defined in the property fill
Then you need to use the set and renderAll functions.
Here is an example
var canvas = new fabric.Canvas("canvas");
var myText = new fabric.Text("Hello", {
top: 100,
left: 100,
width: 60,
height: 70,
fill: "red",
});
setTimeout(() => {
myText.set("fill", "green");
canvas.renderAll();
}, 2000);
canvas.add(myText);

click & drag to create a div with its own size

I'd like to know if you have any idea on how I could click and drag on a canva to create a div.
Like in a video-game where you drag & drop to create an area.
Is there any plugin or things that were made in order to achieve that?
Thanks for your replies.
Building on Ludwig's snippet ... this will draw some squares on the page using mousedown and mouseup event listeners :)
EDIT: Had too much fun playing with this so here is an updated version with a select box to help you draw the selection, and now working in all directions :) I'd still recommend using a library like this one (https://github.com/Simonwep/selection) though, especially if you want touchscreen support.
// declare some global variables
let showSelection = false;
let Xstart;
let Ystart;
$(document).ready(function(){
$(document).mousedown(function(event){
// set a variable that indicates the user is drawing a selection
showSelection=true;
// save the position where the mouse click started
Xstart=event.pageX;
Ystart=event.pageY;
// create the select box element and give it some starting positions
$('<div id="selection"></div>')
.css({
"left": Xstart + 'px',
"top": Ystart + 'px',
})
.appendTo(document.body);
});
$(document).mousemove(function(event){
// if we are making a selection lets keep updating our select box dimensions
if(showSelection == true) {
// horizontal selection
if (event.pageX > Xstart) {
// left to right
$('#selection').css({
"width": event.pageX-Xstart + 'px'
})
} else {
// right to left
$('#selection').css({
"left": event.pageX,
"width": Xstart-event.pageX + 'px'
})
}
// vertical selection
if (event.pageY > Ystart) {
// top to bottom
$('#selection').css({
"height": event.pageY-Ystart + 'px'
})
} else {
// bottom to top
$('#selection').css({
"top": event.pageY,
"height": Ystart-event.pageY + 'px'
})
}
}
});
$(document).mouseup(function(event){
// we can borrow the needed values from the #selection element to draw our 'area' :)
LeftVal = $("#selection").css('left')
TopVal = $("#selection").css('top')
WidthVal = $("#selection").css('width')
HeightVal = $("#selection").css('height')
// create the area element and give it the dimensions
$('<div class="area"></div>')
.css({
"left": LeftVal,
"top": TopVal,
"width": WidthVal,
"height": HeightVal
})
.appendTo(document.body);
// get rid of the selection element from the DOM
$( "#selection" ).remove();
// and set our showSelection variable back to false
showSelection=false;
});
});
.area {
position: absolute;
background-color:lightgray;
}
#selection {
position: absolute;
background-color: lightblue;
border: 2px solid blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
You could use this:
https://simonwep.github.io/selection/
In combination with something like this:
$(document).ready(function(){
$(document).click(function(event){
$('<div id="kenobi">Hello there</div>')
.css({
"left": event.pageX + 'px',
"top": event.pageY + 'px'
})
.appendTo(document.body);
});
});
body {
position: relative;
}
#kenobi {
position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

How to resize TinyMCE editor's height dynamically accordingly to text length

Here is something i'm trying, but I think the logic isn't very right.
I'm trying to use the editor's text contents and dynamically determining the editor's height.
At tinymce.component.ts
ngAfterViewInit() {
tinymce.init({
convert_urls: false,
selector: '#' + this.elementId,
// ....
// .... more properties...
// ....
setup: editor => {
editor.on('SetContent',function(e){
const content = e.content;
var newHeight = String(content.length/2);
editor.theme.resizeTo("100%",newHeight);
});
},
});
}
But somehow the height of the editor still doesn't seems about right and dynamic. Is there any better way to do this?
Try to use Autoresize Plugin
Example:
ngAfterViewInit() {
tinymce.init({
convert_urls: false,
selector: '#editor',
plugins: 'autoresize',
autoresize_min_height: 100,
autoresize_max_height: 1000,
autoresize_bottom_margin: 0
});
}