I am using material ui and i have been trying to make the navabr transparent and get the background image behind it, a similar style to stripe.com and i am having trouble moving the image behind and getting it transparent.
Is there a way to get it looking like stripe.com with the transparent appbar and background image moved up? The main problem is moving up the background image
Code for the Navbar
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '#material-ui/core/styles';
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
import Typography from '#material-ui/core/Typography';
import Button from '#material-ui/core/Button';
import IconButton from '#material-ui/core/IconButton';
import Dialog from '#material-ui/core/Dialog';
import DialogActions from '#material-ui/core/DialogActions';
import DialogContent from '#material-ui/core/DialogContent';
import DialogContentText from '#material-ui/core/DialogContentText';
import DialogTitle from '#material-ui/core/DialogTitle';
import Checkbox from '#material-ui/core/Checkbox';
import TextField from '#material-ui/core/TextField';
import { Link } from 'react-router-dom'
// Styling for our navbar
const styles = {
root: {
flexGrow: 1,
},
grow: {
flexGrow: 1,
},
menuButton: {
marginLeft: -12,
marginRight: 20,
},
button: {
margin: 10,
fontSize: 17
},
text: {
textAlign: 'center',
fontSize: 20,
padding: '0.5em'
},
textField: {
align: 'center',
width: 500
}
};
const MyLink = props => <Link to="/signup" {...props} />
// here is our navbar
class Navbar extends React.Component{
state = {
open: false,
};
handleClickOpen = () => {
this.setState({ open: true });
};
handleClose = () => {
this.setState({ open: false });
};
state = {
checkedA: true,
checkedB: true,
checkedF: true,
};
handleChange = name => event => {
this.setState({ [name]: event.target.checked });
};
render(){
const { classes } = this.props
return (
<div className={classes.root}>
<AppBar position="static" color="inherit" style={{ background: 'transparent', boxShadow: 'none'}}>
<Toolbar>
<IconButton className={classes.menuButton} color="inherit" aria-label="Menu">
</IconButton>
<Typography variant="h6" color="inherit" className={classes.grow}>
</Typography>
<Button color="inherit" onClick={this.handleClickOpen}>Login</Button>
</Toolbar>
</AppBar>
<Dialog
open={this.state.open}
onClose={this.handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description">
<DialogTitle id="alert-dialog-title">{"Have an account? Log In"}</DialogTitle>
<DialogContent>
<DialogTitle>
<Button variant="contained" color="primary" className={classes.button}>
Sign In with Facebook </Button>
<Button variant="contained" color="primary" className={classes.button}>
Sign In with LinkedIn </Button>
</DialogTitle>
<DialogContentText className={classes.text}>
or
</DialogContentText>
<form>
<TextField
id="filled-email-input"
label="Email"
className={classes.textField}
type="email"
name="email"
autoComplete="email"
margin="normal"
variant="filled"
/>
</form>
<form>
<TextField
id="filled-password-input"
label="Password"
className={classes.textField}
type="password"
autoComplete="current-password"
margin="normal"
variant="filled"
/>
</form>
<Checkbox
checked={this.state.checkedG}
onChange={this.handleChange('checkedG')}
value="checkedG"
color= "inherit"
/>
<DialogContentText>
Remember Me?
</DialogContentText>
</DialogContent>
<DialogActions>
<Button component={MyLink} color="primary" autoFocus>
Don't have an account? Sign Up
</Button>
</DialogActions>
</Dialog>
</div>
);
}
}
// requiring a class object
Navbar.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(Navbar);
And heres the code for the Lading page header/background
import React, {Component} from 'react';
import Background from '../img/fixedImg.png';
import './Header.css';
import { Link } from 'react-router-dom';
const headerStyle = {
backgroundImage: `url( ${Background} )`,
height: '100vh',
backgroundSize: 'cover'
}
// class component for our image on the home page
// the <br> needs fixing in the css file
class Header extends Component {
render() {
return (
<header style={headerStyle}>
<h1>Hashtag Hound </h1>
<p> Connecting influencers with brands </p>
<Link to="/signup">Find an Influencer</Link>
</header>
);
}
};
export default Header;
Here is the css for it
header {
margin: 0 auto;
text-align: center;
}
header h1 {
margin: 0;
font-family: arial;
font-size: 4rem;
color: #383636;
}
header p {
font-weight: 700;
font-size: 1.75rem;
font-family: arial;
color: #383636;
}
header a {
box-shadow: 0 3px 3px 0 rgb(0,0,0,1);
font-weight: 700;
font-size: 1.2rem;
background-color: black;
border-color: black;
color: white;
padding: 1.25rem 2.5rem;
border-radius: 2rem;
text-decoration: none;
font-family: arial;
display: inline-block;
}
Related
I have a webpage that looks like this:
This is my _app.tsx file:
import '../styles/globals.css'
import type { AppProps } from 'next/app'
import { createTheme } from '#arwes/design'
import { ThemeProvider, Global, css } from '#emotion/react'
import { globalStyles } from '../shared/styles.js'
function MyApp({ Component, pageProps }: AppProps) {
const theme = createTheme();
return (
<ThemeProvider theme={theme}>
{globalStyles}
<div style={{
marginBottom: theme.space(2),
borderBottom: `${theme.outline(2)}px solid ${theme.palette['primary'].main}`,
padding: theme.space(2),
backgroundColor: theme.palette.neutral.elevate(2),
textShadow: `0 0 ${theme.shadowBlur(1)}px ${theme.palette['primary'].main}`,
color: theme.palette['primary'].main
}}>
Futuristic Sci-Fi UI Web Framework
</div>
<Component {...pageProps} />
</ThemeProvider>
)
}
export default MyApp
And this is shared/styles.js:
import { css, Global, keyframes } from '#emotion/react'
import styled from '#emotion/styled'
export const globalStyles = (
<Global
styles={css`
html,
body {
margin: 0;
background: papayawhip;
min-height: 100%;
font-size: 24px;
}
`}
/>
)
export const blueOnBlack = (theme) => css`
marginBottom: ${theme.space(2)};
borderBottom: ${theme.outline(2)}px solid ${theme.palette['primary'].main};
padding: ${theme.space(2)};
backgroundColor: ${theme.palette.neutral.elevate(2)};
textShadow: 0 0 ${theme.shadowBlur(1)}px ${theme.palette['primary'].main};
color: ${theme.palette['primary'].main};
`
Notice that blueOnBlack is an attempt to put the Futuristic Sci-Fi UI Web Framework style into its own importable variable.
The problem is that when I put blueOnBlack into the _app.tsx as the style for the Futuristic Sci-Fi UI Web Framework div tag, it fails.
This is _app.tsx with blueOnBlack imported:
import '../styles/globals.css'
import type { AppProps } from 'next/app'
import { createTheme } from '#arwes/design'
import { ThemeProvider, Global, css } from '#emotion/react'
import { globalStyles, blueOnBlack } from '../shared/styles.js'
function MyApp({ Component, pageProps }: AppProps) {
const theme = createTheme();
return (
<ThemeProvider theme={theme}>
{globalStyles}
<div style={blueOnBlack(theme)}>
Futuristic Sci-Fi UI Web Framework
</div>
<Component {...pageProps} />
</ThemeProvider>
)
}
export default MyApp
The resulting webpage looks like this,
It's almost right... but it dropped the background color. Why is it different?
I changed shared/styles.js from:
import { css, Global, keyframes } from '#emotion/react'
import styled from '#emotion/styled'
export const globalStyles = (
<Global
styles={css`
html,
body {
margin: 0;
background: papayawhip;
min-height: 100%;
font-size: 24px;
}
`}
/>
)
export const blueOnBlack = (theme) => css`
marginBottom: ${theme.space(2)};
borderBottom: ${theme.outline(2)}px solid ${theme.palette['primary'].main};
padding: ${theme.space(2)};
backgroundColor: ${theme.palette.neutral.elevate(2)};
textShadow: 0 0 ${theme.shadowBlur(1)}px ${theme.palette['primary'].main};
color: ${theme.palette['primary'].main};
`
to this:
import { css, Global, keyframes } from '#emotion/react'
import styled from '#emotion/styled'
export const globalStyles = (
<Global
styles={css`
html,
body {
margin: 0;
background: papayawhip;
min-height: 100%;
font-size: 24px;
}
`}
/>
)
export const blueOnBlack = (theme) => styled.div={
marginBottom: theme.space(2),
borderBottom: theme.outline(2) + 'px solid' + theme.palette['primary'].main,
padding: theme.space(2),
backgroundColor: theme.palette.neutral.elevate(2),
textShadow: '0 0 ' + theme.shadowBlur(1) + 'px ' + theme.palette['primary'].main,
color: theme.palette['primary'].main
}
And then it ran and gave me the correct styling including the black background on the text. Notice that I'm using styled.div instead of css
I'm writing a social media app that allows you to post either text or image posts. I'm struggling to be able to show image as preview when posting.
It doesn't seem to be able to set the imageData, or does so async and idk how to await the result so it shows in my preview.
Heres the parent component:
import React, { useState } from "react";
import { collection, addDoc, getFirestore } from "firebase/firestore";
import { useUserContext } from "../../../services/user-context";
import { getStorage, ref, uploadBytes } from "firebase/storage";
import TextPost from "./TextPost";
import ImagePost from "./ImagePost";
export const CreatePostModal = ({ open, setOpen }) => {
const { user } = useUserContext();
const db = getFirestore();
const storage = getStorage();
const [imageData, setImageData] = useState(null);
const handleImageUpload = async (e) => {
if (e.target.files[0]) {
const reader = new FileReader();
reader.onload = (img) => setImageData(img.target.result);
reader.readAsDataURL(await e.target.files[0]);
console.log(imageData);
}
};
const pictureUploadRef = ref(storage, "posts/");
const handleSubmit = async (e) => {
e.preventDefault();
const formData = new FormData(e.target);
console.log(formData);
const title = formData.get("title");
const content = formData.get("content");
const postRef = await addDoc(collection(db, "posts"), {
comments: [],
content: content,
likes: [],
picture: imageData,
technologies: [],
timestamp: new Date(),
title: title,
userAvatar: "avatarUrl",
userID: user.id,
});
};
return imageData ? (
<div>
<ImagePost
open={open}
setOpen={setOpen}
handleImageUpload={handleImageUpload}
handleSubmit={handleSubmit}
/>
</div>
) : (
<div>
<TextPost
open={open}
setOpen={setOpen}
handleImageUpload={handleImageUpload}
handleSubmit={handleSubmit}
imageData={imageData}
/>
</div>
);
};
And here is child:
import React from "react";
import Box from "#mui/material/Box";
import Typography from "#mui/material/Typography";
import Modal from "#mui/material/Modal";
import styled from "styled-components";
import { Button } from "#mui/material";
import ImageIcon from "#mui/icons-material/Image";
const TitleInput = styled.textarea`
width: 100%;
height: 10%;
border: none;
background-color: inherit;
font-size: 25px;
resize: none;
&:focus-visible {
outline: none;
}
&::placeholder {
color: black;
}
text-align: center;
margin: 10px 0 15px;
color: black;
`;
const ContentInput = styled.textarea`
width: 100%;
height: 20%;
border: none;
background-color: inherit;
font-size: 20px;
resize: none;
&:focus-visible {
outline: none;
}
&::placeholder {
color: black;
}
`;
const ImageContainer = styled.div`
width: 100%;
height: 50%;
// background-color: red;
`;
const style = {
position: "absolute",
height: "50%",
minWidth: "400px",
minHeight: "550px",
width: "40%",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
bgcolor: "#f0f2f5",
boxShadow: 24,
p: 4,
borderRadius: "20px",
display: "flex",
justifyContent: "flex-start",
alignItems: "center",
flexDirection: "column",
outline: "none",
padding: "15px 25px 25px",
};
const ImagePost = ({
open,
setOpen,
handleImageUpload,
handleSubmit,
imageData,
}) => {
return (
<Modal
open={open}
onClose={() => setOpen(false)}
aria-labelledby="modal-modal-title"
>
<Box sx={style}>
<Typography
id="modal-modal-title"
variant="h4"
component="h2"
sx={{ fontSize: "30px" }}
>
Create a post
</Typography>
<div
style={{
border: "0.5px solid #a6a6a6",
width: "100%",
margin: "15px 0 0",
}}
/>
<form style={{ width: "100%", height: "100%" }}>
<TitleInput placeholder="Post title" required name="title" />
<ContentInput placeholder="Post content" required name="content" />
<ImageContainer>
{imageData ? <img src={imageData} alt="" /> : <p>failed</p>}
</ImageContainer>
<div style={{ display: "flex", justifyContent: "center" }}>
<label htmlFor="upload-button">
<input
onChange={handleImageUpload}
accept="image/*"
id="upload-button"
type="file"
style={{ display: "none" }}
/>
<Button
variant="contained"
size="large"
sx={{ ml: "-70px" }}
component="span"
>
<ImageIcon />
</Button>
</label>
<label htmlFor="submit-button">
<Button
type="submit"
id="submit-button"
variant="contained"
size="large"
color="success"
sx={{ ml: "10px", width: "150px" }}
onClick={handleSubmit}
>
Submit
</Button>
</label>
</div>
</form>
</Box>
</Modal>
);
};
export default ImagePost;
Can you help me figure out what I'm doing wrong?
1 key thing that you are missing here is that react state updates are not instantaneous, they are scheduled. You make api call which is async and may complete after the page has already been rendered. you may wanna look into useEffect hook to solve this problem.
Card Component
import image from "../../Assets/pic.jpg";
import React, { useState } from "react";
import { makeStyles } from "#material-ui/core/styles";
import Card from "#material-ui/core/Card";
import CardActionArea from "#material-ui/core/CardActionArea";
import FavoriteBorderIcon from "#material-ui/icons/FavoriteBorder";
import CardContent from "#material-ui/core/CardContent";
import CardMedia from "#material-ui/core/CardMedia";
import Typography from "#material-ui/core/Typography";
import styles from "./Cards.module.css";
import Stars from "../Stars/Stars";
const useStyles = makeStyles({
root: {
maxWidth: 345,
},
});
const Cards = () => {
const [showComponent, setShowComponent] = useState(false);
const classes = useStyles();
const handleToggleHoverIn = (event) => {
event.preventDefault();
setShowComponent(true);
};
const handleToggleHoverOut = (event) => {
event.preventDefault();
setShowComponent(false);
};
console.log("The state showComponent value is ", showComponent);
return (
<div className={styles.container}>
<Card
onMouseEnter={handleToggleHoverIn}
onMouseLeave={handleToggleHoverOut}
className={classes.root}
>
<CardActionArea>
<div id={styles.imageCentre}>
<CardMedia
component="img"
alt=""
className={styles.image}
image={image}
title="Contemplative Reptile"
/>
{/*
here when I hover over my <Stars/> and <FavoriteBorderIcon/>, the hover effect of opacity that I have on
my Card's image, vanishes
*/}
{showComponent ? (
<>
<div id={styles.stars}>
<Stars />
</div>
<FavoriteBorderIcon fontSize="large" id={styles.heart} />
</>
) : null}
</div>
<CardContent>
<Typography
gutterBottom
variant="h5"
component="h2"
id={styles.textCentre}
>
Printed round Neck
</Typography>
<Typography variant="body2" color="textSecondary" component="p">
<div class="text">
<p id={styles.price}>
<b>Rs. 454</b>
<strike>Rs. 699</strike>
<span style={{ color: "#FF7F7F" }}> (35 % off) </span>
</p>
</div>
</Typography>
</CardContent>
</CardActionArea>
</Card>
</div>
);
};
export default Cards;
Card's CSS styling
.image {
width: 300px;
justify-content: center;
}
.image:hover {
opacity: 0.5;
}
#imageCentre {
align-items: center !important;
position: relative;
}
/* #imageCentre:hover {
opacity: 0.5;
} */
#textCentre {
text-align: center;
}
.container {
display: flex;
justify-content: center;
padding: 2em;
}
#price,
.text h3 {
text-align: center;
}
#price b {
padding-right: 0.5em;
font-size: 1.3em;
}
#heart {
position: absolute;
top: 0;
right: 0;
padding: 20px 20px 0 0;
color: aliceblue;
}
#stars {
position: absolute;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%);
margin-top: 50%;
}
when I hover over my card, the opacity hover-effect comes in but when I move to the heart or star component, the opacity-hover vanishes. I want the hover-effect to remain even when I hover over my star and heart component. Is there any way that I can make the opacity-hover-effect to remain there, when I hover over the stars and heart component
Live Link
Below is an example of one way to do this. The key aspect of the solution is to use the :hover pseudo-class on a common parent of the img, stars, and icon elements. In my example, this is done via the action class applied to the CardActionArea element. My example is using makeStyles, but you could achieve the same effect in your CSS with the following:
#imageCentre:hover .image {
opacity: 0.5;
}
It looks like you tried something similar (the commented out #imageCenter:hover styles), but since you weren't targeting the descendant .image class for the opacity, the opacity would have impacted the stars and favorite icon as well which you probably don't want.
Here's a full working example:
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import Card from "#material-ui/core/Card";
import CardActionArea from "#material-ui/core/CardActionArea";
import CardActions from "#material-ui/core/CardActions";
import CardContent from "#material-ui/core/CardContent";
import CardMedia from "#material-ui/core/CardMedia";
import Button from "#material-ui/core/Button";
import Typography from "#material-ui/core/Typography";
import FavoriteBorderIcon from "#material-ui/icons/FavoriteBorder";
import Rating from "#material-ui/lab/Rating";
const useStyles = makeStyles({
root: {
maxWidth: 345
},
media: {
height: 140
},
action: {
position: "relative",
"&:hover $media": {
opacity: 0.5
}
},
favorite: {
position: "absolute",
top: 10,
left: 10,
color: "white"
},
rating: {
position: "absolute",
top: 100,
left: 100
}
});
export default function MediaCard() {
const classes = useStyles();
return (
<Card className={classes.root}>
<CardActionArea className={classes.action}>
<CardMedia
component="img"
className={classes.media}
image="https://material-ui.com/static/images/cards/contemplative-reptile.jpg"
title="Contemplative Reptile"
/>
<CardContent>
<Typography gutterBottom variant="h5" component="h2">
Lizard
</Typography>
<Typography variant="body2" color="textSecondary" component="p">
Lizards are a widespread group of squamate reptiles, with over 6,000
species, ranging across all continents except Antarctica
</Typography>
</CardContent>
<FavoriteBorderIcon className={classes.favorite} />
<Rating className={classes.rating} name="rating" />
</CardActionArea>
<CardActions>
<Button size="small" color="primary">
Share
</Button>
<Button size="small" color="primary">
Learn More
</Button>
</CardActions>
</Card>
);
}
I have a React application. I have decided to add a layout using Ant Design. And i followed below example.
https://2x.ant.design/components/layout/#components-layout-demo-custom-trigger
This is my component code. (Full.js)
import React, { Component, Fragment } from 'react'
import { Layout, Menu } from 'antd'
import Icon from '#ant-design/icons'
import './Full.css'
import ReactDOM from 'react-dom'
import DailyData from '../DailyData'
import Container from 'react-bootstrap/Container'
import Toggle from './Toggle'
const { Header, Footer, Sider, Content } = Layout;
class Full extends React.Component {
state = {
collapsed: false,
};
toggle = () => {
this.setState({
collapsed: !this.state.collapsed,
});
}
render() {
return (
<Layout style={{ height: "100vh" }}>
<Sider
trigger={null}
collapsible
collapsed={this.state.collapsed}
>
<div className="logo" />
<Menu theme="dark" mode="inline" defaultSelectedKeys={['1']}>
<Menu.Item key="1">
<Icon type="user" />
<span>nav 1</span>
</Menu.Item>
<Menu.Item key="2">
<Icon type="video-camera" />
<span>nav 2</span>
</Menu.Item>
<Menu.Item key="3">
<Icon type="upload" />
<span>nav 3</span>
</Menu.Item>
</Menu>
</Sider>
<Layout>
<Header style={{ background: '#fff', padding: 0 }}>
<Icon
className="trigger"
type={this.state.collapsed ? 'menu-unfold' : 'menu-fold'}
onClick={this.toggle}
/>
</Header>
<Content style={{ margin: '24px 16px', padding: 24, background: '#fff', minHeight: 280 }}>
Content
</Content>
</Layout>
</Layout>
);
}
}
export default Full;
I'm using this component as below in App.js file.
import React from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import Header from './components/layout/Header.js'
import DailyData from './components/DailyData.js'
import Container from 'react-bootstrap/Container'
import Toggle from './components/layout/Toggle.js'
import Full from './components/layout/Full'
class App extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div className="App">
<Full />
</div >
);
}
}
export default App;
My Full.css file as below.
#components-layout-demo-custom-trigger .trigger {
font-size: 18px;
line-height: 64px;
padding: 0 16px;
cursor: pointer;
transition: color .3s;
}
#components-layout-demo-custom-trigger .trigger:hover {
color: #108ee9;
}
#components-layout-demo-custom-trigger .logo {
height: 32px;
background: #333;
border-radius: 6px;
margin: 16px;
}
But the output will display like this.
Well, I also used Ant design Sider and I am using version 4.4.1. Not sure what you want to acheive, so I am sharing the whole code with you.
import React from 'react';
import { Route, Switch, NavLink, Redirect, withRouter } from 'react-router-dom'
import {RouteComponentProps} from "react-router";
import { Layout, Menu } from 'antd';
import {
DesktopOutlined,
PieChartOutlined,
UserOutlined,
SettingOutlined
} from '#ant-design/icons';
import Shipper from '../shipper/shipper'
const { Header, Content, Footer, Sider } = Layout;
const { SubMenu } = Menu;
// Type whatever you expect in 'this.props.match.params.*'
type PathParamsType = {
param1: string,
}
// Your component own properties
type PropsType = RouteComponentProps<PathParamsType> & {
}
class Sidebar extends React.Component<PropsType> {
state = {
collapsed: false,
};
onCollapse = (collapsed: any) => {
this.setState({ collapsed });
};
render() {
let { pathname } = this.props.location;
return (
<Layout style={{ minHeight: '100vh' }}>
<Header className="header">
<div className="logo" />
<Menu mode="horizontal" theme="dark" className="flex-setting">
<SubMenu icon={<SettingOutlined />} title="Settings">
<Menu.ItemGroup title="Basic Settings">
<Menu.Item key="setting:2">
<a href={"/accounts/logout/"} target="_self">
Signout
</a>
</Menu.Item>
</Menu.ItemGroup>
</SubMenu>
</Menu>
</Header>
<Layout>
<Sider collapsible collapsed={this.state.collapsed} onCollapse={this.onCollapse}>
{/* <div className="logo" /> */}
<Menu theme="dark"
defaultSelectedKeys={['/shipper']}
selectedKeys={[pathname]}
mode="inline">
<Menu.Item key="/shipper" icon={<PieChartOutlined />}>
<NavLink to="/shipper">
<span>Shipper</span>
</NavLink>
</Menu.Item>
</SubMenu>
</Menu>
</Sider>
<Layout className="site-layout">
{/* <Header className="site-layout-background" style={{ padding: 0 }} /> */}
<Content style={{ margin: "16px 16px", background: "#fff" }}>
<div style={{ padding: 24, background: "#fff", minHeight: 360 }}>
<Switch>
<Route exact path="/" render={() => (
<Redirect to="/shipper"/>
)}/>
<Route path="/shipper">
<Shipper />
</Route>
</Switch>
</div>
</Content>
<Footer style={{ textAlign: 'center' }}>Copyrights © 2020 All Rights Reseverd by Company.</Footer>
</Layout>
</Layout>
</Layout>
);
}
}
export default withRouter(Sidebar);
My css is following:
.header {
display: inherit;
}
.logo {
height: 32px;
width: 35px;
margin: 16px;
background-image: url("main-logo.jpg");
}
.flex-setting {
display: flex;
flex-direction: row-reverse;
width: 100%;
}
Alot of things not necessary for you, so remove that part. Once you follow this, you will achieve something link this:
Remove " #components-layout-demo-custom-trigger" from css file and it will work.
I am sharing my css file.
App.css
#import "~antd/dist/antd.css";
.trigger {
font-size: 18px;
line-height: 64px;
padding: 0 24px;
cursor: pointer;
transition: color 0.3s;
}
.trigger:hover {
color: #1890ff;
}
.logo {
height: 32px;
background: rgba(255, 255, 255, 0.2);
margin: 16px;
}
.site-layout .site-layout-background {
background: #fff;
}
Because the example has trigger class ID # component-layout-demo-custom-trigger in front of it but the copied code also has # component-layout-demo-custom-trigger removed
enter image description here
I'm creating a Sidebar similar to the Mini Variant drawer demo, but my project specifies that all the css formatting must be done in a separate css file, not in the drawer's js file (as the material-ui demos do). I've figured out how to format my drawer according to the demos, but now I need to figure out how to separate out the css and make it workable.
Right now the drawer renders with default settings, but all but one of the css classes aren't working/rendering. Only one, listItem, works and changes the height of a ListItem, which is weird. All the other css classes don't change how the drawer looks.
This is the non-working version with a separate css file imported in:
.root {
display: flex;
}
.drawerOpen {
top: 70px;
bottom: 70px;
position: fixed;
white-space: nowrap; /*text doesn't shrink into side*/
width: 240;
transition: width 2s;
}
.drawerClose {
top: 70px;
bottom: 70px;
position: fixed;
width: 240;
overflow-x: hidden; /*hides text when drawer is closed*/
transition: width 2s;
}
.iconButton {
margin-top: 15px;
margin-bottom: 7px;
}
.listItem {
height: 75px;
}
SideBar.js:
import React, { Component } from "react";
import PropTypes from "prop-types";
import Drawer from "#material-ui/core/Drawer";
import { withStyles } from "#material-ui/core/styles";
import { IconButton, Divider, ListItemIcon } from "#material-ui/core";
import { List, ListItem, ListItemText } from "#material-ui/core";
import InboxIcon from "#material-ui/icons/MoveToInbox";
import MailIcon from "#material-ui/icons/Mail";
import ChevronRightIcon from "#material-ui/icons/ChevronRight";
import ChevronLeftIcon from "#material-ui/icons/ChevronLeft";
import "../css/SideBar.css";
import "../css/SideBar.css";
class Sidebar extends Component {
state = {
open: false
};
handleSidebarToggle = () => {
this.setState({ open: !this.state.open });
};
render() {
const { classes } = this.props;
const { open } = this.state;
return (
<div className="root">
<Drawer
variant="permanent"
anchor="left"
open={open}
className={(open === true) ? "drawerOpen" : "drawerClose"}
>
<div>
<Divider />
<IconButton
className="iconButton"
onClick={this.handleSidebarToggle}
>
{open === false ? <ChevronRightIcon /> : <ChevronLeftIcon />}
</IconButton>
</div>
<List>
<Divider />
<ListItem className="listItem" button>
<ListItemIcon>
<InboxIcon />
</ListItemIcon>
<ListItemText primary="Info" />
</ListItem>
<Divider />
<ListItem className="listItem" button>
<ListItemIcon>
<MailIcon />
</ListItemIcon>
<ListItemText primary="Roofing" />
</ListItem>
<Divider />
<ListItem className="listItem" button>
<ListItemIcon>
<InboxIcon />
</ListItemIcon>
<ListItemText primary="Siding" />
</ListItem>
<Divider />
<ListItem className="listItem" button>
<ListItemIcon>
<MailIcon />
</ListItemIcon>
<ListItemText primary="Windows" />
</ListItem>
<Divider />
<ListItem className="listItem" button>
<ListItemIcon>
<MailIcon />
</ListItemIcon>
<ListItemText primary="Shop" />
</ListItem>
<Divider />
</List>
</Drawer>
</div>
);
}
}
export default Sidebar;
This is the working version in just one .js file with the css in the const styles:
import React, { Component } from "react";
import PropTypes from "prop-types";
import Drawer from "#material-ui/core/Drawer";
import { withStyles } from "#material-ui/core/styles";
import { IconButton, Divider, ListItemIcon } from "#material-ui/core";
import { List, ListItem, ListItemText } from "#material-ui/core";
import InboxIcon from "#material-ui/icons/MoveToInbox";
import MailIcon from "#material-ui/icons/Mail";
import ChevronRightIcon from "#material-ui/icons/ChevronRight";
import ChevronLeftIcon from "#material-ui/icons/ChevronLeft";
import "../css/SideBar.css";
const styles = theme => ({
root: {
display: "flex",
},
drawerPaper: {
top: "70px", //moves Sidebar below AppBar
bottom: "70px",
position: "fixed",
whiteSpace: "nowrap", //text doesn't shrink into side
width: 240,
transition: theme.transitions.create("width", {
//makes transitions smooth
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen
})
},
drawerPaperClose: {
overflowX: "hidden", //display mini sidebar
width: theme.spacing.unit * 7,
[theme.breakpoints.up("sm")]: {
width: theme.spacing.unit * 9
},
transition: theme.transitions.create("width", {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen
})
},
iconButton: { //fixes spacing
marginTop: "15px",
marginBottom: "7px"
},
listItem: {
height: "75px"
}
});
class Sidebar extends Component {
state = {
open: false
};
handleSidebarToggle = () => {
this.setState({ open: !this.state.open });
};
render() {
const { classes } = this.props;
const { open } = this.state;
return (
<div className={classes.root}>
<Drawer
variant="permanent"
anchor="left"
open={open}
classes={{
paper: classNames(
classes.drawerPaper,
!open && classes.drawerPaperClose
)
}}
className="drawer"
>
<div>
<Divider />
<IconButton
className={classes.iconButton}
onClick={this.handleSidebarToggle}
>
{open === false ? <ChevronRightIcon /> : <ChevronLeftIcon />}
</IconButton>
</div>
<List>
<Divider />
<ListItem className={classes.listItem} button>
<ListItemIcon>
<InboxIcon />
</ListItemIcon>
<ListItemText primary="Info" />
</ListItem>
<Divider />
<ListItem className={classes.listItem} button>
<ListItemIcon>
<MailIcon />
</ListItemIcon>
<ListItemText primary="Roofing" />
</ListItem>
<Divider />
<ListItem className={classes.listItem} button>
<ListItemIcon>
<InboxIcon />
</ListItemIcon>
<ListItemText primary="Siding" />
</ListItem>
<Divider />
<ListItem className={classes.listItem} button>
<ListItemIcon>
<MailIcon />
</ListItemIcon>
<ListItemText primary="Windows" />
</ListItem>
<Divider />
<ListItem className={classes.listItem} button>
<ListItemIcon>
<MailIcon />
</ListItemIcon>
<ListItemText primary="Shop" />
</ListItem>
<Divider />
</List>
</Drawer>
</div>
);
}
}
Sidebar.propTypes = {
classes: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired
};
export default withStyles(styles, { withTheme: true })(Sidebar);
you can create a separate file with styles but as .js files and refer it in the component.
material-UI uses CSS-in-js
referer this link:https://material-ui.com/customization/css-in-js/
In your scenario, you can create a styles.js file in the same folder with the component(or any place you wish) like below:
export default const styles = {
.root {
display: flex;
}
.drawerOpen {
top: 70px;
bottom: 70px;
position: fixed;
white-space: nowrap; /*text doesn't shrink into side*/
width: 240;
transition: width 2s;
}
.drawerClose {
top: 70px;
bottom: 70px;
position: fixed;
width: 240;
overflow-x: hidden; /*hides text when drawer is closed*/
transition: width 2s;
}
.iconButton {
margin-top: 15px;
margin-bottom: 7px;
}
.listItem {
height: 75px;
}
}
and refer it in the component as:
import styles from "./styles"
... component ...
export default withStyles(styles)(Sidebar);
find more details about how to override styles of material-UI components from here: https://material-ui.com/customization/overrides/
hope this will help you.