Material UI - Widget component issue - javascript

I'm using the autocomplete component, and finally, I finished the feature as I wanted but since this component is rendered in other pages as a widget I'm getting some weird issues with the styling since the page that renders my component is overriding/adding styles they have globally.
This is how it looks in my local:
And this is how it looks when I deploy it and I check it on one of the pages:
I've been working on this the whole day without success, but I found that the styles that are braking my component are these ones:
I'm using these styles to hide the outlined style of the textfield
const useStyles = makeStyles(theme => ({
root: {
"& .MuiOutlinedInput-root .MuiOutlinedInput-notchedOutline": {
border: 'none !important',
outline: 'none'
},
"& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline": {
border: 'none !important',
outline: 'none'
}
}
}));
And this is how my autocomplete components look like
<Autocomplete
id="listings-filter"
multiple
disableCloseOnSelect={true}
freeSolo
clearOnBlur={false}
limitTags={5}
disableCloseOnSelect={true}
blurOnSelect={false}
options={options}
groupBy={(option) => option.key }
onInputChange={handleInputChange}
onChange={handleOptionSelection}
disableCloseOnSelect
getOptionLabel={(option) => option.value}
renderOption={(option, { selected }) => (
<React.Fragment>
<Checkbox
icon={icon}
checkedIcon={checkedIcon}
style={{ marginRight: 8 }}
checked={selected}
/>
{option.value}
</React.Fragment>
)}
style={{ width: "100%" }}
renderInput={(params) => (
<TextField
id='autocomplete-input'
{...params}
margin={'dense'}
className={autocompleteClasses.root}
InputLabelProps={{
shrink: true
}}
variant='outlined'
label="Search listings by address, MLS or property name"
placeholder='Type the address, MLS or property name'
/>
)}
/>
I tried to add inputProps to the textfield and give the styles there but this didn't work at all, also tried adding the styles on the makeStyles part but I'm confused about how to get into the exact class I need with MUI style overrides, and since this looks that is related with generic input component and not with a material UI component, made me confuse even more.
I don't know if this is possible with react or I have to build a CSS file to be able to avoid this behavior. Really appreciate any help!
EDIT:
Also tried using the inputProps of the TextField component leaning on another stackoverflow question but that make the autocomplete component to crash when the input is clicked with the following error -> Uncaught TypeError: Cannot read property 'focus' of null
const useStyles = makeStyles(theme => ({
root: {
"& .MuiOutlinedInput-root .MuiOutlinedInput-notchedOutline": {
border: 'none !important',
outline: 'none'
},
"& .MuiOutlinedInput-root.Mui-focused .MuiOutlinedInput-notchedOutline": {
border: 'none !important',
outline: 'none'
}
},
input: {
border: '10 !important',
borderColor: 'red',
boxShadow: 'unset !important',
color: 'red'
}
}));
renderInput={(params) => (
<TextField
id='autocomplete-input'
{...params}
margin={'dense'}
className={autocompleteClasses.root}
InputLabelProps={{
...params.InputLabelProps,
shrink: true
}}
inputProps={{
...params.InputProps,
classes:{
root: autocompleteClasses.input,
}
}}
variant='outlined'
label="Search listings by address, MLS or property name"
placeholder='Type the address, MLS or property name'
/>
)}

I solved the issue by creating a scss file:
.autocomplete-component > div > div > input {
border: 0px !important;
border-color: white !important;
box-shadow: unset !important;
-webkit-box-shadow: unset !important
}
and used as a className on the autocomplete component:
import './listingStyles.scss'
<Autocomplete
id="listings-filter"
className={'autocomplete-component'}
multiple
disableCloseOnSelect={true}
freeSolo
clearOnBlur={false}
limitTags={5}
disableCloseOnSelect={true}
blurOnSelect={false}
options={options}
groupBy={(option) => option.key }
onInputChange={handleInputChange}
onChange={handleOptionSelection}
disableCloseOnSelect
... />
Hope this is useful for anyone!

Related

React - Material label not in right position in Textfield

