justifyContent with createStyles in TypeScript - javascript

I have a toolbar where I am using 2 icons that appear on the left end. Currently, I am using this styling method:
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
display: 'flex',
},
appBar: {
width: `calc(100% - ${drawerWidth}px)`,
marginLeft: drawerWidth,
},
drawer: {
width: drawerWidth,
flexShrink: 0,
},
drawerPaper: {
width: drawerWidth,
},
panelheaderRight: {
marginRight: 0,
right: 0,
},
toolbar: theme.mixins.toolbar,
content: {
flexGrow: 1,
// justifyContent: spaceBetween,
backgroundColor: theme.palette.background.default,
padding: theme.spacing(3),
},
}),
);
I want the icons to appear on the right end. If I add a separate css file with this, it works:
.toolbar-class{
justify-content:space-between;
}
but I want to use it inside the createStyles. There's no 'space-between' option in createStyles. This is how a portion of my component looks like:
<AppBar position="fixed" className={classes.appBar}>
<Toolbar className="toolbar-class">
<Typography variant="h6" noWrap>
Al
</Typography>
<div className="panelheaderRight">
<NotificationsIcon />
{/* <ExitToAppIcon onClick={() =>
<ExitToAppIcon onClick={logout}></ExitToAppIcon>
</div>
</Toolbar>
</AppBar>
Is there any way I can move the icons to the left using createStylesand without adding a separate css file?

Some notice points:
Change justify-content to justifyContent, and value as string.
No need to use createStyels for makeStyles
const useStyles = makeStyles((theme: Theme) => ({
toolBar: {
justifyContent: 'space-between'
},
...
...
<Toolbar className={classes.toolBar}>

Related

Required Details not showing

I am trying to display a large version of my post in the postDetail.jsx file but it shows blank when i Open it on my web browser. the application is being fetched properly as shown on my network tab in developer option and no form of error is printed on the console.
import React, { useEffect } from 'react';
import { Paper, Typography, CircularProgress, Divider } from '#material-ui/core/';
import { useDispatch, useSelector } from 'react-redux';
import moment from 'moment'; //js library for time
import { useParams, useHistory } from 'react-router-dom';
import { getPost } from '../../actions/posts';
import useStyles from './styles'
const PostDetails = () => {
const { post, posts, isLoading } = useSelector((state) => state.posts);
const dispatch = useDispatch();
const history = useHistory();
const classes = useStyles();
const { id } = useParams();
useEffect(() => {
dispatch(getPost(id));
}, [id]);
if(!post) return null;
//if this return this else return jsx
if(isLoading) {
return (
<Paper elevation={6} className={classes.loadingPaper}>
<CircularProgress size="7em" />
</Paper>
);
}
return (
<Paper style={{ padding: '20px', borderRadius: '15px' }} elevation={6}>
<div className= {classes.card}>
<div className={classes.section}>
<Typography variant="h3" component="h2">{post.title}</Typography>
<Typography gutterBottom variant="h6" color="textSecondary" component="h2">{ post.tags }</Typography>
<Typography gutterBottom variant="body 1" component="p"> {post.message} </Typography>
<Typography variant="h6"> Created by:{post.name} </Typography>
<Typography variant="body 1">{moment(post.createdAt).fromNow()}</Typography>
<Divider style={{ margin: "20px 0" }} />
<Typography variant="body1"><strong>Realtime Chat - coming soon !</strong></Typography>
<Divider style={{ margin: '20px 0px'}}/>
<Typography variant="body 1"><strong>Comments - coming soon !</strong></Typography>
<Divider style={{ margin: '20px 0px' }}/>
</div>
<div className={ classes.imageSection }>
<img className={ classes.media } src={post.selectedFile} alt={post.title} />
</div>
</div>
</Paper>
)
}
export default PostDetails;
This is the styles used for the code.. I used Material-Ui
import { makeStyles } from '#material-ui/core/styles';
export default makeStyles((theme) => ({
media: {
borderRadius: '20px',
objectFit: 'cover',
width: '100%',
maxHeight: '600px',
},
card: {
display: 'flex',
width: '100%',
[theme.breakpoints.down('sm')]: {
flexWrap: 'wrap',
flexDirection: 'column',
},
},
section: {
borderRadius: '20px',
margin: '10px',
flex: 1,
},
imageSection: {
marginLeft: '20px',
[theme.breakpoints.down('sm')]: {
marginLeft: 0,
},
},
recommendedPosts: {
display: 'flex',
[theme.breakpoints.down('sm')]: {
flexDirection: 'column',
},
},
loadingPaper: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
padding: '20px',
borderRadius: '15px',
height: '39vh',
},
commentsOuterContainer: {
display: 'flex',
justifyContent: 'space-between',
},
commentsInnerContainer: {
height: '200px',
overflowY: 'auto',
marginRight: '30px',
},
}));
Original image Containing the post before a specific id is clicked
[Image of the postDetails when clicked on the original post which contains the specific id i.e /posts/:1d]

Styling TextField in DesktopDatePicker Material UI

Self-taught dev here.
I am trying to style a textfield rendered by a DesktopDatePicker in a react application. I can change the width using MakeStyles, but can't seem to change the height of the box, or the font of the input text. My code is as follows:
const useStyles = makeStyles(() => ({
textField: {
width: "90%",
height: "75%",
marginLeft: "auto",
marginRight: "auto",
paddingBottom: 0,
marginTop: 0,
},
input: {
height: "70%",
fontSize: "small",
}
}));
const classes = useStyles();
return (
<div >
<LocalizationProvider dateAdapter={AdapterDateFns}>
<DesktopDatePicker
inputFormat="MM/dd/yyyy"
selected={new Date(initialVal)}
size="small"
onChange={(newDate) => {
setDateBirth(newDate);
setFieldValue("dateBirth", newDate);
}}
renderInput={(params) => <TextField
className={classes.textField}
sx={{ color: 'red', display: 'inline', fontSize: 8, height: "75%" }}
variant='outlined'
size="small"
InputProps={{
className: classes.input,
}}
{...params} />}
/>
</LocalizationProvider>
</div>
)
}
This renders the following:
MUI styling
The only thing I have been able to do to change the box size is the inline size="small" property. Thanks in advance.

Is there a better way to change style based on screen size on react app?

Im using Material UI on my react app and I'm using useMediaQuery and useTheme from mui. This is the code I have right now. Is there a better way to optimize less code? There are only a few style changes between the 2 codes.
const MainPage = () => {
const theme = useTheme();
const isMatch = useMediaQuery(theme.breakpoints.down('md'))
return (
<div className='mainPage'>
{
isMatch ? (
<>
<Box sx={{ display: "flex", justifyContent: "center", alignContent: "center", flexDirection: "column", padding: "60px 10px 10px 10px" }}>
<Box component="img" src={LandingImage} sx={{ width: "100%" }} />
<Box sx={{ paddingTop: 8 }}>
<Typography sx={{ fontSize: 26, fontWeight: "bold", fontFamily: "sans-serif", textAlign: "center", paddingBottom: 5 }}>About us</Typography>
</Box>
</Box>
</>
) : (
<>
<Box sx={{ display: "flex", justifyContent: "center", alignContent: "center", flexDirection: "row", paddingTop: 20 }}>
<Box component="img" src={LandingImage} />
<Box sx={{ width: 700, paddingTop: 8 }}>
<Typography sx={{ fontSize: 30, fontWeight: "bold", fontFamily: "sans-serif", textAlign: "center", paddingBottom: 5 }}>About us</Typography>
</Box>
</Box>
</>
)}
</div>
)
}
There really is no need to do a media query like this, as the sx prop provides per-breakpoint customization if you want it.
Notice, for example, the flexDirection styling on the first Box component. Everything up to the md breakpoint gets column, then it becomes row.
const MainPage = () => {
const theme = useTheme();
return (
<div className='mainPage'>
<Box sx={{
display: "flex",
justifyContent: "center",
alignContent: "center",
flexDirection: { xs: "column", md: "row" },
padding: { xs: "60px 10px 10px 10px", md: "20px 0 0 0" }
}}>
<Box
component="img"
src={LandingImage}
sx={{
width: { xs: "100%", md: 'unset' }
}}/>
<Box sx={{
paddingTop: 8,
width: { md: 700 }
}}>
<Typography
sx={{
fontSize: { xs: 26, md: 30 },
fontWeight: "bold",
fontFamily: "sans-serif",
textAlign: "center",
paddingBottom: 5
}}>
About us
</Typography>
</Box>
</Box>
</div>
)
}
https://mui.com/system/basics/#responsive-values
As the structure of JSX for mobile / desktop is the same, you could drop one of those two JSX templates, build a variable to store component configuration based on isMatch and pass this variable into component template.
const MainPage = () => {
const theme = useTheme();
const isMatch = useMediaQuery(theme.breakpoints.down('md'))
// Subset of props, to illustrate the idea.
const config = isMatch ? {fontSize: 26} : {fontSize: 30};
// Here only root <Box/> is configured, but you can configure all the nested components the same way.
return (
<div className='mainPage'>
<Box sx={config}>[...]</Box>
</div>
)
}
(Same with components nested inside <Box/> - the idea is the same - declare some variables with value based on your state and pass them to JSX declaration)
There are several options. The first is to create a style object in javascript, which can be interacted with like normal javascript. You are already doing this in-line, but if we do it in the code above, we can make it dynamic.
const myOuterBoxStyle = {
display: "flex",
justifyContent: "center",
alignContent: "center",
flexDirection: "row",
paddingTop: 20
}
if (isMatch) {
myOuterBoxStyle.flexDirection = "column";
myOuterBoxStyle.paddingTop = undefined;
myOuterBoxStyle.padding = "60px 10px 10px 10px";
}
Once you do all of the dynamic styling you need, you can make a single return for your component and simply put
<Box sx={{myOuterBoxStyle}}>
The other option is to make a seperate CSS sheet and import it, and then use classes. Something like
.outer-box {
display: "flex";
justify-content: "center";
align-content: "center";
}
.is-match {
flex-direction: "column";
padding: "60px 10px 10px 10px"
}
And then you can either add the is-match class or, perhaps, the is-not-match class depending.
The final option is to use a third-party package that does most of this for you, like Tailwind
Mui has breakpoints shorthand syntax, as you can check here.
So, for example, your code will also work with:
const MainPage = () => {
return (
<div className="mainPage">
<Box
sx={{
display: "flex",
justifyContent: "center",
alignContent: "center",
flexDirection: ["column", "column", "row"],
paddingTop: ["60px 10px 10px 10px", "60px 10px 10px 10px", 20]
}}
>
<Box component="img" />
<Box sx={{ width: ["unset", "unset", 700], paddingTop: 8 }}>
<Typography
sx={{
fontSize: [26, 26, 30],
fontWeight: "bold",
fontFamily: "sans-serif",
textAlign: "center",
paddingBottom: 5
}}
>
About us
</Typography>
</Box>
</Box>
</div>
);
};
In the example above i use the Breakpoints as an array and mui docs says:
The second option is to define your breakpoints as an array, from the smallest to the largest breakpoint.
So imagine that array positions would be: [xs, sm, md, lg, xl] and the breakpoints are equivalent to theme.breakpoints.up.
Another way to do it is use Breakpoints as an object:
Simple example
<Box
sx={{
width: {
xs: 100, // theme.breakpoints.up('xs')
sm: 200, // theme.breakpoints.up('sm')
md: 300, // theme.breakpoints.up('md')
lg: 400, // theme.breakpoints.up('lg')
xl: 500, // theme.breakpoints.up('xl')
},
}}
>

Position Material-UI Drawer component under Appbar

I'm creating a single-page application (Material-UI based) with an AppBar (+ ToolBar) and a Drawer. At the moment, the Drawer overlaps the AppBar and under no circumstances can I get the Drawer to move down, so it is basically positioned right under the AppBar.
I tried adding some padding, but this does not do anything. I'm using makeStyles for styling of most of the components, and I am wondering if it is even possible to position the Drawer below the AppBar.
Is there any way to position the drawer below the AppBar?
I have a lot of code, but the makeStyle function is simple:
const useStyles = makeStyles((theme) => ({
root: {
display: 'flex',
},
appBar: {
zIndex: theme.zIndex.drawer + 1,
},
title: {
flexGrow: 1,
},
toolbar: {
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-end',
padding: theme.spacing(0, 1),
...theme.mixins.toolbar,
},
content: {
flexGrow: 1,
padding: theme.spacing(3),
},
drawer: {
paddingTop: 30
},
}));
and the main component (that includes the Drawer:
<div className={classes.root}>
<AppBar position="absolute" >
<Toolbar>
<Typography component="h1" variant="h6" noWrap className={classes.title}>
x
</Typography>
<Switch checked={isDarkTheme} onChange={handleThemeSwitch}/>
<WbIncandescentIcon />
</Toolbar>
</AppBar>
<ServiceDrawer className={classes.drawer}
onOperationSelected={onOperationSelect} serviceList={services} onDrawerOpen={onDrawerOpen} onDrawerClose={onDrawerClose}>
</ServiceDrawer>
<main className={classes.content}>
<div className={classes.toolbar} />
{selectedOperation && <Operation operation={selectedOperation}/>}
</main>
</div>
You need to set the variant of the Drawer to permanent so that it does not create an overlay over the current page, and put it inside the current app layout. Because the Drawer position is fixed, you also have to set the AppBar to fixed so they're on the same stacking context, and the z-index will be applied correctly, to put it in code:
<Drawer variant="permanent"
<AppBar position="fixed"
And finally the zIndex itself
appBar: {
zIndex: theme.zIndex.drawer + 1
},
Reference
https://v4.mui.com/components/drawers/#clipped-under-the-app-bar

Why would material-ui's AppBar just break its own css on a few page reloads?

I'll show you exactly what I mean here. (it's a short video demonstrating exactly how this problem is reproduced and the missing css elements)
I also have screenshots of before:
and after:
Via inspect element it's clear that important css elements just straight up disappear, and it doesn't make any sense why that would happen specifically after clicking on a link, coming back, and refreshing.
Has anyone run into a similar problem with material-ui before or think you might know why the css is breaking?
EDIT: console is logging errors only when the search bar is in the wacky position as such:
unfortunately, I'm still not quite sure what to make of it.
I'll also include my appbar component which uses #material-ui/core/styles' makeStyles CSS rendering. If you want the entire repository to play around with I can make it available as well.
import React from 'react';
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
import IconButton from '#material-ui/core/IconButton';
import Typography from '#material-ui/core/Typography';
import InputBase from '#material-ui/core/InputBase';
import { fade } from '#material-ui/core/styles/colorManipulator';
import { makeStyles } from '#material-ui/core/styles';
import MenuIcon from '#material-ui/icons/Menu';
import SearchIcon from '#material-ui/icons/Search';
import {connectSearchBox} from 'react-instantsearch-dom';
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1,
},
menuButton: {
marginRight: theme.spacing(2),
},
title: {
flexGrow: 1,
display: 'none',
[theme.breakpoints.up('sm')]: {
display: 'block',
},
},
search: {
position: 'relative',
borderRadius: theme.shape.borderRadius,
backgroundColor: fade(theme.palette.common.white, 0.15),
'&:hover': {
backgroundColor: fade(theme.palette.common.white, 0.25),
},
marginLeft: 0,
width: '100%',
[theme.breakpoints.up('sm')]: {
marginLeft: theme.spacing(1),
width: 'auto',
},
},
searchIcon: {
width: theme.spacing(7),
height: '100%',
position: 'absolute',
pointerEvents: 'none',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
inputRoot: {
color: 'inherit',
},
inputInput: {
padding: theme.spacing(1, 1, 1, 7),
transition: theme.transitions.create('width'),
width: '100%',
[theme.breakpoints.up('sm')]: {
width: 300,
'&:focus': {
width: 400,
},
},
}
}));
function SearchBox({currentRefinement, refine}){
const classes = useStyles();
return(
<InputBase
type="search"
value={currentRefinement}
onChange={event => refine(event.currentTarget.value)}
placeholder="Search by state, park name, keywords..."
classes = {{
root: classes.inputRoot,
input: classes.inputInput,
}}
/>
)
}
const CustomSearchBox = connectSearchBox(SearchBox);
function SearchAppBar() {
const classes = useStyles();
return (
<div className={classes.root}>
<AppBar position="static" color="primary">
<Toolbar>
<IconButton
edge="start"
className={classes.menuButton}
color="inherit"
aria-label="Open drawer"
>
<MenuIcon />
</IconButton>
<Typography className={classes.title} variant="h6" noWrap>
Title
</Typography>
<div className={classes.search}>
<div className={classes.searchIcon}>
<SearchIcon />
</div>
<CustomSearchBox/>
</div>
</Toolbar>
</AppBar>
</div>
);
}
export default SearchAppBar;

Categories