This is my site with this issue.
I'm coding a blog in ReactJS. In this article section, I use a mui Tabs and three mui Tabs like this to take apart an article into description, code and others parts. In description and code parts, I use google-code-prettify.
It works when I load the description page but it doesn't work when I click code or others page and then back to the description page.
BasicTabs.js
import React, { useState } from 'react';
import Box from '#mui/material/Box';
import Tab from '#mui/material/Tab';
import Tabs from '#mui/material/Tabs';
import CreateTabPanel from "./TabPanel";
export default function CreateBasicTabs(props) {
const [value, setValue] = useState(0);
const handleChange = (event, newValue) => {
setValue(newValue);
};
function a11yProps(index) {
return {
id: `simple-tab-${index}`,
'aria-controls': `simple-tabpanel-${index}`,
};
}
const boxSx = {
position: 'sticky',
top: props.breadcrumbsHeight + 9.5,
borderBottomLeftRadius: 10,
borderBottomRightRadius: 10,
}
const boxSxForTablet = {
position: 'sticky',
top: props.appBarHeight - 0.5,
borderBottomLeftRadius: 0,
borderBottomRightRadius: 0,
}
return (
<Box sx={{ width: '100%' }}>
<Box
sx={props.isTablet ? boxSxForTablet : boxSx}
className={`pop-up ${props.isScrolling && 'active shadow-active'}`}
>
<Tabs
value={value}
onChange={handleChange}
aria-label="basic tabs example"
sx={{ paddingLeft: 4 }}
>
<Tab label="Detail" {...a11yProps(0)} sx={{ textTransform: 'none' }} />
<Tab label="Code" {...a11yProps(1)} sx={{ textTransform: 'none' }} />
<Tab label="Others" {...a11yProps(2)} sx={{ textTransform: 'none' }} />
</Tabs>
</Box>
<CreateTabPanel value={value} />
</Box >
);
}
TabPanel.js
import React from 'react';
import Box from '#mui/material/Box';
import PropTypes from 'prop-types';
import Typography from '#mui/material/Typography';
import { data } from "../assets/data";
import { useSearchParams } from "react-router-dom";
function getArticleContent() {
const [searchParams] = useSearchParams();
const articleTitle = searchParams.get('title');
for (const item of data) {
if (articleTitle === item.query) {
return item.content;
}
}
}
function TabPanel(tabProps) {
const { children, value, index, ...other } = tabProps;
return (
<div
role="tabpanel"
hidden={value !== index}
id={`simple-tabpanel-${index}`}
aria-labelledby={`simple-tab-${index}`}
style={{
backgroundColor: 'rgb(255, 255, 255)',
borderRadius: 10,
marginLeft: 30,
marginRight: 30,
marginBottom: 30,
}}
{...other}
className='shadow-active'
>
{value === index && (
<Box
sx={{
p: 3,
marginBottom: 10,
}}
>
<Typography>
{children}
</Typography>
</Box>
)}
</div>
);
}
export default function CreateTabPanel(props) {
return (
<>
<TabPanel value={props.value} index={0}>
<div
dangerouslySetInnerHTML={{ __html: getArticleContent() }}
/>
</TabPanel>
<TabPanel value={props.value} index={1}>
<div
dangerouslySetInnerHTML={{ __html: getArticleContent() }}
/>
</TabPanel>
<TabPanel value={props.value} index={2}>
Item Three
</TabPanel>
</>
);
}
CreateTabPanel.propTypes = {
children: PropTypes.node,
index: PropTypes.number.isRequired,
value: PropTypes.number.isRequired,
};
These are screen captures of when it is loaded and when I back to the page.
The second capture looks like blackout but this is because it's css from google-code-prettify works
pre.prettyprint {
border: 0 solid #888;
}
.prettyprint {
background: #000;
}
Could you tell me why it does not work?
Related
I am using React with material-ui. I am using appbar with tabs and I want to be able when I pick some of the tabs the content of the tab to be full width and height.
Here is the sandbox example: https://codesandbox.io/s/vigorous-cookies-4dmf2?file=/src/App.js
As you can see the provided picture the content of the tab does not fill the whole page under the bar. How I can do it to fill it?
If you inspect your marked div in your screenshot. You will find out the padding style is related to MuiTabPanel-root. On Material's official website, they introduced a few ways to override component's styles. Here is one of the ways you can do, to overide component's style by rule names. You can also find each component's rule name under Component API section on their website.
const useStyles = makeStyles({
tabPanelRoot: {
padding: 0
},
});
usage:
export default function App() {
const classes = useStyles();
return(
...
<TabPanel value="1" classes={{ root: classes.tabPanelRoot}}>
...
)
}
See edited code here.
since the parent container is not of full height so, the tanpanel is not of full height. to make the tabpanel of full height pass a class to the root of the tabpanel. Pass the required height to tabpanelRoot class. (here I've neglected the height of the appbar)
export default function App() {
const classes= useStyles()
const [value, setValue] = React.useState("1");
const handleChange = (event, newValue) => {
setValue(newValue);
};
return (
<Box style={{height:'100%', background:'red'}}>
<TabContext value={value}>
<AppBar position="static">
<TabList
variant="scrollable"
onChange={handleChange}
aria-label="simple tabs example"
>
<Tab label="Business Info" value="1" icon={<ContactMailIcon />} />
<Tab label="Financial" value="2" icon={<MonetizationOnIcon />} />
<Tab label="Participants" value="3" icon={<AccessibilityIcon />} />
</TabList>
</AppBar>
<Box style={{height:'100%', background:'red'}}>
<TabPanel value="1" classes={{root:classes.tabpanelRoot}}>
<Box style={{height:'100%', backgroundColor: "red" }}>Content 1</Box>
</TabPanel>
<TabPanel value="2" classes={{root:classes.tabpanelRoot}}>
<Box style={{height:'100%', backgroundColor: "green" }}>Content 2</Box>
</TabPanel>
<TabPanel value="3" classes={{root:classes.tabpanelRoot}}>
<Box style={{height:'100%', backgroundColor: "blue" }}>Content 3</Box>
</TabPanel>
</Box>
</TabContext>
</Box>
);
}
const useStyles = makeStyles((theme) => ({
tabpanelRoot: {
padding:0,
height: `calc(100vh - 52px)`
},
}));
Here is the codesandbox link:- https://codesandbox.io/s/angry-noether-huxvz
Try this
Updated code with useStyle hook.
App.js
import React from "react";
import "./styles.css";
import AppBar from "#material-ui/core/AppBar";
import Tab from "#material-ui/core/Tab";
import TabContext from "#material-ui/lab/TabContext";
import TabList from "#material-ui/lab/TabList";
import TabPanel from "#material-ui/lab/TabPanel";
import Box from "#material-ui/core/Box";
import MonetizationOnIcon from "#material-ui/icons/MonetizationOn";
import ContactMailIcon from "#material-ui/icons/ContactMail";
import AccessibilityIcon from "#material-ui/icons/Accessibility";
import { makeStyles } from "#material-ui/core";
const useStyles = makeStyles({
appContainer: {
display: "flex",
flexDirection: "column",
width: "100vw",
height: "100vh"
},
container: {
display: "flex",
height: "100%",
width: "100%"
},
panel: {
width: "100%"
}
});
export default function App() {
const [value, setValue] = React.useState("1");
const classes = useStyles();
const handleChange = (event, newValue) => {
setValue(newValue);
};
return (
<Box className={classes.appContainer}>
<TabContext value={value}>
<AppBar position="static">
<TabList
variant="scrollable"
onChange={handleChange}
aria-label="simple tabs example"
>
<Tab label="Business Info" value="1" icon={<ContactMailIcon />} />
<Tab label="Financial" value="2" icon={<MonetizationOnIcon />} />
<Tab label="Participants" value="3" icon={<AccessibilityIcon />} />
</TabList>
</AppBar>
<Box className={classes.container}>
<TabPanel value="1" className={classes.panel}>
<Box
className={classes.container}
style={{ backgroundColor: "red" }}
>
Content 1
</Box>
</TabPanel>
<TabPanel value="2" className={classes.panel}>
<Box style={{ backgroundColor: "green" }} className={classes.container} >Content 2</Box>
</TabPanel>
<TabPanel value="3" className={classes.panel}>
<Box className={classes.container} style={{ backgroundColor: "blue" }}>Content 3</Box>
</TabPanel>
</Box>
</TabContext>
</Box>
);
}
Here is the sandbox link - https://codesandbox.io/s/shy-voice-nih2s
import * as React from 'react';
import Box from '#mui/material/Box';
import Tab from '#mui/material/Tab';
import TabContext from '#mui/lab/TabContext';
import TabList from '#mui/lab/TabList';
import TabPanel from '#mui/lab/TabPanel';
export default function LabTabs() {
const [value, setValue] = React.useState('1');
const handleChange = (event, newValue) => {
setValue(newValue);
};
return (
<Box sx={{ width: '100%', typography: 'body1' }}>
<TabContext value={value}>
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
<TabList onChange={handleChange} aria-label="lab API tabs example">
<Tab label="Item One" value="1" />
<Tab label="Item Two" value="2" />
<Tab label="Item Three" value="3" />
</TabList>
</Box>
<TabPanel sx={{pl: 1,pt:1}} value="1">Item One</TabPanel>
<TabPanel sx={{pl: 1,pt:1}} value="2">Item Two</TabPanel>
<TabPanel sx={{pl: 1,pt:1}} value="3">Item Three</TabPanel>
</TabContext>
</Box>
);
}
Tabs Height can be changed by .MuiTabs-root
const AntTab = styled((props: StyledTabProps) => (
<Tab disableRipple {...props} />
))(() => ({
**minHeight: '33px',
maxHeight: '33px',**
color: '#718296',
fontFamily: 'Montserrat',
}))
I'm trying to design a UI that looks like this
So far what I have is this
The problem I'm having is getting the info icon to show up where it's supposed to be and getting the direct text and create icon on the top left corner. I also can't have the primary and general show up in my UI like Instagrams and the scrollbar on my drawer goes all the way up instead of stopping where the appbar is.
Here's my code
import React from "react";
import { makeStyles, withStyles } from "#material-ui/core/styles";
import Drawer from "#material-ui/core/Drawer";
import AppBar from "#material-ui/core/AppBar";
import Toolbar from "#material-ui/core/Toolbar";
import List from "#material-ui/core/List";
import Typography from "#material-ui/core/Typography";
import Divider from "#material-ui/core/Divider";
import ListItem from "#material-ui/core/ListItem";
import ListItemText from "#material-ui/core/ListItemText";
import Avatar from "#material-ui/core/Avatar";
import PersonIcon from "#material-ui/icons/Person";
import Badge from "#material-ui/core/Badge";
import InfoIcon from "#material-ui/icons/Info";
import ListItemAvatar from "#material-ui/core/ListItemAvatar";
import { connect } from "react-redux";
function mapStateToProps(state) {
return {};
}
const drawerWidth = 240;
const useStyles = makeStyles((theme) => ({
root: {
display: "flex",
},
appBar: {
width: `calc(100% - ${drawerWidth}px)`,
backgroundColor: "#fff",
},
drawer: {
width: drawerWidth,
flexShrink: 0,
},
drawerPaper: {
width: drawerWidth,
},
// necessary for content to be below app bar
toolbar: theme.mixins.toolbar,
content: {
flexGrow: 1,
backgroundColor: theme.palette.background.default,
padding: theme.spacing(3),
},
}));
const SmallAvatar = withStyles((theme) => ({
root: {
width: 11,
height: 11,
color: "green",
backgroundColor: "green",
},
}))(Avatar);
const Messaging = () => {
const classes = useStyles();
const dummy = "Active now";
return (
<div className={classes.root}>
<AppBar position='fixed' className={classes.appBar}>
<Toolbar style={{ width: "100%" }}>
<Avatar>
<PersonIcon />
</Avatar>
<Typography variant='h6'>adib.akm</Typography>
<InfoIcon />
</Toolbar>
</AppBar>
<Drawer
className={classes.drawer}
variant='permanent'
classes={{
paper: classes.drawerPaper,
}}
anchor='left'>
<div className={classes.toolbar} />
<Divider />
<List>
<ListItem>
<ListItemAvatar>
<Badge
overlap='circle'
anchorOrigin={{
vertical: "bottom",
horizontal: "right",
}}
badgeContent={<SmallAvatar />}>
<Avatar>
<PersonIcon />
</Avatar>
</Badge>
</ListItemAvatar>
<ListItemText primary='Photos' secondary={dummy} />
</ListItem>
<ListItem>
<ListItemAvatar>
<Badge
overlap='circle'
anchorOrigin={{
vertical: "bottom",
horizontal: "right",
}}
badgeContent={<SmallAvatar />}>
<Avatar>
<PersonIcon />
</Avatar>
</Badge>
</ListItemAvatar>
<ListItemText primary='Work' secondary={dummy} />
</ListItem>
<ListItem>
<ListItemAvatar>
<Badge
overlap='circle'
anchorOrigin={{
vertical: "bottom",
horizontal: "right",
}}
badgeContent={<SmallAvatar />}>
<Avatar>
<PersonIcon />
</Avatar>
</Badge>
</ListItemAvatar>
<ListItemText primary='Vacation' secondary={dummy} />
</ListItem>
</List>
</Drawer>
</div>
);
};
export default connect(mapStateToProps)(Messaging);
This is the codesandbox https://codesandbox.io/s/mutable-monad-dsvf8?file=/src/index.js
So I try the following code to convert a functional component to the classical component, it kinda worked, no error but styles are not applied.
import { makeStyles } from '#material-ui/core/styles';
import { withStyles } from '#material-ui/core/styles';
const playtheMusic = () => {
pauseMusic();
};
const pausetheMusic = () => {
pauseMusic();
};
const useStyles = makeStyles(theme => ({
text: {
padding: 50
},
paper: {
paddingBottom: 50
},
list: {
marginBottom: theme.spacing(2)
},
subheader: {
backgroundColor: theme.palette.background.paper
},
appBar: {
top: 'auto',
bottom: 0,
backgroundColor: '#282828',
padding: '15px'
},
grow: {
flexGrow: 1
}
}));
class BottomAppBar extends React.Component {
// const classes = useStyles();
render() {
const { classes } = this.props;
return (
<div>
<AppBar position="fixed" className={classes.appBar}>
<div style={{ display: 'flex', alignItems: 'center', alignContent: 'center' }}>
<div>
<Typography style={{ fontSize: 15 }}> Stress Out </Typography>
<br />
<Typography style={{ fontSize: 12, color: '#B3B3B3' }}>
Twenty One Pilots
</Typography>
</div>
<div className={classes.grow} />
<div>
<IconButton style={{ color: 'white' }}>
<ShuffleIcon />
</IconButton>
<IconButton style={{ color: 'white' }}>
<SkipPreviousRoundedIcon style={{ fontSize: 30 }} />
</IconButton>
<IconButton onClick={pausetheMusic} style={{ color: 'white' }}>
<PauseCircleOutlineRoundedIcon style={{ fontSize: 46 }} />
<PlayCircleOutlineIcon style={{ fontSize: 46, display: 'none' }} />
</IconButton>
<IconButton style={{ color: 'white' }}>
<SkipNextRoundedIcon style={{ fontSize: 30 }} />
</IconButton>
<IconButton style={{ color: 'white' }}>
<RepeatIcon />
</IconButton>
</div>
<div className={classes.grow} />
<div>
<IconButton style={{ color: 'white' }}>
<VolumeUpIcon />
</IconButton>
</div>
</div>
</AppBar>
</div>
);
}
}
export default withStyles(useStyles)(BottomAppBar);
also, there is a problem with StackOverflow. it says "It looks like your post is mostly code; please add some more details". that's the reason I'm writing some unnecessary things XD
you can skip it.
Thanks for reading. have a good day <3
A common approach for material-ui component styling:
Classical
withStyles (High order function) + createStyles
Functional
useStyles (hooks) + makeStyles
In your code, you shall not use the hooks useStyles inside withStyle, hooks shouldn't be used inside any classical component,
Wrong here
export default withStyles(useStyles)(BottomAppBar);
Right example
import { withStyles, createStyles } from "#material-ui/core/styles";
const styles = theme => createStyles({
root: {
},
// ...
});
...
const { classes } = this.props;
...
export default withStyles(styles)(App);
Online sample for both classical component and functional component styling
I am putting together a component for my Goal Sharing social media app. This is what I have so far:
I'm trying to position the Avatar component as well as the two typography components beneath the Avatar component within the center of the left section of this Paper component. I have tried doing this by altering marginLeft and marginTop as you can see in the code below, but the issue when I do this is the components in this Goal component jumble on top of each other when I switch over to smaller devices. So, what's the best way to position these components in the center of the left section, and to ensure they remain that way on smaller devices?
This is the parent component file:
import React, { useEffect } from "react";
import Moment from "react-moment";
import PropTypes from "prop-types";
import { Link } from "react-router-dom";
import { connect } from "react-redux";
import { getGoals } from "../../actions/goal";
import Spinner from "../layout/Spinner";
import Navbar from "../dashboard/Navbar";
import ThumbUpAltIcon from "#material-ui/icons/ThumbUpAlt";
import ThumbDownAltIcon from "#material-ui/icons/ThumbDownAlt";
import ChatIcon from "#material-ui/icons/Chat";
import DeleteIcon from "#material-ui/icons/Delete";
import DoneIcon from "#material-ui/icons/Done";
import {
Typography,
Container,
CssBaseline,
makeStyles,
Grid,
Card,
Avatar,
CardContent,
CardActions
} from "#material-ui/core";
const useStyles = makeStyles(theme => ({
paper: {
marginTop: theme.spacing(8),
display: "flex",
flexDirection: "column",
alignItems: "center"
},
submit: {
margin: theme.spacing(2, 0, 2)
},
form: {
marginTop: theme.spacing(5)
},
cardGrid: {
paddingTop: theme.spacing(4),
paddingBottom: theme.spacing(4)
},
card: {
height: "100%",
display: "flex",
flexDirection: "column",
alignItems: "center"
},
cardContent: {
flexGrow: 1
},
profileHeader: {
textAlign: "center",
marginBottom: 10
},
avatar: {
width: theme.spacing(10),
height: theme.spacing(10),
marginLeft: "2.5vw",
marginTop: "5vh"
},
name: {
textAlign: "center",
marginLeft: "2vw"
},
goalText: {
marginTop: "5vh",
marginLeft: "3vw"
},
postedOn: {
marginLeft: "2vw"
}
}));
const Goals = ({ getGoals, auth, goal: { goals, user, loading } }) => {
useEffect(() => {
getGoals();
}, [getGoals]);
const classes = useStyles();
return loading ? (
<>
<Navbar />
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Spinner />
</div>
</Container>
</>
) : (
<>
<CssBaseline />
<Navbar />
<main>
<Container className={classes.cardGrid} maxWidth="md">
<Typography variant="h2" className={classes.profileHeader}>
Goals
</Typography>
<Grid container spacing={4}>
{goals.map(singleGoal => (
<Grid item key={singleGoal._id} xs={12}>
<Card fullwidth="true" className={classes.card}>
<Grid container spacing={2}>
<Grid item>
<Avatar
className={classes.avatar}
src={singleGoal.avatar}
/>
<Typography variant="subtitle2" className={classes.name}>
{singleGoal.first_name} {singleGoal.last_name}
</Typography>
<Typography
variant="caption"
className={classes.postedOn}
>
Posted on{" "}
<Moment format="MM/DD/YYYY">{singleGoal.date}</Moment>
</Typography>
</Grid>
<Grid item xs={12} sm container>
<Grid item xs container direction="column" spacing={2}>
<Grid item xs>
<Typography
className={classes.goalText}
variant="body1"
gutterBottom
>
{singleGoal.text}
</Typography>
<Typography variant="h5"></Typography>
</Grid>
</Grid>
</Grid>
</Grid>
<CardContent className={classes.cardContent}></CardContent>
<CardActions>
<ThumbUpAltIcon />
<Typography variant="caption">
{singleGoal.likes.length}
</Typography>
<ThumbDownAltIcon />
<Link to={`/goal/${singleGoal.user}`}>
<ChatIcon />
</Link>
<Typography variant="caption">
{singleGoal.comments.length}
</Typography>
{!auth.loading && singleGoal.user === auth.user._id && (
<DoneIcon />
)}
{!auth.loading && singleGoal.user === auth.user._id && (
<DeleteIcon />
)}
</CardActions>
</Card>
</Grid>
))}
</Grid>
</Container>
</main>
</>
);
};
Goals.propTypes = {
getGoals: PropTypes.func.isRequired,
goal: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
goal: state.goal,
auth: state.auth
});
export default connect(mapStateToProps, { getGoals })(Goals);
Try this
card: {
height: "100%",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center"
},
I recently learn react native, but i got problem with input text. When i try to type 1st text field the 2nd text field cannot get focus, when i tap 2nd text field two times text field focus correctly
See video below : https://streamable.com/70njw
My code :
import React, { Component, Fragment } from 'react'
import { View, StyleSheet } from 'react-native'
import { Text, Button, Content, Card, CardItem, Body, Input, Icon, Item} from 'native-base'
import { Grid, Row } from 'react-native-easy-grid'
import ThemeVariable from '../../../native-base-theme/variables/platform'
import AuthHeaderNavigation from '../../components/auth/HeaderNavigation'
class LoginScreen extends Component {
state = {
input: {
email: null,
password: null
}
}
setInputState(key, value) {
this.setState(prevState => ({
input: {
...prevState.input,
[key]: [value]
}
}))
}
render() {
return (
<Fragment>
<AuthHeaderNavigation/>
<Grid>
<Row style={styles.firstRow}></Row>
<View style={styles.authWrapper}>
<Card style={styles.authCard}>
<CardItem>
<Body>
<Item>
<Icon style={{ color: ThemeVariable.footerDefaultBg }} name="person"/>
<Input onChangeText={text => this.setInputState('email', text)} placeholder="Email"/>
</Item>
</Body>
</CardItem>
<CardItem style={{ paddingTop: 0}}>
<Body>
<Item last>
<Icon style={{ color: ThemeVariable.footerDefaultBg }} name="lock"/>
<Input onChangeText={text => this.setInputState('password', text)}
secureTextEntry={true}
placeholder="Password"/>
</Item>
</Body>
</CardItem>
<CardItem>
<Body>
<Button block>
<Text> Login </Text>
</Button>
</Body>
</CardItem>
</Card>
</View>
<Row style={styles.secondRow}></Row>
</Grid>
</Fragment>
)
}
}
const styles = StyleSheet.create({
content: {
height: '100%'
},
firstRow: {
backgroundColor: ThemeVariable.footerDefaultBg
},
secondRow: {
backgroundColor: ThemeVariable.contentBaseBgColor
},
authWrapper: {
position: 'absolute',
width: '100%',
height: '100%',
flex: 1,
alignItems: 'center',
justifyContent: 'center',
flexDirection:'row',
},
authCard: {
width: '90%',
borderRadius: 6,
padding: 5,
}
})
export default LoginScreen
If i change View to ScrollView everything works correctly, but may broken page design