I tried create the MUI textfield using same code in Codesandbox but everything works fine.
I tried to follow this post but not working
Can anyone give me some ideas of how to fix this issue?
const textfieldUseStyles = makeStyles((theme) => ({
root: {
"& > *": {
margin: "auto",
width: "100%",
},
},
}));
...
const textFieldClasses = textfieldUseStyles();
return (
<form className={textFieldClasses.root}>
<TextField
key="Confirmation Code"
variant="outlined"
id="email"
label="Post title"
name="email"
autoComplete="confirmation code"
value="123"
InputLabelProps={{ shrink: true }}
/>
</form>
)
Updated 1
After I added css class below, it changed to more good UI
.MuiInputLabel-outlined.MuiInputLabel-shrink {
transform: translate(0, -6px);
font-size: 12px;
margin: 0 14px;
background-color: white;
}
What I want is something like this, at least the label is in right position:
makeStyle is deprecated in Mui-v5 !!!
you can change textFiled border and other properties in various ways like:
the sx prop:
<TextField
sx={{ '& .MuiOutlinedInput-root': { borderRadius: '20px' } }} // change border form here
key="Confirmation Code"
variant="outlined"
id="email"
label="Post title"
name="email"
autoComplete="confirmation code"
value="123"
InputLabelProps={{ shrink: true }}
/>
Mui styled component way(using emotion)
import { styled } from '#mui/material/styles'
import TextField from '#mui/material/TextField'
export const StyledTextField = styled(TextField)(() => ({
'& .MuiInputBase-root': {
borderRadius: 20
}
}))

How to embed checkbox with label in Card Media?

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>

Not able to change padding of material UI Select component

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"

Can't change border radius of text-field variant=filled in Material-ui-core

Current Behavior 😯
my current component is as follows
export const BirthdayTextFields = styled(TextField)`
width: 80px;
margin-right: 10px;
border-radius: 50px;
`;
and I'm using it as follows:
<BirthdayTextFields
id="filled-dense-hidden-label"
margin="dense"
hiddenLabel
variant="filled"
placeholder="18"
inputProps={{ 'aria-label': 'dense hidden label' }}
onChange={this.handleChange('day')}
/>
since the variant="failed" it doesn't allow me to set the border-radius, I have tried overriding the rule fo TextField Component by following trick:
export const TextFieldWrapper = styled(TextField)`
fieldset {
border-radius: 50px;
}
`;
and I'm using like this, since it is variant=outlined the overriding works
<TextFieldWrapper
id="outlined-dense"
label="Last name"
margin="dense"
variant="outlined"
onChange={this.handleChange('lastName')}
/>
So how to solve this out? I have also try adding the fieldset value to BirthdayTextFields but it doesn't make any effect mostly becaues of the variant="filled"
export const BirthdayTextFields = styled(TextField)`
width: 80px;
margin-right: 10px;
fieldset {
border-radius: 50px;
}
`;
Environment
Windows 10
Tech : Version
Material-UI: ^3.9.3
React : ^16.8.6
Browser : Chrome
Have you tried using <FilledInput> ?
const useStyles = makeStyles(theme => ({
root: {
borderRadius: "50px 50px 0 0"
},
container: {
display: "flex",
flexWrap: "wrap"
},
textField: {
marginLeft: theme.spacing(1),
marginRight: theme.spacing(1)
}
}));
export default function FilledTextFields() {
const classes = useStyles();
const [values, setValues] = React.useState({
name: "Cat in the Hat",
age: "",
multiline: "Controlled",
currency: "EUR"
});
const handleChange = name => event => {
setValues({ ...values, [name]: event.target.value });
};
return (
<form className={classes.container} noValidate autoComplete="off">
<FilledInput
id="filled-name"
label="Name"
className={classes.textField}
value={values.name}
onChange={handleChange("name")}
margin="normal"
variant="filled"
classes={{
root: classes.root
}}
/>
</form>
https://codesandbox.io/embed/material-demo-sos7s
I wasn't able to access the outline container which applies the borderRadius, so I used the CSS approach instead.
<TextField className="inputRounded" placeholder="Search" variant="outlined" />
Then I addeded the the borderRadius code in the index.css file of the project.
.inputRounded .MuiOutlinedInput-root{
border-radius: 50px;
}
const useStyles = makeStyles({
root: {
[`& fieldset`]: {
borderRadius: 15,
},
},
});
<TextField
className={classes.root}
id="inputRounded"
label="Email address"
variant="outlined"
fullWidth
/>
You have to use the browser dev tools to identify the slot for the component you want to override.
Once that's done, you write a CSS file with the class you want to change.
To force the class you can use :
!important
file : styles.css
.css-1q6at85-MuiInputBase-root-MuiOutlinedInput-root{
border-radius: 50px!important;
}
in a clear way, it worked for me
add this to sx={} in TextField
'& .MuiOutlinedInput-root': {
'& fieldset': {
borderColor: 'black',
borderRadius: 2,
},
},

Material UI's CardHeader action styling

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

Categories

Resources