I have an side-drawer/modal that will slide into view when clicking on an image of my application. I'm trying to blur all the contents behind the side-drawer when it comes into view, I realized I might need another component like Backdrop that takes the whole content of the page and somehow blur the whole div when the side-drawer is displayed.
I tried using backdrop-filter but that's not supported in Chrome yet. Are there any alternatives? Or am I going to need a transparent "dummy" image to blur?
My component is just this:
import React from 'react';
import styles from './styles.module.css';
const backdrop = props => (
<div className={styles.backdrop} onClick={props.click}></div>
)
export default backdrop;
I tried this:
.backdrop {
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
filter: blur(2px);
z-index: 300;
}
And mounting it on my app as so:
class App extends Component {
componentDidMount() {
const { loadUserAction } = this.props;
const {
auth: { token }
} = readLocalStorage();
if (token) loadUserAction(token);
}
render() {
return (
<BrowserRouter>
<Route exact path={signInPath} component={Login} />
<Backdrop />
<SideDrawer />
<ProtectedRoute exact path={feedPath} component={MovieFeed} />
</BrowserRouter>
);
}
}
Related
I'm trying to make different icons in the footer, with different brands. I want them to change color when I'm hovering over them. I've created a CSS class with the hover pseudo-class, but I want to make a sort of parameter in my JSX file which tells the class that a certain color should be applied to a certain icon
This Is my CSS class:
.icon-background {
color: rgb(49, 45, 44, 0.8);
}
.icon-background:focus,
.icon-background:hover {
background-color: var(--color);
transition-duration: 0.2s;
padding: 2.5px;
}
An easy way to accomplish this would be through utility css classes. For instance, you could insert an icon in the jsx file like this:
<div className="blue default_icon">ICON</div>
With corresponding css:
.blue:hover,
.blue:focus {
background-color: #0000ff;
}
.default_icon {
color: rgb(49, 45, 44, 0.8);
}
.default_icon:hover {
transition-duration: 0.2s;
padding: 2.5px;
}
A better way you could do this is with React state. Basically, create an icon component and pass a color as a prop. This will be much less css and will be more scalable:
import { useState } from 'react';
const Icon = (props) => {
const hoverColor = props.hoverColor;
const [isHover, setIsHover] = useState(false);
const handleMouseEnter = () => {
setIsHover(true);
};
const handleMouseLeave = () => {
setIsHover(false);
};
const hoverStyle = {
backgroundColor: isHover ? hoverColor : "defaultColor",
};
return (
<div
style={hoverStyle}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
ICON
</div>
);
};
export default Icon;
You can then use the icon anywhere in your project like so:
<Icon hoverColor={"#0000ff"} /> // This would turn blue on hover
Currently I'm trying to replicate this hover effect of this website on my map component: http://www.francoisrisoud.com/projects where basically when you hover over a dot, it brings up a full screen image and when you click on it, it'll take you to a particular page. Currently this is my React and CSS code:
export default function Map({posts}) {
const [viewport, setViewport] = useState({
latitude: 36.592206968562685,
longitude: 3.332469343750031,
width:"100%",
height:"100vh",
zoom: 1.3,
});
const [selectedProperty, setSelectedProperty] = useState(null)
return (
<div>
<ReactMapGL {...viewport} mapboxApiAccessToken="//myAPIkey"
mapStyle="mapbox://styles/jay/cks5xkaa892cp17o5hyxcuu0z"
onViewportChange={viewport => {
setViewport(viewport);
}}>
{
posts &&
posts.map((maps) => (
<Marker key={maps.id} latitude={maps.Latitude} longitude={maps.Longitude}>
{/* <div>{maps.Title}</div> */}
<button className="marker-btn" onClick={e => {
e.preventDefault();
setSelectedProperty(maps);
}}>
<img src="placeholder.svg"/>
</button>
</Marker>
))}
{selectedProperty ? (
<Popup latitude={selectedProperty.Latitude} longitude={selectedProperty.Longitude}
onClose={() => {setSelectedProperty(null);}}>
<h1>{selectedProperty.Title}</h1>
</Popup>) : null}
</ReactMapGL>
</div>
);
}
CSS:
.marker-btn{
background: none;
border: none;
cursor: pointer;
}
.marker-btn :hover{
background: #000;
width: 100vw;
height: 100vh;
border: none;
cursor: pointer;
}
.marker-btn img{
width: 20px;
height: 20px;
}
But when I hover over the Marker in my map this is the result I get:
I want it so that it covers my whole map and not just start from the point where I'm hovering. Additionally, if I hover out of it I want it to go away but when I drag my cursor towards the big popup, it doesnt go away.
There are a lot of ways to do it. Here is mine:
Replace onClick prop and hover pseudo-class for the button inside the Marker component with onMouseEnter prop.
Create your own Popup that has a full height and width of the parent component.
Hide the Map component (by setting the width and height of viewport into 0%) and show the custom Popup component when the mouse enters the button and vice versa.
Here is the working code https://codesandbox.io/s/full-popup-mapbox-stackoverflow-36oi0?file=/src/App.js
Note: you have to attach your own Mapbox Token. You can get it from here https://account.mapbox.com/access-tokens/
import React, { useState } from "react";
import ReactMapGL, { Marker } from "react-map-gl";
import "./styles.css";
export default function App() {
const [viewport, setViewport] = useState({
latitude: 50.826758,
longitude: 4.380197,
width: "100vw",
height: "100vh",
zoom: 3
});
const YOURMAPBOXTOKEN = "";
const posts = [
{
id: 1,
latitude: 50.826758,
longitude: 4.380197
},
{
id: 2,
latitude: 48.893615,
longitude: 2.490906
},
{
id: 3,
latitude: 51.454007,
longitude: -0.235523
}
];
const [selectedProperty, setSelectedProperty] = useState(null);
const [isPopupShown, setIsPopupShown] = useState(false);
return (
<div className="root">
{!isPopupShown && (
<div className="map">
<ReactMapGL
{...viewport}
mapboxApiAccessToken={YOURMAPBOXTOKEN}
mapStyle="mapbox://styles/mapbox/dark-v9"
onViewportChange={(viewport) => {
setViewport(viewport);
}}
>
{posts &&
posts.map((item) => (
<Marker
key={item.id}
latitude={item.latitude}
longitude={item.longitude}
>
<button
className="marker-btn"
onMouseEnter={() => {
setSelectedProperty(item);
setViewport({
latitude: 50.826758,
longitude: 4.380197,
width: "0vw",
height: "0vh",
zoom: 3
});
setIsPopupShown(true);
}}
>
<img src="placeholder.svg" />
</button>
</Marker>
))}
</ReactMapGL>
</div>
)}
{/* SHOW FULL CUSTOM POPUP HERE */}
{selectedProperty && isPopupShown && (
<div className="full-popup">
// todo: create a closing popup button here
</div>
)}
</div>
);
}
Todo: you have to create a closing popup button for the custom Popup.
You can do it by reversing my code like this:
Set selectedProperty into null.
Set isPopupShown into false.
Sett the width and height of the viewport into 100%.
I trying to add the background color for my react app. background color is not applied to the whole screen.
Here is the code for the App.js file
import React from "react";
import "./App.css";
function App() {
return (
<body className="App">
<div>
<h1>Hello world</h1>
</div>
</body>
);
}
export default App;
and the source code of the App.css file is here
.App {
background-color: #efeff6;
height: 100%;
width: 100%;
position: fixed;
}
The result of this here and you can see some white space in left and the right sides.
Can I know that is the mistake I have done?
Try this
html, body {
margin:0;
padding:0;
}
in file index.css change this.
body {
margin: 0;
}
I currently have a page and a button. Upon clicking a button, I would like to update a state property, and once it has been updated, the component will rerender and show the transparent page over the original page.
Would want transparent page like so:
So far thought up of something like:
render() {
if(this.state.buttonPressed) {
return(
<div style={styles.transparentPage}>
//transparentPage content
</div>
)
} else {
return(
<div style={styles.originalPage}>
//originalPage content
</div>
)
}
But this would completely remove the originalPage and be rerendered with the transparentPage. So what would be the correct/proper approach to implementing a transparent page over an original page?
All you would need to do is have something like
render() {
var overlay = this.state.buttonPressed ? <div className="overlay" /> : null;
return(
<div style={styles.originalPage}>
{overlay}
</div>
)
}
and then in your css do:
.overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(250,250,250,.5);
z-index: 25;
}
just make sure your z-index of the modal is more then the overlay z-index so it doesn't make it transparent as well
After trying to find an example where the FloatingActionButton floats at its standard bottom-right screen position with no results, I come to you if you could provide one because it seems to be a normal button without floating to that corner by default.
Am I supposed to make it float by setting custom CSS rules?
Material-UI docs doesn't mention any property about floating Material-UI FloatingActionButton documentation.
Indeed, no property for this in the component FloatingActionButton for the moment.
Waiting for it :
1) A solution using inline styles :
At the top of your component, add :
const style = {
margin: 0,
top: 'auto',
right: 20,
bottom: 20,
left: 'auto',
position: 'fixed',
};
... and in your render method :
render() {
return <FloatingActionButton style={style}><ContentAdd /></FloatingActionButton>
}
OR
2) A solution using CSS file
Add in your CSS file (ex : styles.css referenced on your index.html) :
.fab {
margin: 0px;
top: auto;
right: 20px;
bottom: 20px;
left: auto;
position: fixed;
};
... and put on your React component :
render() {
return <FloatingActionButton className="fab"><ContentAdd /></FloatingActionButton>
}
I actually found this on the Material-UI documentation. I just made a few tweaks to it. Here's the resulting code.
import { makeStyles } from '#material-ui/core/styles';
import Fab from '#material-ui/core/Fab';
import AddIcon from '#material-ui/icons/Add';
const useStyles = makeStyles(theme => ({
fab: {
position: 'fixed',
bottom: theme.spacing(2),
right: theme.spacing(2),
},
}));
add this to your component
const classes = useStyles();
return (
<Fab color="primary" aria-label="add" className={classes.fab}>
<AddIcon />
</Fab>
);
If you want to manipulate CSS in material-ui, its better to use withStyles currying function.
Like this:
import React, {Component} from 'react';
import {Button} from "material-ui";
import {Add} from 'material-ui-icons';
import { withStyles } from 'material-ui/styles';
const style = theme => ({
fab: {
margin: 0,
top: 'auto',
left: 20,
bottom: 20,
right: 'auto',
position: 'fixed',
}
});
class MyPage extends Component{
render() {
const {classes} = this.props;
return <Button fab variant="fab" color="primary" aria-label="add" className={classes.fab}><Add />
</Button>
}
export default withStyles(style)(MyPage);
Documentation link: https://material-ui.com/customization/css-in-js/
In MUI v5, you can add the one-off styles directly to the Fab component via the sx props. Set the position to fixed (as opposed to absolute in other answers*) along with the anchor positions and you're done.
return (
<Fab
sx={{
position: "fixed",
bottom: (theme) => theme.spacing(2),
right: (theme) => theme.spacing(2)
}}
color="primary"
>
<AddIcon />
</Fab>
);
*: Setting to absolute will anchor the button to the bottom right of the closest relative container, the container itself will be moved if the user scrolls down which in turn moves the button. Use fixed value to anchor the button in relative to the viewport, so the scrolling would not affect the button position.
If you are creating a custom theme you can use the theme overrides to style the FAB (Floating Action Button) is floating in the bottom right corner:
import { createMuiTheme } from "#material-ui/core";
export default createMuiTheme({
overrides: {
MuiFab: {
root: {
position: 'absolute',
bottom: '2rem',
right: '2rem'
}
}
}
});
This will override the FAB for every component usage. You can use the same style with a specific class name and override it again for other usages.
In case of custom theme, in MUI v5 the overriding of the style it's a bit different from the v4,
see MUI v5-style-changes.
components: {
MuiFab: {
styleOverrides: {
root: {
position: 'fixed',
bottom: '2rem',
right: '2rem'
}
}
}
}