Overriding Material-UI Select Style - javascript

I am trying to override the styling applied by Material-UI's <Select> component when variant="outlined". For this example, I want the <Select>'s dropdown icon to be hidden and padding-right to be 0px.
From my understanding of the API, I should be able to overwrite the styles by passing in classes={{ icon: classes.hideIcon, outlined: classes.noPaddingRight }}, where classes is:
const useStyles = makeStyles(theme => ({
hideIcon: {
display: "none"
},
noPaddingRight: {
paddingRight: "0px"
}
}));
const classes = useStyles();
I am able to successfully hide the icon, but my noPaddingRight class is overridden by both MuiSelect-select.MuiSelect-select and MuiSelect-outlined.MuiSelect-outlined (I'm also confused what the . is doing in those two classes):
The only way I've gotten it to work is by using paddingRight: 0px !important but that's something I'd like to avoid if at all possible.
Here is the CodeSandbox: https://codesandbox.io/s/overwrite-select-style-zqk1r

You can use nesting selector for the className MuiSelect-outlined
hideIconPadding: {
"& .MuiSelect-outlined": {
paddingRight: "0px"
}
}
Notice that use className here:
className={classes.hideIconPadding}

Related

TreeView - How to change font of expandable TreeItems to bold?

I have an object which I map through and convert the key/value pairs to Material-UI TreeItems. Is it a way to add unique styling (font-weight bold) to TreeItems if they are expandable?
TreeItem is expandable when it has any children. Otherwise, the children is undefined. You can conditionally render different styles after checking if any children exist:
import TreeView from "#material-ui/lab/TreeView";
import MuiTreeItem from "#material-ui/lab/TreeItem";
const useTreeItemStyles = makeStyles({
label: {
fontWeight: (props) => (props.children ? "bold" : "initial")
}
});
function TreeItem(props) {
const classes = useTreeItemStyles(props);
return <MuiTreeItem {...props} classes={{ label: classes.label }} />;
}
Live Demo

How to use CSS withinin the file - ReactJS

I'm very new to react. And I'm trying to learn some new stuff. So what I want to do is to add CSS within my Header.js file, And I don't know how to do that. Because I don't want to import external or inline CSS. But rather use it like in Html with tag on the header. But not just that, I want to use that CSS specifically for the file, in this case, Header.js.
This might help
Header.js
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
// alignSelf: 'center',
},
textStyle: {
marginTop: Metrics.ratio(0),
marginHorizontal: Metrics.ratio(70),
fontFamily: Fonts.type.base,
fontSize: Fonts.size.normal,
color: Colors.black,
},
});
class Header extends React.Component {
render() {
return (
<div style={ styles.color } />
);
}
}
You have several possibilites.
The simplest is to use css code directly in the element like
<div style={{color:'#000',backgroundColor:'#fff'}}>
...
</div>
Or you can use the libraries for that, like styled-components (https://styled-components.com/) for this.
You need to import this:
import styled from 'styled-components';
Then you can define your element css on the top of the page, i.e. SomeCSSStyling
const SomeCSSStyling = styled.div`
color:#000;
background-color:#fff;
`
Then you can use this constant in the class code of the react component:
class MyReactComponent extends Component {
constructor(props) {
...
}
render() {
return (
<SomeCSSStyling>
...
</SomeCSSStyling>
);
}
}
export default MyReactComponent;
UPDATE:
You can also define :hover or ::before etc. with style-components:
const SomeCSSStyling = styled.div`
color:#000;
background-color:#fff;
&:hover{
font-weight:bold;
}
`
You can create style object inside react component like this:
const myDivStyles = {
color: "red",
fontSize: "32px"
}
All propertis are the same like in CSS but this one with "-" sign change in to camelCase nams, e.g. font-size change to fontSize, background-color change to backgroundColor.
Then you can add this style to elements in your components by style attribute.
render() {
return (
<div style={ myDivStles } />
)
}
You can also describe style without creating style object like this:
<div style={{ color: "red", backgroundColor: "#fff" }} />
Be sure you are using double closure {{ }}.
EDIT
With :hover selector
You have two prosibilites. First you can use component state to determinate if component is hovered and then prepare correct style, e.g:
class Component extends React.Component {
constructor(props) {
super(props)
this.state = {
hovered: false
}
this.toggleHover = this.toggleHover.bind(this)
}
toggleHover(state) {
this.setState({
hovered: state
})
}
render() {
const styles = {
color: this.state.hovered ? "red" : "blue"
}
return (
<div style={styles} onMouseEnter={ () => this.toggleHover( true ) } onMouseLeave={ () => this.toggleHover( false ) }>
Text
</div>
);
}
}
Second you can use js styled components syntax and refer to other component, you can read more about this here: https://styled-components.com/docs/advanced#referring-to-other-components
But to be honest when I dealing with :hover or other selectors I prefer using default css files or much more often scss files prepared for components. So when I have e.g Button component in same location I have Button.css ( or Button.scss ) file where I can work with standard css. After this I have css files connected with components which should handled them.

Changing the styling in MUI Table

I'm creating a Material UI table what I believe is the default way, and I'm getting huge padding internally.
I have tried using withStyles and passing the resulting class into through the component property, like this:
const StyledPaper = withStyles(theme => ({
root: {
padding: "0",
},
}), Paper);
...
<Table component={StyledPaper}>
I have tried making classes and passing them in:
const useStyles = makeStyles(theme => ({
root: {
padding: "0",
},
}));
...
const classes = useStyles();
...
<Table classes={classes}>
I have futzed around endlessly and I'm not having any effect at all.
Any suggestions?
If you look at the DOM element class name, you would find out that it starts with MuiPaper-root under the MuiGrid-root element.
Perhaps use nesting selector is a good approach in this situation for customized styles
import { withStyles } from "#material-ui/core/styles";
const styles = {
root: {
"& .MuiPaper-root": {
padding: 0
}
}
};
...
const { classes } = this.props;
...
export default withStyles(styles)(App);
usage
Notice it's not inside the Table so you may want to add the padding for Grid
<Grid container>
<Grid item className={classes.root} // ...>
// ...
</Grid>
</Grid>
Similar online demo and related QA:
How to change material-ui Textfield label styles in react

Is there a way to change the clicked color of the Chip

I'm trying to change the clicked color of a Chip component, without changing my theme.js.
I have tried using the classes override, with the colors that I need, but its still changing it to the primary/secondary colors. I found this part in the implementation
[...]
/* Styles applied to the root element if `onClick` and `color="primary"` is defined or `clickable={true}`. */
clickableColorPrimary: {
'&:hover, &:focus': {
backgroundColor: emphasize(theme.palette.primary.main, 0.08),
},
},
/* Styles applied to the root element if `onClick` and `color="secondary"` is defined or `clickable={true}`. */
clickableColorSecondary: {
'&:hover, &:focus': {
backgroundColor: emphasize(theme.palette.secondary.main, 0.08),
},
},
[...]
and I was wondering if there was a way to overide this...
My attempt with the classes override looks like this,
<Chip
classes={{
ColorSecondary: '#00d799',
ColorPrimary: '#ffb34b',
}}
color={!clicked ? 'primary' : 'secondary'}
size="small"
label={`${clicked ? 'Copied!' : 'Copy'}`}
onClick={() => setClicked(!clicked)}
/>
but it didn't help.
edit:
I've updated my code according to Fred A comment:
<Chip
classes={{
colorPrimary: classes.overrideColorPrimary,
colorSecondary: classes.overrideColorSecondary,
}}
color={!clicked ? 'primary' : 'secondary'}
size="small"
label={`${clicked ? 'Copied!' : 'Copy'}`}
onClick={() => setClicked(!clicked)}
/>
using the classes prop:
[...]
overrideColorPrimary: {
backgroundColor: '#ffb34b',
},
overrideColorSecondary: {
backgroundColor: '#00d799',
},
[...]
But I'm still having issues when the Chip is focused or hovered, where it defaults to the theme.js colors.
after clicking the Chip, this property shows up:
.MuiChip-clickableColorPrimary:hover, .MuiChip-clickableColorPrimary:focus {
background-color: rgb(137, 137, 138);
}
when inspecting the element.
classes props is used to Override or extend the styles applied to the component. See CSS API below for more details.
OR
You can override CSS attributes by adding a new class or you can pass the CSS attributes to the style props.
Please check my Code Sandbox example.
You cannot use classes property like that. The ColorSecondary and ColorPrimary are the classes located within the Chip component which you can access using the classes property, therefore to override it, you need to pass your own self defined classes to it.
/* Define the styling to pass into the classes */
const styles = theme => ({
overrideColorPrimary: { /* styling in here */ },
overrideColorSecondary: { /* styling in here */ }
});
/* Inside the component function */
const { classes } = props
/* Pass it to the classes like that */
<Chip
classes={{
ColorPrimary: classes.overrideColorPrimary
ColorSecondary: classes.overrideColorSecondary
}}
color={!clicked ? 'primary' : 'secondary'}
size="small"
label={`${clicked ? 'Copied!' : 'Copy'}`}
onClick={() => setClicked(!clicked)}
/>
This way, the MUI will use your defined styles to the MUI defined classes.

React Native: You attempted to set the key on an object that is meant to be immutable and has been frozen

I am new to react native and was creating my first.
In my add I decided to change the backgroundColor of my App dynamically for which I did something like this
let style = StyleSheet.flatten({
upperRow: {
display: "flex",
flexDirection: "row",
marginBottom: 5,
backgroundColor: "white"
},
})
let {
upperRow
} = style
And then something like this in componentWillReceiveProps
componentWillReceiveProps(nextProps) {
if (this.props.coinPrice != nextProps.coinPrice ) {
if (this.props.coinPrice > nextProps.coinPrice) {
console.log("previous value is greater")
//change background color to red
upperRow["backgroundColor"] = "#ffe5e5"
console.log(upperRow)
//We
}
}
}
This is throwing following error
You attempted to set the key backgroundColor with the value
#ffe5e5 on an object that is meant to be immutable and has been
frozen.
Question: Can anyone tell me what is going wrong here?
Something you should know about Stylesheet:
When you do Stylesheet.flatten, it will flatten arrays of style objects one immutable style object.
When you do Stylesheet.create, it will generate an immutable style object.
But why does it have to be immutable?
Refer the documentation, in order to increase the performance, the immutability of the style object will enable a simpler communication between the UI and JS Thread. In other words, they will just use the IDs of the style objects to communicate with each other through the native bridge. So, the object can't be mutated.
The solution to this problem is just as simple as this:
Using an array of styles.
Updating the styles dynamically using state.
Below is the code demonstrating how to do it:
class App extends React.Component {
state = {
clicked: false
}
handleOnPress = () => {
this.setState(prevState => ({clicked: !prevState.clicked}))
}
render() {
return (
<View style={[styles.container, {backgroundColor: this.state.clicked ? "blue" : "red"}]}>
<Button onPress={this.handleOnPress} title="click me" />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
});
Here is the Snack Expo link of the code: https://snack.expo.io/SJBLS-1I7

Categories