in my project I need to customize a checkbox with FormControlLabel. In this label I need to show name and code of an item one above another with lowered font size. I tried to add html markup to label or used Typography, but it did not work. The code is as follows:
<FormControlLabel
label={<Typography variant="subtitle2" style={{ color: 'black', fontSize: '10px' }}>{"name_here" + "<br />(\n also not working)" + "code_here"}</Typography>}
control={<Checkbox size="small"/>}
/>
Any ideas how to fix it would be welcome. Thank you.
You can achieve this by using the sx property in the FormControlLabel for MUI V5. Alternative ways is to use styled components, or if you want a global solution to use the MUI theme.
Below is a solution using the sx and here is the working codesanbox to play with
<FormControlLabel
value="top"
sx={{
".MuiFormControlLabel-label": {
fontSize: "10px"
}
}}
control={
<Checkbox
name="test"
value="test"
checked={true}
size="small"
inputProps={{ "aria-label": "controlled" }}
/>
}
label="Top"
labelPlacement="top"
/>
Alternatively, if you want to render a Typography component in side the label you can write similar as you did
label={
<Typography sx={{ fontSize: '10px' }}>
Label Text
</Typography>
}
or give any properties you want in the Typography component
Related
I tried to code this thing. But the CardMedia will not go together with the checkbox. so responsive is a failure.
<Card>
<CardMedia
component='img'
alt=''
height='160'
image=''
title='Image'
style={{ backgroundColor: '#DEDBDB',
position: 'relative' }}
/>
{/*<input type='checkbox' id='select'*/}
{/* style={{ position: 'absolute', marginLeft: '20%', marginTop: '-2%'}}*/}
{/*/>*/}
{/*<label htmlFor='select'*/}
{/* style={{ position: 'absolute', marginLeft: '21%', marginTop: '-2.15%'}}*/}
{/*>選択</label>*/}
<Box mt={-6} ml={45}>
<span><Checkbox inputProps={{ 'aria-label': 'uncontrolled-checkbox' }} /></span>
</Box>
</Card>
I tried also the FormControlLabel for this so that the label and checkbox will be together and style it with position: absolute and some margins so that the result will be like this.
But the problem is that it is not responsive and if using box label disappear.
Thanks.
Ciao, your problem is connected to the zIndex of the label in FormControlLabel. Infact, if you inspect the page you can see the label present on DOM but invisible (maybe because on CardMedia the image is always on top, but this is my personal opinion).
To solve this problem, you can override the style of the label associated to the FormControlLabel. This is a codesandbox example.
At first I defined a CustomCheckbox:
const CustomCheckbox = withStyles((theme) => ({
root: {
// checkbox style example
// color: "#000000"
// '&$checked': {
// color: "#000000",
// },
},
checked: {}
}))((props) => <Checkbox color="default" {...props} />);
Then, I used it into Card:
<Box mt={-6} ml={45}>
<span>
<FormControlLabel
control={
<CustomCheckbox
checked={cheboxChecked}
onChange={handleChange}
name="toggleFavorite"
/>
}
label="Checkbox label" // label value
classes={{
label: styles.formcontrollabel // label class overriding
}}
/>
</span>
</Box>
And finally in makeStyles I made the override:
const useStyles = makeStyles(() => ({
formcontrollabel: {
"&.MuiFormControlLabel-label": {
zIndex: 1
}
}
}));
The result is:
The label is responsive also (in this case "label" word goes on new line if you reduce screen width) as long as possible (if you continue to reduce screen width, label will be cutted). But this is normal (because you defined Box like <Box mt={-6} ml={45}>). If you don't like this behaviour, you could use a Hidden component to hidden checkbox and label if screen goes under a certain breakpoint like:
<Hidden smDown> // if screen width goes under smDown breakpoint, the Hidden content will be hided
...
</Hidden>
How can I properly add dots the the title in my Cardheader if it exceeds the parents width (Card width). So far I have done this:
card: {
width: 275,
display: "flex"
},
overflowWithDots: {
textOverflow: 'ellipsis',
whiteSpace: 'nowrap',
overflow: 'hidden',
width: '100px'
}
<Card className={classes.card}>
<CardHeader
title={
<Typography gutterBottom variant="h6" component="h4" className={classes.overflowWithDots}>
{movie.title}
</Typography>
}
/>
This works in a way, but I have to tell the class to have a width of 100px until it adds the dots. I need to add the dots if it exceeds the parents width.
Problem
As I understand it you are limiting the size of the Card, in this case, you are not being able to place the ellipsis due to the way the CardHeader is rendered in the html.
The CardHeader component is rendered with a "root" element and a "content" element. See below:
Typography has a built-in prop to adding dots noWrap. For the noWrap property to work correctly, we have the following approaches.
Solution 1
CardHeader's default behavior is to use flex. If you don't need it use flex:
...
cardHeader: {
display: "block",
overflow: "hidden"
}
...
<CardHeader
className={classes.cardHeader}
title={
<Typography noWrap gutterBottom variant="h6" component="h4">
A world wide web - the revolution
</Typography>
}
/>
...
Solution 2
If you need to keep CardHeader with flex behavior, in this case, the overflow needs to be applied to the root and content. To reach the elements use the CardHeader classes property passing the generated class to the content prop.
...
cardHeaderRoot: {
overflow: "hidden"
},
cardHeaderContent: {
overflow: "hidden"
}
...
<CardHeader
classes={{
root: classes.cardHeaderRoot,
content: classes.cardHeaderContent
}}
title={
<Typography noWrap gutterBottom variant="h6" component="h4">
A world wide web - the revolution
</Typography>
}
/>
...
Here's an example in the sandbox.
Atention
Be aware that by modifying the default behavior of how components are rendered, some side effects may occur in your entire component tree.
Anyway
If you still have any problems let us know.
Although this solution works, if you are using mui v5, this is how you can do it using the sx prop described here. You can set the .MuiCardHeader-content style and titleTypographyProps prop to style the title. I added an action button and subheader as an extra example.
import React from "react";
import { Card, CardHeader, IconButton } from "#mui/material";
import { MoreVert as MoreVertIcon } from "#mui/icons-material";
const SimpleCard = () => (
<Card sx={{ width: "275px", display: "flex" }}>
<CardHeader
sx={{
display: "flex",
overflow: "hidden",
"& .MuiCardHeader-content": {
overflow: "hidden"
}
}}
title={"A very long title coooooooooooooool"}
titleTypographyProps={{ noWrap: true }}
subheader={"ps long subheader cooooooooooooool"}
subheaderTypographyProps={{ noWrap: true }}
action={
<IconButton>
<MoreVertIcon />
</IconButton>
}
/>
</Card>
);
export default SimpleCard;
Here's the sandbox to mess around with.
Typography has a built-in prop to adding dots. You can simply add noWrap prop to Typography. It will add dots in header text and according to the parent component width.
<Card className={classes.card}>
<CardHeader
title={
<Typography gutterBottom noWrap variant="h6" component="h4">
{movie.title}
</Typography>
}
/>
/>
I tried below code and while I was expecting to get a yellowish Hi, I got [object Object] instead.
Is there a way to fix it? maybe using InputProps helps but unfortunately I couldn't find any detailed tutorial about it.
<TextField
id="outlined-multiline-static"
label="Multiline"
multiline
fullWidth
rows="22"
value={<div> Hi <div style={{ color: "yellow" }}>There</div></div>}
variant="outlined"
/>
Edit:
I just simplified the problem and don't want the whole of the text to be yellow.
https://codesandbox.io/s/hopeful-bush-gfi9m?fontsize=14&hidenavigation=1&theme=dark
Use inputComponent inside InputProps to achieve customized text field inside the TextField
InputProps={{
inputComponent: () => (
<div style={{ color: "yellow" }}>XXXXXXXXXXXXXXXXX</div>
)
}}
Try it online:
You don't have to do use div's inside value attribute. You want the text to be styled, use InputProps
import React from "react";
import TextField from "#material-ui/core/TextField";
export default function App() {
return (
<>
<TextField
id="outlined-multiline-static"
fullWidth
rows="12"
value="Hi"
variant="outlined"
InputProps={{
style: {
color: "yellow"
}
}}
/>
</>
);
}
I'm struggling to override the default padding of the Select component to match the size of my other text fields. I understand that I need to modify nested components but have been unable to find a working solution.
<div className='wifi-chooser-column'>
<TextField
style={{margin: '6px'}}
label='SSID'
variant='outlined'
size='small'
/>
<Select
style={{margin: '6px', padding: '0px'}}
variant='outlined'
value={this.state.security}
onChange={(event) => this.setState({security: event.target.value})}
classes={{
select: {
padding: '10.5px 14px'
}
}}
>
<MenuItem label='security' value='Unsecured'>Unsecured</MenuItem>
<MenuItem value='WEP'>WEP</MenuItem>
<MenuItem value='WPA2'>WPA2</MenuItem>
</Select>
<TextField
style={{margin: '6px'}}
label='Username'
variant='outlined'
size='small'
/>
<TextField
style={{margin: '6px'}}
label='Password'
variant='outlined'
size='small'
/>
Layout issue
According to the doc, there are several ways that we can override the material UI component styles.
If we want to override the padding of the Select components differently and occasionaly, or if this process would not be repeated in the entire project, we can simply use Overriding styles with classes approach. In this way, first we need to create our desired padding for Select component by makeStyles as below:
const useStyles = makeStyles((theme) => ({
rootFirstSelect: {
padding: "4px 0px"
},
rootSecondSelect: {
padding: "10px 80px"
}
}));
and then assign it to the classes prop of the component, by modifying the root element:
const classes = useStyles();
//Other part of the code
return (
//Other part of the code
<Select
classes={{ root: classes.rootFirstSelect }}
//other props
>
//Other part of the code
)
working sandbox example for this method
If we want to override the padding of the Select component for the whole project, Global theme variation would prevent repetition. In this way, we should create a theme by createMuiTheme, as below, and apply our desired changes there:
const theme = createMuiTheme({
overrides: {
MuiSelect: {
select: {
padding: "4px 0px 10px 130px !important"
}
}
}
});
then pass this theme as a prop to the ThemeProvider component which surround the whole project:
<ThemeProvider theme={theme}>
<Demo />
</ThemeProvider>
working example in sandbox
I found an alternative way in the docs, that's easier to use for me: instead of using Select component, I use TextField with "select" props
cf: https://material-ui.com/components/text-fields/#select
<TextField
id="standard-select-currency"
select
label="Select"
value={currency}
onChange={handleChange}
helperText="Please select your currency"
>
{currencies.map((option) => (
<MenuItem key={option.value} value={option.value}>
{option.label}
</MenuItem>
))}
</TextField>
Which allows you to access TextField props such as margin="none", margin="dense"
I have a CardHeader which has a dropdown within it, I use the to select various options for the table, however currently it looks awful and im not entirely sure how to style it in a more appropriate way, I am using material UI's framework to do this.
formControl: {
flexBasis: 'auto',
position: 'relative'
},
<CardHeader className={classes.cardHeader} classes={{ title: classes.cardHeader }}
avatar={
<Home />
}
action={
<FormControl className={classes.formControl}>
<InputLabel htmlFor="Available Contracts" style={{ marginRight: 20, color: 'white' }}>Contract Type</InputLabel>
<Select
value={contractType.contractObject}
onChange={handleChange}
inputProps={{
name: 'contractObject',
id: 'contractObject',
}}
>
<MenuItem value={10}>Local Contract</MenuItem>
<MenuItem value={20}>Framework Contract</MenuItem>
</Select>
</FormControl>
}
/>
A screen shot below of the table
As you can see the Contract Type is currently on the right, I would like this on the left next to the Home icon if possible, any ideas?
The 'Card' component has further sub components - 'CardHeader', 'CardContent'.
To style the CardHeader for instances, the API indicates that you can do the following:
import React from 'react';
import { makeStyles } from '#material-ui/styles';
import {
Card, CardContent, CardHeader, Divider
} from '#material-ui/core';
const useStyles = makeStyles(theme => ({
action: {
margin: 0
}
}))
const CustomerInfoCards = ({ customer }) => {
const classes = useStyles();
return (
<Card>
<CardHeader
action={
<p>{customer._id}</p>
}
classes={{ action: classes.action }}
className={classes.action}
subheader={customer.email}
title={customer.name}
/>
<Divider />
<CardContent>
<h2>Some text</h2>
</CardContent>
</Card>
)
}
export default CustomerInfoCards
Main thing here is classes={{ action: classes.action }} - which removes the default margin top and right of 8px for the action prop.
Take a look at the API link above to know the various CSS exposed by material-ui and have fun styling!
In your styling for formControl add a new property flex and have its value as flex: "0 1 auto",
formControl: {
flexBasis: 'auto',
position: 'relative',
flexgrow: '1',
flex: '0 1 auto',
}
Hope this helps. flex usually adjust the component to relative right of the earlier component.
Read more: CSS flex on W3Schools