I am a newbie in MUI, now my icon and text are not aligned:
My desired results:
My code is:
<div style={{
display: 'inline-flex',
VerticalAlign: 'text-bottom',
BoxSizing: 'inherit',
textAlign: 'center',
AlignItems: 'center'
}}>
<LinkIcon className={classes.linkIcon} />
revolve
</div>
I tried grid and row, but not work. Can anyone help me?
This works perfectly!
<div style={{
display: 'flex',
alignItems: 'center',
flexWrap: 'wrap',
}}>
<LinkIcon />
<span>revolve</span>
</div>
You need to use Grid.
Something like that should works:
<Grid container direction="row" alignItems="center">
<Grid item>
<LinkIcon className={classes.linkIcon} />
</Grid>
<Grid item>
revolve
</Grid>
</Grid>
This can be easily achieved in MUI v5 by using a Stack and set alignItems prop to center:
import Stack from '#mui/material/Stack';
import Typography from '#mui/material/Typography';
import AddCircleIcon from '#mui/icons-material/AddCircle';
<Stack direction="row" alignItems="center" gap={1}>
<AddCircleIcon />
<Typography variant="body1">text</Typography>
</Stack>
Try the below code. You can use variant as per your requirement.
const useStyles = makeStyles(theme => ({
wrapIcon: {
verticalAlign: 'middle',
display: 'inline-flex'
}
}));
<Typography variant="subtitle1" className={classes.wrapIcon}>
<LinkIcon className={classes.linkIcon} /> revolve
</Typography>
alternative simple solution
<Grid container direction="row" alignItems="center">
<SearchIcon /> example
</Grid>
styles
const styles = theme => ({
icon: {
position: "relative",
top: theme.spacing.unit,
width: theme.typography.display1.fontSize,
height: theme.typography.display1.fontSize
}
});
JSX
<Typography variant="display1">
<Icon className={this.props.classes.icon}/>Your Text
</Typography>
you could replace display1 with display3 or another typography variant in all 3 places to choose your text size. The ensures that your text doesn't break between words when it wraps.
For me this can render to look like this
with display3 and a few other styles added for color.
Having ListItemIcon and ListItemText wrapped inside a ListItem will keep it in one line and prevent breaking:
import ListItem from '#material-ui/core/ListItem';
import ListItemIcon from '#material-ui/core/ListItemIcon';
import ListItemText from '#material-ui/core/ListItemText';
<ListItem >
<ListItemIcon><AccessAlarmIcon color="secondary" /></ListItemIcon>
<ListItemText>Updated 1 hour ago</ListItemText>
</ListItem>
Demo image:
You can also use Material UI's Flexbox component.
For example:
// ...
import { Box } from '#material-ui/core';
// ...
<Box alignItems="center" display="flex">
<Box>
<LinkIcon className={classes.linkIcon} />
</Box>
<Box>
revolve
</Box>
</Box>
The alignItems: center attribute will vertically align the inner items.
This will add some additional markup. However, if you look at the component's API there's a lot of additional flexibility. Such as
for example a method to use margin or padding that's consistent with the rest of your Material UI implementation. Also it's really easy to align the items differently if the use-case should occur.
You can import these on top
import { Grid, Typography } from "#material-ui/core";
import LinkIcon from "#material-ui/icons/Link";
You can use
<Grid style={{ display: "flex" }}>
<LinkIcon />
<Typography>Revolve</Typography>
</Grid>
Sample Sandbox Example Here
If you are trying to vertical align text and icon within MUI's Typography without using variant, you can simply add a display setting to Typography as follows:
<Typography display="flex">
Welcome!
<Icon />
</Typography>
This is what worked for me.
Same problem here, this is what I did.
import LinkIcon from '#material-ui/icons/Link';
import styled from 'styled-components';
...
const Resolve = styled.div`
display: flex;
vertical-align: middle,
`;
<Resolve>
<LinkIcon style={{ marginRight: '5px' }} />
<p>resolve</p>
</Resolve>
If you aren't happy with mUI default link icon you can always DIY:
{/* this is the same chained icon used in the own material-ui,
idk why this ins't avaiable yet */}
function CustomLinkIcon(props) {
return (
<SvgIcon {...props}>
<path d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z" />
</SvgIcon>
);
}
...
<Resolve>
<CustomLinkIcon
{/* adjust margin top if needed */}
style={{ marginRight: '3px', marginTop: '3px' }} {
/>
<p>resolve</p>
</Resolve>
the best option is to use it like that :
import {Box, Typography} from '#material-ui/core'
import LinkIcon from '#material-ui/icons/LinkIcon';
........
<Box display='flex' alignItems='center'>
<LinkIcon className={classes.linkIcon} />
<Typography variant='h5'>
resolve
</Typography>
</Box>
With this solution the icon will inherit your typography, it prevents having to re-write the style when changin
<Typography component={Stack} direction="row" alignItems="center" color="secondary">
<EditIcon fontSize="inherit" sx={{ marginRight: 1 }} />
Edit
</Typography>
We can use Typography to make align horizontal spacing with icon
const styles = theme => ({
icon: {
fontSize: '1rem',
position: 'relative',
right: theme.spacing(0.5),
top: theme.spacing(0.5),
},
});
<Typography><CheckCircleIcon className={className={this.props.classes.icon}}/>Home</Typography>
I have seen all the solutions. But here is the simplest I believe :-):
<Typography><LinkIcon sx={{verticalAlign:"middle"}}/> RESOLVE</Topography>
It also works with inline image when you want the image align with the text.
Related
I'm trying to style a TextField component in a one-off fashion using the sx prop:
<TextField
size="small"
sx={{
padding: '1px 3px',
fontSize: '0.875rem',
lineHeight: '1.25rem',
}}
{...params}
/>
I'm using MUI v5. If I inspect the input element, the styles are not applied. What am I missing?
UPDATE: it seems the styles are actually added to the wrapper element via its generated class. But I need to style the input element.
I've also tried using inputProps, but that did nothing at all.
You can style the constituent components by targeting their classes directly through sx. For example:
<TextField
label="My Label"
defaultValue="My Value"
size="small"
sx={{
".MuiInputBase-input": {
padding: '1px 3px',
fontSize: '0.875rem',
lineHeight: '1.25rem',
}
}}
/>
Working CodeSandbox: https://codesandbox.io/s/customizedinputs-material-demo-forked-jog26e?file=/demo.js
What you can use is the inputProps prop. This lets you pass the sx prop as a regular object down to the input component. For example:
<TextField
size="small"
inputProps={{
sx: {
padding: '1px 3px',
fontSize: '0.875rem',
lineHeight: '1.25rem'
}
}}
/>
Docs here: https://mui.com/material-ui/api/text-field/#props
Im trying to align items in react native using expo, but the children View justifyContent is not working after aligning items in the parent View. For example:
<View>
<View style={{ borderBottomColor: 'black',borderBottomWidth: 3}}>
<View style={{flexDirection:'row',justifyContent:'space-between'}}>
<Text style={{ color: "#6B35E2"}}>Name</Text>
<Text style={{ fontWeight: 'bold',color: "#6B35E2"}}>Nico</Text>
</View>
</View>
<View style={{alignSelf:'flex-end'}}>
<Icon
name="fingerprint"
iconStyle={styles.iconRight}
/>
</View>
</View>
Renders the following image. The icon apears below the bottom border, and I need it to be at the right of the second text. Its important to note that the bottom border must not reach the icon. It has to end at the second text. So, I tried to apply a flexDirection:row to the parent View like this:
<View style={{flexDirection: "row"}}>
<View style={{ borderBottomColor: 'black',borderBottomWidth: 3}}>
<View style={{flexDirection:'row',justifyContent:'space-between'}}>
<Text style={{ color: "#6B35E2"}}>Name</Text>
<Text style={{ fontWeight: 'bold',color: "#6B35E2"}}>Nico</Text>
</View>
</View>
<View style={{alignSelf:'flex-end'}}>
<Icon
name="fingerprint"
iconStyle={styles.iconRight}
/>
</View>
</View>
Sadly, it does not render correctly. The icon is at the right as expected and the bottom border ends just before, but the justifyContent:space-between property applied to the child View does not work anymore. Any ideas? Here is a image with the expected result. Its important that the bottom border must not be under the icon, it must end before.
The idea is to have a parent view with flexDirection of row. Then inside the parent view there will be two views -
1.) First View With flex: 1, flexDirection : 'row' and justifyContent: 'space-between'
2.) Second View would not have any styles just a simple view.
I've made a Snack for this.
You can do something like this
<View style={styles.parentView}>
<View style={styles.firstRowView}>
<Text>Name</Text>
<Text>Nico</Text>
</View>
<View style={styles.secondRow}>
<Ionicons name="finger-print" size={24} color="black" />
</View>
</View>
And Styles will be
parentView: {
flexDirection: 'row',
},
firstRowView: {
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
borderBottomColor: 'black',
borderBottomWidth: 2,
},
secondRow: {},
If you want the icon on the same row of Name and Nico then you need to put the Icon component inside the same row of Name and Nico.
<View style={{flexDirection: "row"}}>
<View style={styles.futBorder}>
<View style={{flexDirection:'row',justifyContent:'space-between'}}>
<Text style={styles.placeholderText}>Name</Text>
<Text style={styles.dataText}>Nico</Text>
<View style={{alignSelf:'flex-end'}}>
<Icon
name="fingerprint"
iconStyle={styles.iconRight}
/>
</View>
</View>
</View>
</View>
That way places Nico at the middle of the row. You also can create 2 rows inside one row like this:
<View style={{flexDirection:'row',justifyContent:'space-between'}}> {/* parent row */}
<View style={{flexDirection: 'row'}}> {/* child row */}
<Text style={styles.placeholderText}>Name</Text>
<Text style={styles.dataText}>Nico</Text>
</View>
<View style={{alignSelf:'flex-end'}}>
<Icon
name="fingerprint"
iconStyle={styles.iconRight}
/>
</View>
</View>
And then if necessary you can adjust the widths
Disclaimer:
I'm new to ReactJS, and web-development as a whole. Did my best to research before, and did not find an answer.
I'm probably missing something simple, but can't figure it out - so sorry if this question's answer is a one liner "How-Did-I-Miss-That' sort of answer.
Feel free to comment/answer with best practices I missed, or things I can improve in this question.
Thanks is advance to anybody that reads this!
My Own Research:
Float 3 Divs - I did not need the z-axis property, as non of my divs are on top of the other.
3 Divs LTR - Talks about 3 divs aligned horizontally, not vertically. The same method did not work for me in the vertical axis.
3 Divs LTR #2 - This talks about flex, so I tried it too. In the right direction, but not enough.
Vertical Align etc - could not make it happen with this solution either.
(5... 1000) A bunch of other first-second-third results in Google search queries like: "ReactJS vertical 3 divs" and the likes.
Actual Question:
Trying to make a basic outline of a mockup web-page, which consists of 3 divs:
Header Div - In The Top, Not Sticky (=when you y axis scroll, it does not appear).
Content Div - In The Middle, Y/X Axis Scrollable.
Bottom Nav Div - In The Bottom, Sticky.
Mockup:
My Current Status:
Can't make my bottom-menu div to appear. it's stuck under the frame.
Can't be sure my bottom-menu div is actually sticky because of the point above.
The contents tab div has no margin from the Header div, which makes the upper end of the text in it - unreadble.
My Code:
Did a lot of back-and-fourth on this, and this is the closest version I have for this simple (yet - not working!) task:
App.jsx
import React from "react";
import BottomMenu from "../BottomMenu/BottomMenu";
import Header from "../Header/Header";
import ContentTab from "../ContentTab/ContentTab";
const App = () => {
return (
<div style = {{display: "flex", flexDirection: "column", overflow: "visible",
direction: "rtl"}}>
<Header/>
<ContentTab />
<BottomMenu />
</div>
);
};
export default App;
Header.jsx
import React from "react";
import { Toolbar, AppBar } from "#material-ui/core";
import Typography from '#material-ui/core/Typography';
const Header = props => {
return (
<div>
<AppBar color="primary" style={{alignItems: 'center'}}>
<Toolbar>
<Typography>
Test
</Typography>
</Toolbar>
</AppBar>
</div>
);
};
export default Header;
ContentTab.jsx
import React from "react";
import Typography from "#material-ui/core/Typography";
import Paper from "#material-ui/core/Paper";
const ContentTab = (props) => {
return (
<div style={{height: "80%", width: "100%"}}>
<Paper align="center" elevation={3}>
<Typography paragraph>First</Typography>
<Typography paragraph>TextTab</Typography>
<Typography paragraph>Last</Typography>
</Paper>
</div>
);
};
export default ContentTab;
BottomMenu.jsx
import React from "react";
import BottomNavigation from "#material-ui/core/BottomNavigation";
import BottomNavigationAction from "#material-ui/core/BottomNavigationAction";
import RestoreIcon from "#material-ui/icons/Restore";
import FavoriteIcon from "#material-ui/icons/Favorite";
import LocationOnIcon from "#material-ui/icons/LocationOn";
import { Toolbar, AppBar } from "#material-ui/core";
export default function BottomMenu() {
const [value, setValue] = React.useState(0);
return (
<div style={{
position: "fixed", bottom: "0", width: "100%", height: "10%"}}>
<AppBar
style={{ background: '#FFFFFF', alignItems: "center" }}
>
<Toolbar>
<BottomNavigation
value={value}
onChange={(event, newValue) => {
setValue(newValue);
}}
showLabels
>
<BottomNavigationAction label="Recents" icon={<RestoreIcon />} />
<BottomNavigationAction label="Favorites" icon={<FavoriteIcon />} />
<BottomNavigationAction label="Nearby" icon={<LocationOnIcon />} />
</BottomNavigation>
</Toolbar>
</AppBar>
</div>
);
}
Actually; the issue is that you're using the Material-UI component AppBar. If this were just a regular DIV tag then you could position it the way you want. To use the AppBar component and make it do what you what then this should do the trick:
remove the outer DIV on the BottomMenu component
style the BottomMenu component's appBar with top of auto and bottom of 0 and give it a position property of fixed.
additionally, style the Header component's appBar with position of static.
this:
in BottomMenu:
<AppBar
position="fixed"
style={{
top: "auto",
bottom: "0",
background: "#FFFFFF",
alignItems: "center"
}}
>
in Header:
<AppBar
position="static"
color="primary"
style={{ alignItems: "center" }}
>
Here's a link to the docs that show it doing what you want:
https://material-ui.com/components/app-bar/
and here's a link to a code sandbox with your code.
https://codesandbox.io/s/material-ui-with-bottom-appbar-ugk31
In general, what I've found with Material-UI is that some of their components have positioning logic built into them and you need to use their properties for positioning instead of trying to do it with CSS.
I am trying to make one pdf page as one base64 image using react-pdf in my reactjs web application.
and I have tried everything that I know of for making the image as an A4 size
image and fill the image completely so that one image comes as one entire page in react-pdf
I have tried width:100%, height:100%, object-fill, tried to increase the size.
but so far I am unsuccessful.
Right now the image comes on center and does not make it to all the corners in the page.
import React, { Component } from 'react'
import ReactPDF, { Page, Text, View, Document, StyleSheet , Font, Image,} from '#react-pdf/renderer';
import pic from "../pics/pic.jpeg"
// Create styles
const styles = StyleSheet.create({
page: {
flexDirection: 'row',
backgroundColor: '#fff',
width:"100%",
orientation:"portrait"
},
image: {
width: '100%',
height:"100%",
padding: 10,
backgroundColor: 'white',
},
});
// Create Document Component
export default class ImageToPDF extends Component {
render() {
return (
<Document >
<Page object-fit="fill" style={styles.page} size="A4">
<View object-fit="fill" style={styles.image}>
<Image object-fit="fill" style={{ padding:"0, 0, 0, 0", margin:"33%, 2rem, 2rem, 2rem",
transform: 'rotate(90deg)'}} src={pic} alt="images" />
</View>
</Page>
</Document>
)
}
}
Expected output: One image comes as one page in the pdf using react-pdf.
Actual result: one image comes in the middle of a page using react-pdf and has a lot of margin on all four sides
Thanks a lot for the help. I really appreciate it
A bit late i guess, but maybe someone else can be helped by this.
I think the code below will do the trick.
I've altered a few things:
The view element had padding, i removed it.
applied objectFit to the image element, I would suggest to use "cover" instead of "fill".
Let me know if this helped.
import React, { Component } from 'react'
import ReactPDF, { Page, Text, View, Document, StyleSheet, Font, Image } from '#react-pdf/renderer';
import pic from "../pics/pic.jpeg"
// Create styles
const styles = StyleSheet.create({
page: {
flexDirection: 'row',
backgroundColor: '#fff',
width: '100%',
orientation: 'portrait',
},
view: {
width: '100%',
height: '100%',
padding: 0,
backgroundColor: 'white',
},
image: {
objectFit: 'cover',
},
});
// Create Document Component
export default class ImageToPDF extends Component {
render() {
return (
<Document >
<Page object-fit="fill" style={styles.page} size="A4">
<View style={styles.view}>
<Image style={styles.image} src={pic} alt="images" />
</View>
</Page>
</Document>
);
};
};
Using Material UI #next v1.0.0 beta 32:
Tabs labels wrap as expected on smaller devices.
But the wrapping makes them change font-size, which in turn, in some screen width removes the need for the text to wrap.
So I end up with this: tabs with non-wrapped labels and different font sizes.
sandbox example: https://codesandbox.io/s/o7worrr32q
In order to see the described result make the window narrow enough for at least 1 tab label to wrap, but not all.
I' have overriddeen the wrapped styles this way:
<Tab
value={value}
label='my label'
classes={{
root: classes.tab,
rootPrimarySelected: classes.selected,
labelWrapped: classes.labelWrapped
}}
/>
and my style:
labelWrapped: {
fontSize: '0.875rem'
},
The problem as illustrated in this gif animation, is that as you click on other tabs, the text wraps and unwraps alternatively, seemingly without reason.
My guess is that a padding changes somewhere, but I can't figure it out.
It was easier than I thought in the end:
I only had to use the MUI provided css override labelWrapped, as documented in the MUI API:
<Tab
aria-label="aria description"
label="Wrapping Label"
icon={<Icon />}
value={x}
classes={{
root: classes.root,
labelContainer: classes.labelContainer,
rootInheritSelected: classes.rootInheritSelected,
labelWrapped: classes.labelWrapped,
}}
component={Link}
to={{
pathname: '/my/router/url',
search: this.props.location.search,
}}
/>
and my overriding styles:
const styles = theme => ({
root: {
minWidth: 60,
height: '100%',
color: 'rgba(255,255,255,0.5)',
alignItems: 'flex-start',
paddingBottom: 5,
wordWrap: 'break-word',
flex: 1,
overflowWrap: 'break-word',
textAlign: 'center',
},
labelContainer: {
paddingLeft: 0,
paddingRight: 0,
},
rootInheritSelected: {
color: '#FFF',
},
labelWrapped: {
fontSize: '0.875rem',
},
})