How can I make a header with 4 equally spaced items in React Native?
Coming from a web dev background, the following flexbox produces 4 equally spaced items:
<html>
<head>
<style>
#header {
display: flex;
flex: 1;
flex-direction: "row";
height: 20px;
}
.item {
flex: 1;
background-color: red;
}
</style>
</head>
<body>
<div id="header">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="item">Item 4</div>
</div>
</body>
</html>
That HTML produces this:
However, with React Native, the same thing doesn't seem to work:
var navbarStyles = StyleSheet.create({
navbar: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
height: 20
},
navbarItem: {
flex: 1
}
});
var Navbar = React.createClass({
render: function() {
return (
<View style={navbarStyles.navbar}>
<View style={navbarStyles.navbarItem}>
<Text>Item 1</Text>
</View>
<View style={navbarStyles.navbarItem}>
<Text>Item 2</Text>
</View>
<View style={navbarStyles.navbarItem}>
<Text>Item 3</Text>
</View>
<View style={navbarStyles.navbarItem}>
<Text>Item 4</Text>
</View>
</View>
);
}
});
Hi I did the above code and it works fine and gives output like the html example you have given above. And if you need to center align all text instead of the beginning of each subview, you could use alignItems to 'center' at navbaritem.
I beleive you are facing the error because of the style of parent view above it. try fixing that. try giving a backgroundcolor to navbar and you will get some idea of issue.
You can do this for parent
parent:{
flex: 1,
flexDirection:'row'
}
and then child items
child:{
flex: 1,
}
Related
I have one parent div which height is 450px. And 3 child div which height is 150px each. i want to align this 3 div using flex. and the position is 1div: left-corner, 2div:center, 3div:bottom-right.
give me the solution using only css flexbox.
Try this,
display:'flex',
height:'450px',
justifyContent:'space-between'
Edit
<div
style={{
display: "flex",
height: "450px",
flexDirection: "column",
}}
>
{/* top */}
<div
style={{
display: "flex",
}}
>
<div style={{ flex: "0 0 25%", border: "1px solid" }}>
<h1>left</h1>
</div>
<div style={{ flex: "0 0 25%", border: "1px solid" }}>
<h1>center</h1>
</div>
</div>
{/* bottom */}
<div
style={{
display: "flex",
justifyContent:'flex-end'
}}
>
<div
style={{
flex: "0 0 50%",
border: "1px solid",
}}
>
<h1>bottom right</h1>
</div>
</div>
</div>
New to Material UI and flex I've read a lot of documentation but for some reason I'm missing how to take a Material UI <CancelIcon /> and align right only that icon in a <Drawer />. I've read that to be able to prevent the <Drawer /> from being inline I need to use flexDirection: 'column'.
Code
<Drawer
{...{
anchor: 'right',
open: drawerOpen,
onClose: handleDrawerClose,
}}
>
<div className={drawerContainer}>
<CancelIcon className={cancelBtn} />
<GetDrawerChoices />
</div>
</Drawer>
Styles
import { makeStyles } from '#material-ui/core'
const useStyles = makeStyles({
drawerContainer: {
padding: '24px 0',
display: 'flex',
flexDirection: 'column',
},
cancelBtn: {
margin: '0 28px 8px 28px',
cursor: 'pointer',
// justify: 'flex-end',
alignContent: 'flex-end',
},
})
export default useStyles
Research
I've tried the following:
How to add close icon in Material UI Dialog Header top right corner:
cancelBtn: {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
},
What's the right way to float right or left using the material-ui appbar with material-ui-next?
cancelBtn: {
display: 'flex',
flex: 1,
},
How to align a component to the center/right:
cancelBtn: {
justify: 'flex-end',
},
Further reading: Aligning Items in a Flex Container
Preview
In Material UI with flex how can I get the <CancelIcon /> to align right but leave the remaining text left justified?
You can use Box component outside the CancelBtn like this.
<Box
display="flex"
justifyContent="flex-end"
>
<CancelIcon className={cancelBtn} />
</Box>
Or like this.
<Box
display="flex"
>
<Box flexGrow={1} />
<CancelIcon className={cancelBtn} />
</Box>
hotcakedev's answer got me where I needed. Just cleaned it up:
bring in:
// Material UI
import { Box } from '#material-ui/core'
import CancelIcon from '#material-ui/icons/Cancel'
// Styles
import useStyles from '../styles'
const { drawerContainer, cancelBtn } = useStyles()
the div:
<div className={drawerContainer}>
<Box className={cancelBtn}>
<CancelIcon />
</Box>
<GetDrawerChoices />
</div>
and styles:
drawerContainer: {
padding: '24px 0',
display: 'flex',
flexDirection: 'column',
},
cancelBtn: {
margin: '0 20px 8px 0',
cursor: 'pointer',
display: 'flex',
justifyContent: 'flex-end',
},
if you want move only one element to right side you can use order in flex
cancelBtn: {
order : 1 // it moves just cancelBtn to the right side
};
I am trying to redirect the user if he/she has not logged in. I am using the below snipet to do that.
if(!this.props.isAuthenticated){
this.nextPath('/account/login')
}
But when I execute it, I am getting an error. (Error: Maximum update depth exceeded). If I takeoff the above snippet. I am not getting Error.
I have also attached the full code. Help me with debugging this problem.
import React, { Component, Suspense } from 'react'
import { Layout, Menu } from 'antd';
import {TagFilled, SettingFilled , FileAddOutlined, DeleteFilled, LogoutOutlined } from '#ant-design/icons';
import { renderRoutes } from 'react-router-config';
import { loadLabels, deleteLabel} from '../../Store/Action/label'
import { logout } from '../../Store/Action/auth'
import { connect } from 'react-redux';
import Dialog from '#material-ui/core/Dialog';
import DialogActions from '#material-ui/core/DialogActions';
import DialogContent from '#material-ui/core/DialogContent';
import DialogTitle from '#material-ui/core/DialogTitle';
import Button from '#material-ui/core/Button';
import AddLabel from './Components/AddLabel'
import SideBar from './Components/SideBar'
import Avatar from '#material-ui/core/Avatar';
import {Dropdown} from 'react-bootstrap'
import Card from '#material-ui/core/Card';
import CardContent from '#material-ui/core/CardContent';
import { Row, Col, ListGroup } from 'react-bootstrap';
import Typography from '#material-ui/core/Typography';
import Divider from '#material-ui/core/Divider';
import ListSubheader from '#material-ui/core/ListSubheader';
import List from '#material-ui/core/List';
import ListItem from '#material-ui/core/ListItem';
import ListItemIcon from '#material-ui/core/ListItemIcon';
import ListItemText from '#material-ui/core/ListItemText';
import { Redirect } from 'react-router-dom';
const { Header, Content, Footer, Sider } = Layout;
export class HomePage extends Component {
//Constructor
constructor(){
super()
this.state = {
collapsed: false,
addLabelVisible: false,
isHovered: {},
anchorEl: null,
setAnchorEl: null
};
this.addLabelToggle = this.addLabelToggle.bind(this)
this.handleMouseEnter = this.handleMouseEnter.bind(this);
this.handleMouseLeave = this.handleMouseLeave.bind(this);
this.handlelogOut = this.handlelogOut.bind(this);
this.fetchData = this.fetchData.bind(this);
}
//Collapse the Sidebar
onCollapse = collapsed => {
this.setState({ collapsed });
};
//Toogle Add Label Dialog
addLabelToggle(addLabelVisible) {
this.setState({ addLabelVisible });
}
//Fetch All labels from the API
componentDidMount(){
console.log('problem here 1')
this.props.loadLabels()
}
//API CAll
fetchData(){
this.props.loadLabels()
}
//Called Whenever new Label is Added
componentDidUpdate(prevProps) {
if(typeof(prevProps.labels) === 'undefined' ) {
this.fetchData()
}
else if(prevProps.labels === this.props.labels){
this.fetchData()
}else{
}
}
//Hover
handleMouseEnter = index => {
this.setState(prevState => {
return { isHovered: { ...prevState.isHovered, [index]: true } };
});
};
//Hover
handleMouseLeave = index => {
this.setState(prevState => {
return { isHovered: { ...prevState.isHovered, [index]: false } };
});
};
//Delete a Label
handleLabelDelete(id){
const data = {
id: id,
img: 'https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png'
}
this.props.deleteLabel(data)
}
handleClick = (event) => {
this.setState({
anchorEl: event.currentTarget
})
};
handleClose = () => {
this.setState({
anchorEl: null
})
};
handlelogOut = (e) =>{
console.log('logout')
this.props.logout()
}
nextPath(path) {
this.props.history.push(path);
}
render() {
const open = Boolean(this.anchorEl);
const id = open ? 'simple-popover' : undefined;
const { arr, isHovered } = this.state;
console.log(this.props.request)
if(!this.props.isAuthenticated){
this.nextPath('/account/login')
}
return (
<Layout style={{ minHeight: '100vh' }}>
{/* Navbar */}
<Header className="header" style={{ height: '60px', backgroundColor: '#1a243a' }}>
<div style={{ width: '120px', height: '31px', float: 'left', margin: '16px 28px 16px 0' }}>
<h2 style={{ color: 'white' }}>Nexdo</h2>
</div>
<div style={{ float: 'right' }}>
<Dropdown>
<Dropdown.Toggle style={{ backgroundColor: 'transparent', borderColor: 'transparent' }} id="dropdown-basic">
<Avatar>{this.props.user?this.props.user.first_name.slice(0,1):""}</Avatar>
</Dropdown.Toggle>
<Dropdown.Menu>
<Card style={{ background: '#ffffff', boxShadow: 'none', width: '280px' }}>
<CardContent>
<Row>
<Col xs={9}>
<Typography style={{ alignContent: 'right', justifyContent: 'right', display: 'flex' }} variant="h6" noWrap>
{this.props.user?this.props.user.first_name:""} {this.props.user?this.props.user.last_name:""}
</Typography>
<Typography style={{ color: '#333333', fontSize: '11px' , alignContent: 'right', justifyContent: 'right', display: 'flex' }} variant="h6" noWrap>
{this.props.user?this.props.user.email:""}
</Typography>
</Col>
<Col xs={3}>
<Avatar>{this.props.user?this.props.user.first_name.slice(0,1):""}</Avatar>
</Col>
</Row>
</CardContent>
<Divider />
<List
component="nav"
aria-labelledby="nested-list-subheader"
subheader={
<ListSubheader component="div" id="nested-list-subheader">
Actions
</ListSubheader>
}
>
<ListItem button>
<ListItemIcon>
<SettingFilled />
</ListItemIcon>
<ListItemText primary="Profile" />
</ListItem>
<a onClick={this.handlelogOut}>
<ListItem button>
<ListItemIcon>
<LogoutOutlined />
</ListItemIcon>
<ListItemText primary="Logout" />
</ListItem>
</a>
</List>
</Card>
</Dropdown.Menu>
</Dropdown>
</div>
</Header>
{/* SideBar and Content */}
<Layout className="site-layout">
<SideBar labelData = {this.props.labels} addLabelToggle = {this.addLabelToggle}/>
{/* Content which will be loaded dynamically */}
<Content style={{ margin: '0 16px' }}>
<main style={{ backgroundColor: "#fafafa", minHeight: '-webkit-fill-available' }} >
<Suspense fallback={<div>Loading...</div>}>
{renderRoutes(this.props.route.routes,)}
</Suspense>
</main>
</Content>
</Layout>
{/* Footer */}
<Footer style={{ textAlign: 'center' }}>Joan Louji ©2020 Created by Joan Louji</Footer>
{/* Add Label Dialog Box */}
<Dialog scroll="paper" open={this.state.addLabelVisible} onClose={()=>this.addLabelToggle(false)} aria-labelledby="scroll-dialog-title" aria-describedby="scroll-dialog-description">
<DialogTitle id="form-dialog-title"><b>Labels</b></DialogTitle>
<DialogContent>
<div style={{ height: "400px", width: "300px" }}>
{/* Display the Add Label Box */}
<AddLabel editClassName="form-control" value="Create a new Label" />
{this.props.labels?(this.props.labels.length==0?
<div style={{ margin: "0 auto", fontSize: '60px' ,display: 'flex' ,justifyContent: 'center', alignContent: 'center', alignItems: 'center', height: '100%', color: '#e0ebff'}}>
<div className="row">
<div className="col-12">
<FileAddOutlined style={{ margin: "0 auto", fontSize: '60px' ,display: 'flex' ,justifyContent: 'center', alignContent: 'center', alignItems: 'center', height: '100%', width: '100%' ,color: '#e0ebff'}}/>{"\n"}
</div>
<div className="col-12">
<h3 style={{ margin: "0 auto", fontSize: '20px' ,display: 'flex' ,justifyContent: 'center', alignContent: 'center', alignItems: 'center', height: '100%', width: '100%' ,color: '#e0ebff', marginTop: '20px'}}>Label Not Found</h3>
</div>
</div>
</div>
:
""
):"sd"}
{/* Render All the Labels in the Dialog Box */}
{this.props.labels?this.props.labels.map((data,index)=>{
return(
<div style={{ marginTop: '20px', }} >
<div key={data.name}>
<div className="row">
<div className="col-1" onMouseEnter={()=>this.handleMouseEnter(index)} onMouseLeave={()=>this.handleMouseLeave(index)}>
{this.state.isHovered[index]?
<DeleteFilled style={{ fontSize: 17, color: 'grey', cursor: 'pointer' }} onClick={(e)=>this.handleLabelDelete(data._id)}/>
:
<TagFilled style={{ fontSize: 17, color: 'grey' }}/>
}
</div>
<div className="col-9">
{data.name}
</div>
</div>
</div>
</div>
)
}):
<div>
<FileAddOutlined />
</div>
}
</div>
</DialogContent>
<DialogActions>
<Button onClick={(e)=>{
this.addLabelToggle(false)
}}>Done</Button>
</DialogActions>
</Dialog>
</Layout>
);
}
}
//mapStateToProps
const mapStateToProps = (state) => ({
isLoading: state.labels.isLoading,
user: state.auth.user,
labels: state.labels.labels,
});
export default connect(mapStateToProps, {loadLabels, deleteLabel, logout})(HomePage)
From the error, it is clear that there "IF" condition you have mentioned in the ComponentDidUpdate is calling setState repeatedly. That's why the react framework limits.
Please refer Component Did Update
I find it very hard to change the material-ui Appbar component color on scroll. I keep wondering if there's any functionality like that. I also don't know if the 'useScrollTrigger' can work here. But please help me out if you can.
Here's my code:
import React, {Component} from 'react';
import '../css/Home.css'
import Typography from '#material-ui/core/Typography'
import { withStyles, createStyles } from '#material-ui/core'
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
import Avatar from '#material-ui/core/Avatar';
import Grid from '#material-ui/core/Grid';
import Button from '#material-ui/core/Button';
// import Divider from '#material-ui/core/Divider'
import Slide from '../components/Slider'
import {Link} from 'react-router-dom';
const styles = theme => createStyles({
appbar: {
background: 'transparent',
boxShadow: 'none',
transition: '.5s'
},
avatar: {
width: '70px',
height: '70px',
marginLeft: 100
},
fragment: {
position: 'absolute',
right: '10em'
},
links: {
marginLeft: '40px',
fontFamily: 'Trebuchet MS',
fontWeight: 'bold',
padding: '10px',
borderRadius: '5px',
transition: '.8s'
},
mainGrid: {
marginTop: '150px',
fontFamily: 'Trebuchet MS'
},
grid: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
},
button: {
backgroundImage: 'linear-gradient(to right, rgb(26, 131, 252), rgb(250, 29, 250))',
color: 'white',
transition: '.5s'
},
img: {
width: '90%',
height: '90%'
},
section: {
marginTop: '150px',
padding: '20px',
borderRadius: '40px'
},
showcase: {
[theme.breakpoints.down('sm')]: {
width: '100%',
textAlign: 'center'
},
margin: '40px auto',
marginTop: '40px',
width: '50%',
},
slider: {
backgroundColor: 'rgba(0, 0, 0, 0.671)',
padding: '12px 25px',
borderRadius: '20px'
}
})
class Home extends Component {
render(){
const {classes} = this.props;
return(
<div >
<AppBar id='header' position='fixed' className={classes.appbar} >
<Toolbar>
<Avatar
src='logo.png'
variant='square'
className={classes.avatar}
/>
<div className={classes.fragment} >
<Typography color='primary' className={classes.links} variant='inherit' component={Link} to='about' id='links' >About me</Typography>
<Typography color='primary' className={classes.links} variant='inherit' component={Link} to='/gallery' id='links' >Gallery</Typography>
<Typography color='primary' className={classes.links} variant='inherit' component={Link} to='/contact' id='links' >Contact me</Typography>
<Typography color='primary' className={classes.links} variant='inherit' component={Link} to='/hire' id='links' >Hire me</Typography>
</div>
</Toolbar>
</AppBar>
<Grid className={classes.mainGrid} container >
<Grid item className={classes.grid} xs={12} sm={12} md={6} lg={6} >
<div>
<Typography style={{letterSpacing: '1px'}} variant='body2' color='primary' >HEY THERE !</Typography><br />
<Typography style={{fontWeight: 'bold', fontSize: '30px', letterSpacing: '1px'}} variant='h5' color='primary' >I AM NATHAN BRAIN</Typography><br />
<Typography style={{ fontWeight: 500, fontSize: '15px', letterSpacing: '1px'}} variant='h5' color='primary' >CREATIVE WEB DESIGNER AND DEVELOPER</Typography><br />
<br />
<Button id='button' className={classes.button} >
SEE MY WORKS
</Button>
</div>
</Grid>
<Grid item xs={12} sm={12} md={6} lg={6} >
<img className={classes.img} src='nathan.png' alt='nathan' />
</Grid>
</Grid>
<section className={classes.section} >
<div className={classes.showcase} >
<Typography variant='h4' color='primary' style={{fontWeight: 'bold', marginBottom: '40px', fontFamily: 'Trebuchet MS'}} >SHOWCASE</Typography>
<div className={classes.slider}>
<Slide />
</div>
</div>
</section>
</div>
)
}
}
export default withStyles(styles)(Home);
It's all basic. The AppBar is transparent right now, but I need it to change color right on scroll. I haven't tried doing anything, because I kept serching through the documentation, and I couldn't find anything like that. Help me out if you can. Thanks in advance,
I also don't know if the 'useScrollTrigger' can work here
MUI's useScrollTrigger() can allow you to change many AppBar's settings on scroll. That includes changing the AppBar color on scroll.
You can check out my codesandbox to understand how to use MUI's useScrollTrigger() to achieve this.
Try this using material-ui
<AppBar className={classNames(classes.appBar)}
elevation={trigger ? 24 : 0}
style={{
backgroundColor: trigger ? "#fff" : "transparent",
boxShadow: trigger
? "5px 0px 27px -5px rgba(0, 0, 0, 0.3) !important"
: undefined
}}
>
This is the code tried everything, how do u put a background photo
import React, { Component } from "react";
import Photo from "./Emoticons/A.jpg";
class Contact extends Component {
render() {
return (
<div className="contact" style={{ width: "1200px" }}>
<div className="row ml-5">
{/* Prva */}
<div className="col-sm mt-5">
<div
style={{
boxSizing: "content-box",
boxShadow: "-2px -2px 5px #000000",
height: "400px",
width: "345px"
}}
>
<h2 style={{ textAlign: "center" }}>Info</h2>
</div>
</div>
{/* Druga */}
<div className="col-sm mt-5">
<div
style={{
boxSizing: "content-box",
boxShadow: "-2px -2px 5px #000000",
height: "400px",
width: "345px"
}}
></div>
</div>
{/* Treca */}
<div className="col-sm mt-5">
<div
style={{
boxSizing: "content-box",
boxShadow: "-2px -2px 5px #000000",
height: "400px",
width: "345px"
}}
></div>
</div>
</div>
</div>
);
}
}
export default Contact;
Tried background:'photo', nothing.
You just need to use the javascript equivalent of the CSS properties. For example:
const backgroundPhotoUrl = "..."
<div style={{
backgroundImage: `url(${backgroundPhotoUrl})`,
backgroundPosition: "center center",
backgroundSize: "cover",
}}>
{...}
</div>