I have a React-mui draggable dialog component on which I am using resizable box.
const styles = theme => ({
resizable: {
position: "relative",
"& .react-resizable-handle": {
position: "absolute",
width: 20,
height: 20,
bottom: 0,
right: 0,
background:
"url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2IDYiIHN0eWxlPSJiYWNrZ3JvdW5kLWNvbG9yOiNmZmZmZmYwMCIgeD0iMHB4IiB5PSIwcHgiIHdpZHRoPSI2cHgiIGhlaWdodD0iNnB4Ij48ZyBvcGFjaXR5PSIwLjMwMiI+PHBhdGggZD0iTSA2IDYgTCAwIDYgTCAwIDQuMiBMIDQgNC4yIEwgNC4yIDQuMiBMIDQuMiAwIEwgNiAwIEwgNiA2IEwgNiA2IFoiIGZpbGw9IiMwMDAwMDAiLz48L2c+PC9zdmc+')",
"background-position": "bottom right",
padding: "0 3px 3px 0",
"background-repeat": "no-repeat",
"background-origin": "content-box",
"box-sizing": "border-box",
cursor: "se-resize"
}
}
});
return (
<StyledDialog
open={open}
classes={{root: classes.dialog, paper: classes.paper}}
PaperComponent={PaperComponent}
aria-labelledby="draggable-dialog"
>
<ResizableBox
height={520}
width={370}
minConstraints={[300, 500]}
maxConstraints={[Infinity, Infinity]}
className={classes.resizable}
>
<DialogContent classes={{root: classes.dialogContent}} id="draggable-dialog">
<IconButton className={classes.clearIcon} aria-label="Clear" onClick={onClose}>
<ClearIcon/>
</IconButton>
<iframe
src={hjelpemiddel.url}
title={hjelpemiddel.navn}
width="100%"
height="500px">
</iframe>
</DialogContent>
</ResizableBox>
</StyledDialog>
);
}
I would like to use my own icon instead of the default image used for the ResizableBox. How can I set the icon that I am importing from material icons as background of resizable?
import ZoomOutMapIcon from '#material-ui/icons/ZoomOutMap';
Material-UI is using SVG for the ZoomOutMapIcon. What I would do is convert that SVG to base64 then apply that to the background-url
This is its base64 output: PHN2ZyBjbGFzcz0iTXVpU3ZnSWNvbi1yb290IiBmb2N1c2FibGU9ImZhbHNlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgYXJpYS1oaWRkZW49InRydWUiID48cGF0aCBkPSJNMTUgM2wyLjMgMi4zLTIuODkgMi44NyAxLjQyIDEuNDJMMTguNyA2LjcgMjEgOVYzaC02ek0zIDlsMi4zLTIuMyAyLjg3IDIuODkgMS40Mi0xLjQyTDYuNyA1LjMgOSAzSDN2NnptNiAxMmwtMi4zLTIuMyAyLjg5LTIuODctMS40Mi0xLjQyTDUuMyAxNy4zIDMgMTV2Nmg2em0xMi02bC0yLjMgMi4zLTIuODctMi44OS0xLjQyIDEuNDIgMi44OSAyLjg3TDE1IDIxaDZ2LTZ6Ij48L3BhdGg+PC9zdmc+
and I usually use makeStyles for overriding CSS when using Material UI
const useStyles = makeStyles({
resizable: {
position: "relative",
"& .react-resizable-handle": {
position: "absolute",
width: 20,
height: 20,
bottom: 0,
right: 0,
background:
"url('data:image/svg+xml;base64,PHN2ZyBjbGFzcz0iTXVpU3ZnSWNvbi1yb290IiBmb2N1c2FibGU9ImZhbHNlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgYXJpYS1oaWRkZW49InRydWUiID48cGF0aCBkPSJNMTUgM2wyLjMgMi4zLTIuODkgMi44NyAxLjQyIDEuNDJMMTguNyA2LjcgMjEgOVYzaC02ek0zIDlsMi4zLTIuMyAyLjg3IDIuODkgMS40Mi0xLjQyTDYuNyA1LjMgOSAzSDN2NnptNiAxMmwtMi4zLTIuMyAyLjg5LTIuODctMS40Mi0xLjQyTDUuMyAxNy4zIDMgMTV2Nmg2em0xMi02bC0yLjMgMi4zLTIuODctMi44OS0xLjQyIDEuNDIgMi44OSAyLjg3TDE1IDIxaDZ2LTZ6Ij48L3BhdGg+PC9zdmc+')",
"background-position": "bottom right",
padding: "0 3px 3px 0",
"background-repeat": "no-repeat",
"background-origin": "content-box",
"box-sizing": "border-box",
cursor: "se-resize"
}
}
});
<ResizableBox
className={classes.resizable}
>
Related
I'm using material ui icons, is there any way to add plus to icons ?
This is my icon :
import ApartmentIcon from '#mui/icons-material/Apartment';
and that icon should have plus to it like here:
I have been trying to find a way but did not find anything,
these are icons i want plus to them:' CameraAlt,
Apartment,
Web,
Assessment,
Description,', any suggestions ?
Using sx property here is what you need.
<Box sx={{ background: "black" }}>
<Box sx={{ position: "relative", display: "inline", color: "white" }}>
<CameraAltOutlinedIcon sx={{ fontSize: 40 }} />
<AddIcon
sx={{
position: "absolute",
right: "-5px",
bottom: "2px",
color: "black",
fontSize: 22,
strokeWidth: "6",
stroke: "black"
}}
/>
<AddIcon
sx={{
position: "absolute",
right: "-6px",
bottom: "1px",
color: "white",
fontSize: 22
}}
/>
</Box>
</Box>
I had to use two 'plus' svg AddIcons one inside the other with some stroke to the one on the back to act like a frame for the one on the front and have a better looking result.
The only thing you need to do is adjust the left/right attributes depending the main icon you are using and the colors to match your background.
Here also is a working codepen
i think this is the icon you are looking for
import AddAPhotoIcon from '#mui/icons-material/AddAPhoto';
Here is a solution using styled components:
import * as React from "react";
import { Box } from "#material-ui/core/";
import { CameraAlt } from "#material-ui/icons";
import AddIcon from "#material-ui/icons/Add";
import styled from "styled-components";
const IconContainer = styled(Box)`
background-color: red;
position: absolute;
`;
const PlusIconBack = styled(AddIcon)`
position: absolute;
right: -8px;
bottom: -1px;
color: black;
font-size: 21px;
stroke-width: 3;
stroke: black;
`;
const PlusIconFront = styled(AddIcon)`
position: absolute;
right: -7px;
bottom: 0;
color: white;
font-size: 19px;
`;
function Demo() {
return (
<IconContainer>
<CameraAlt />
<PlusIconBack />
<PlusIconFront />
</IconContainer>
);
}
export default Demo;
The point of it, is to use a container giving it position relative, add your main icon, then add your plus icons with position absolute and place them where you want using left/right top/bottom.
Sandbox: sandbox
I have a div like this in react js which renders multiple divs and overflows :
<div
style={{
display: "flex",
padding: "1em 0.7em",
overflowX: "auto",
width: "100%",
direction: "rtl",
background: "#ef394e"
}}
>
{Array.from(Array(10).keys()).map((each, index) => (
<div
key={index}
className="swiper-slide"
style={{
background: "white",
borderRadius: "10px",
width: "270px",
margin: "0 .4em"
}}
>
<div style={{ padding: "2em 6em" }}>Hello</div>
</div>
))}
</div>
But for some reason the padding is applied to the containers right side but not the left side here are some pictures :
How can I apply padding to the array item's container div for both the left and right sides ?
It's because your div width bigger then the body,
and as result your body also have scroll.
Try add boxSizing: border-box to your parent component, and the body scroll will disappear.
const App = () => {
return (
<div
style={{
display: "flex",
padding: "1em 0em",
overflowX: "auto",
width: "100%",
direction: "rtl",
background: "#ef394e",
boxSizing: "border-box" // <--- this line
}}
>
...
</div>
);
};
It's the padding on the div. It's to little and the margin too.
import React from "react";
const App = () => {
return (
<div
style={{
display: "flex",
padding: "1em 0em",
overflowX: "auto",
width: "100%",
direction: "rtl",
background: "#ef394e"
}}
>
{Array.from(Array(10).keys()).map((each, index) => (
<div
key={index}
className="swiper-slide"
style={{
background: "white",
borderRadius: "10px",
width: "270px",
margin: "0 .4em"
}}
>
<div style={{ padding: "2em 6em" }}>Hello</div>
</div>
))}
</div>
);
};
export default App;
import React from 'react';
import { makeStyles, Typography, Grid } from '#material-ui/core';
import Card from '#material-ui/core/Card';
const styles = makeStyles((theme) => ({
card: {
background: 'black',
width: '140px',
margin: '0px 10px',
},
root: {
width: '142px',
height: '196px',
overflow: 'hidden',
position: 'relative',
transition: 'all 0.5s ease-out',
},
image: {
position: 'absolute',
width: '100%',
height: '100%',
objectFit: 'cover',
transition: 'all 0.5s ease-out',
zIndex: 10,
'&:hover': {
zIndex: -1,
},
},
textPositioning: {
width: '140px',
height: '40px',
overflow: 'hidden',
marginTop: '10px',
},
text: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
fontFamily: 'Comfortaa',
},
genresContainer: {
backgroundColor: theme.palette.primary.main,
width: '100%',
height: '100%',
position: 'relative',
transition: 'all 0.5s ease-out',
zIndex: 2,
},
genreList: {
width: '100%',
height: '100%',
},
}));
interface AnimeData {
image_url: string;
title: string;
genres: Array<any>;
}
interface DisplayAnimeCardProps {
data: AnimeData;
}
const DisplayAnimeCard: React.FC<DisplayAnimeCardProps> = (
props: DisplayAnimeCardProps
) => {
const classes = styles();
const { data } = props;
console.log(typeof data, data.genres);
return (
<Card className={classes.card}>
<div className={classes.root}>
<img
className={classes.image}
alt='anime'
src={data.image_url}
/>
<div className={classes.genresContainer}>
<Grid
className={classes.genreList}
container
direction='column'
justifyContent='center'
alignItems='center'
>
{data.genres.map((genre) => (
<Typography
className={classes.text}
variant='body1'
>
{genre.name}
</Typography>
))}
</Grid>
</div>
</div>
<div className={classes.textPositioning}>
<Typography className={classes.text} variant='body1'>
{data.title}
</Typography>
</div>
</Card>
);
};
export default DisplayAnimeCard;
The Hovering effect show a div a top the image with some text. It works fine when I simply hover over the Card and do not move the cursor again. But If I move my cursor(during hovering) a top the card, the hover effect breaks and causes flickering between the textPositioningdiv and the image. I want to stop this flickering and just show the textPositioning div whenever I hover over the card and move my cursor
I am working on a very simple website consisting of an image, with some text overlaid on top of it. In some cases, the image may be bigger than the screen, and then the user can scroll. However, I would like the overlaid text to remain on-screen, centered, even when the user scrolls. How can I do this?
Here is a basic idea of my code at the moment:
const styles = theme => ({
main_screen: {
position: "relative",
textAlight: "center",
color: "white",
height: '100%',
width: '100%',
margin: "0",
padding: "0"
},
caption: {
color: "yellow",
margin: "1em",
},
overlayText: {
position: "absolute",
width: "100%",
top: "5%",
alignItems:"center"
},
main_image: {
maxwidth: "100%",
maxHeight: "100%",
objectFit:"cover",
display: "block",
margin: "0",
padding: "0",
overflow: "scroll"
},
})
class ExampleSite extends React.Component {
....
render(){
return(
<div id="main-screen" className={classes.main_screen}>
<img id='target-image' onLoad={this.readDims} className={classes.main_image} src={pano_1} alt={""}/>
<div className={classes.overlayText}>
<Typography className={classes.caption} align="center" > {this.state.instructionText} </Typography>
</div>
</div>
)
}
}
position: fixed; on the text object is what you want. MDN - CSS Position
I have this object, with the styles I want for the modal:
const customStyles = {
content: {
top: '35%',
left: '50%',
right: 'auto',
bottom: 'auto',
marginRight: '-50%',
width: '60%',
transform: 'translate(-40%, -10%)',
},
};
Then I pass that styles to the modal like this:
<Modal
isOpen={this.state.modalIsOpen}
onRequestClose={this.closeModal}
style={customStyles}
>
And it works fine but I want to pass a class, not create a customStyle object inside the component.
I try something like this, first creating the modal class:
.modal {
top: '35%';
left: '50%';
right: 'auto';
bottom: 'auto';
marginRight: '-50%';
width: '60%';
transform: 'translate(-40%, -10%)';
}
and then:
<Modal
isOpen={this.state.modalIsOpen}
onRequestClose={this.closeModal}
className="modal"
>
But it didn't work. What am I doing wrong?
It should be portalClassName:
<Modal
isOpen={this.state.modalIsOpen}
onRequestClose={this.closeModal}
portalClassName="modal"
>
I think there might be a billion ways to do this, here is just one that uses CSS Modules. If you put your styles into a separate .css.js file you can import it in your module:
/// modal.css.js ///
export default {
modal: {
top: '35%',
left: '50%',
right: 'auto',
bottom: 'auto',
marginRight: '-50%',
width: '60%',
transform: 'translate(-40%, -10%)'
},
greenText: {
color: 'rgb(0,255,100)'
},
style3: {
marginRight: '-25%'
}
}
You can then assign your styles by accessing them as you would with any object and apply them to your component on the style attribute
import styles from './modal.css.js'
...
<Modal
isOpen={this.state.modalIsOpen}
onRequestClose={this.closeModal}
style={styles.modal}
>
if you want to apply multiple styles to your component you give the style attribute an array. This would allow you to apply styles from multiple imported style objects.
<Modal
isOpen={this.state.modalIsOpen}
onRequestClose={this.closeModal}
style={[styles.modal, styles.greenText]}
>
<ReactModal id={this.state.dialogId}
isOpen={showDialog}
onRequestClose={this.onCancel.bind(this)}
className={`shadow p-4`}
style={{
overlay: {
position: 'fixed',
zIndex: 1020,
top: 0,
left: 0,
width: '100vw',
height: '100vh',
background: 'rgba(255, 255, 255, 0.75)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
content: {
background: 'white',
width: '45rem',
maxWidth: 'calc(100vw - 2rem)',
maxHeight: 'calc(100vh - 2rem)',
overflowY: 'auto',
position: 'relative',
border: '1px solid #ccc',
borderRadius: '0.3rem',
}}}
appElement={document.getElementById('root') as HTMLElement}> ... </ReactModal>
i tried this way and it works fine with me i added a simple class to the react modal tag
<Modal
size="sm"
aria-labelledby="contained-modal-title-vcenter"
className='modalStyle'
centered
show={prescriptionPreview}
onHide={() => setPrescriptionPreview(false)}
>
then i went to app.css and selected like this way
.modalStyle .modal-dialog
and style it whatever you want
Just in case you also need to handle different env file depending on your environment, e.g: .env.prod and .env.dev, then follow this:
Make sure that .env.prod and .env.dev are in the root directory of your project.
Load Environment Variables in next.config.js like that:
const dotenv = require('dotenv');
const environment = process.env.NODE_ENV || 'development';
if (environment === 'development') {
dotenv.config({ path: '.env.dev' });
} else {
dotenv.config({ path: '.env.prod' });
}
module.exports = withBundleAnalyzer({
// ...
env: {
VALUE_1: process.env.VALUE_1,
VALUE_2: process.env.VALUE_2,
VALUE_3: process.env.VALUE_3,
},
});